<commit_before>/*

generate.js - generate ASCII text representation of PEG grammar

The MIT License (MIT)

Copyright (c) 2015 Dale Schumacher

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var generate = module.exports;

var q = function quote(o) {
    return JSON.stringify(o);
}

var indentDepth = 0;
var indentWidth = 2;
var indentSpace =
'                                                                ';
var indent = function indent() {
    return indentSpace.substring(0, indentDepth);
};

/*
 * text(grammar[, indent]) - generate ASCII text representation of PEG grammar
 */
generate.text = function text(grammar, width) {
    indentWidth = width || indentWidth;
    var s = '';

    s += '/* Generated PEG grammar */\n';
    s += '"use strict";\n';
    s += 'var grammar = module.exports;\n';
    s += '\n';
    s += 'var PEG = require("./index.js");\n';
    s += 'var named = require("./named.js");\n';
    s += '\n';
    s += 'grammar.build = function build(sponsor) {\n';
    indentDepth += indentWidth;
    s += indent() + 'var ns = named.scope(sponsor);\n';
    s += '\n';

    for (var name in grammar) {
        if (grammar.hasOwnProperty(name)) {
            s += indent() + textRule(name, grammar[name]) + '\n\n';
        }
    }

    s += indent() + 'return ns;  // return grammar namespace\n';
    indentDepth -= indentWidth;
    s += '};\n';

    return s;
};

var textRule = function textRule(name, expr) {
    var s = '';

    s += 'ns.define(' + q(name) + ',\n';
    indentDepth += indentWidth;
    s += indent() + textExpression(expr) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ');';

    return s;
};

var textExpression = function textExpression(list) {
    if (list.length == 1) {
        return textSequence(list[0]);
    }

    var s = '';
    var a = [];

    s += 'sponsor(PEG.choice([\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        a[i] = textSequence(list[i]);
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ']))';

    return s;
};

var textSequence = function textSequence(list) {
    if (list.length == 1) {
        return textTerm(list[0]);
    }

    var s = '';
    var a = [];

    s += 'sponsor(PEG.sequence([\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        a[i] = textTerm(list[i]);
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ']))';

    return s;
};

var textTerm = function textTerm(term) {
    if ((typeof term === 'object') && (term.length > 0)) {
        return textExpression(term);
    } else if (term.type === 'Literal') {
        return textLiteral(term.ptrn);
    } else if (term.type === 'Class') {
        return textClass(term.ptrn);
    } else if (term.type === 'Object') {
        return textObject(term.ptrn);
    }

    var s = '';

    if (term.type === 'Name') {
        s += 'ns.lookup(' + q(term.ptrn) + ')';
    } else if (term.type === 'AND') {
        s += 'sponsor(PEG.follow(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'NOT') {
        s += 'sponsor(PEG.not(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'QUESTION') {
        s += 'sponsor(PEG.optional(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'STAR') {
        s += 'sponsor(PEG.star(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'PLUS') {
        s += 'sponsor(PEG.plus(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'DOT') {
        s += 'sponsor(PEG.dot)';
    } else {
        s += q(term);
    }

    return s;
};

var textCharacter = function textCharacter(code) {
    var s = '';

    s += 'sponsor(PEG.terminal(';
    s += q(String.fromCharCode(code));
    s += '))';

    return s;
};

var textLiteral = function textLiteral(list) {
    if (list.length == 1) {
        return textCharacter(list[0]);
    }

    var s = '';
    var a = [];

    s += 'sponsor(PEG.sequence([\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        a[i] = textCharacter(list[i]);
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ']))';

    return s;
};

var rq = function rq(code) {
    var s = q(String.fromCharCode(code));
    s = s.substring(1, s.length - 1);  // drop outer quotes
    if ((s === '[') || (s === ']')) {
        s = '\\' + s;
    }
    return s;
};
var textClass = function textClass(list) {
    var s = '';

    s += 'sponsor(PEG.predicate(function (token) {\n';
    indentDepth += indentWidth;
    s += indent() + 'return /[';
    for (var i = 0; i < list.length; ++i) {
        var range = list[i];
        if (typeof range === 'number') {
            s += rq(range);
        } else {
            s += rq(range[0]) + '-' + rq(range[1]);
        }
    }
    s += ']/.test(token);\n';
    indentDepth -= indentWidth;
    s += indent() + '}))';

    return s;
};

var sq = function sq(list) {
    var s = '';
    for (var i = 0; i < list.length; ++i) {
        s += String.fromCharCode(list[i]);
    }
    return q(s);
};
var textObject = function textObject(list) {
    var s = '';
    var a = [];

    s += 'sponsor(PEG.object({\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        var rule = list[i];
        if (rule.type === 'Property') {
            a.push(q(rule.name) + ': '
                + sq(rule.value.ptrn));
        }
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + '}))';

    return s;
};
<commit_msg>Generate string terminal for single-quoted literal<commit_after>/*

generate.js - generate ASCII text representation of PEG grammar

The MIT License (MIT)

Copyright (c) 2015 Dale Schumacher

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/
"use strict";

var generate = module.exports;

var q = function quote(o) {
    return JSON.stringify(o);
}

var indentDepth = 0;
var indentWidth = 2;
var indentSpace =
'                                                                ';
var indent = function indent() {
    return indentSpace.substring(0, indentDepth);
};

/*
 * text(grammar[, indent]) - generate ASCII text representation of PEG grammar
 */
generate.text = function text(grammar, width) {
    indentWidth = width || indentWidth;
    var s = '';

    s += '/* Generated PEG grammar */\n';
    s += '"use strict";\n';
    s += 'var grammar = module.exports;\n';
    s += '\n';
    s += 'var PEG = require("./index.js");\n';
    s += 'var named = require("./named.js");\n';
    s += '\n';
    s += 'grammar.build = function build(sponsor) {\n';
    indentDepth += indentWidth;
    s += indent() + 'var ns = named.scope(sponsor);\n';
    s += '\n';

    for (var name in grammar) {
        if (grammar.hasOwnProperty(name)) {
            s += indent() + textRule(name, grammar[name]) + '\n\n';
        }
    }

    s += indent() + 'return ns;  // return grammar namespace\n';
    indentDepth -= indentWidth;
    s += '};\n';

    return s;
};

var textRule = function textRule(name, expr) {
    var s = '';

    s += 'ns.define(' + q(name) + ',\n';
    indentDepth += indentWidth;
    s += indent() + textExpression(expr) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ');';

    return s;
};

var textExpression = function textExpression(list) {
    if (list.length == 1) {
        return textSequence(list[0]);
    }

    var s = '';
    var a = [];

    s += 'sponsor(PEG.choice([\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        a[i] = textSequence(list[i]);
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ']))';

    return s;
};

var textSequence = function textSequence(list) {
    if (list.length == 1) {
        return textTerm(list[0]);
    }

    var s = '';
    var a = [];

    s += 'sponsor(PEG.sequence([\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        a[i] = textTerm(list[i]);
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ']))';

    return s;
};

var textTerm = function textTerm(term) {
    if ((typeof term === 'object') && (term.length > 0)) {
        return textExpression(term);
    } else if (term.type === 'Literal') {
        if ((term.open === '\'') && (term.close === '\'')) {
            return textString(term.ptrn);
        } else {
            return textLiteral(term.ptrn);
        }
    } else if (term.type === 'Class') {
        return textClass(term.ptrn);
    } else if (term.type === 'Object') {
        return textObject(term.ptrn);
    }

    var s = '';

    if (term.type === 'Name') {
        s += 'ns.lookup(' + q(term.ptrn) + ')';
    } else if (term.type === 'AND') {
        s += 'sponsor(PEG.follow(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'NOT') {
        s += 'sponsor(PEG.not(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'QUESTION') {
        s += 'sponsor(PEG.optional(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'STAR') {
        s += 'sponsor(PEG.star(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'PLUS') {
        s += 'sponsor(PEG.plus(\n';
        indentDepth += indentWidth;
        s += indent() + textTerm(term.ptrn) + '\n';
        indentDepth -= indentWidth;
        s += indent() + '))';
    } else if (term.type === 'DOT') {
        s += 'sponsor(PEG.dot)';
    } else {
        s += q(term);
    }

    return s;
};

var textCharacter = function textCharacter(code) {
    var s = '';

    s += 'sponsor(PEG.terminal(';
    s += q(String.fromCharCode(code));
    s += '))';

    return s;
};

var sq = function sq(list) {
    var s = '';
    for (var i = 0; i < list.length; ++i) {
        s += String.fromCharCode(list[i]);
    }
    return q(s);
};
var textString = function textString(list) {
    var s = '';

    s += 'sponsor(PEG.terminal(';
    s += sq(list);
    s += '))';

    return s;
};

var textLiteral = function textLiteral(list) {
    if (list.length == 1) {
        return textCharacter(list[0]);
    }

    var s = '';
    var a = [];

    s += 'sponsor(PEG.sequence([\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        a[i] = textCharacter(list[i]);
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + ']))';

    return s;
};

var rq = function rq(code) {
    var s = q(String.fromCharCode(code));
    s = s.substring(1, s.length - 1);  // drop outer quotes
    if ((s === '[') || (s === ']')) {
        s = '\\' + s;
    }
    return s;
};
var textClass = function textClass(list) {
    var s = '';

    s += 'sponsor(PEG.predicate(function (token) {\n';
    indentDepth += indentWidth;
    s += indent() + 'return /[';
    for (var i = 0; i < list.length; ++i) {
        var range = list[i];
        if (typeof range === 'number') {
            s += rq(range);
        } else {
            s += rq(range[0]) + '-' + rq(range[1]);
        }
    }
    s += ']/.test(token);\n';
    indentDepth -= indentWidth;
    s += indent() + '}))';

    return s;
};

var textObject = function textObject(list) {
    var s = '';
    var a = [];

    s += 'sponsor(PEG.object({\n';
    indentDepth += indentWidth;
    for (var i = 0; i < list.length; ++i) {
        var rule = list[i];
        if (rule.type === 'Property') {
            a.push(q(rule.name) + ': '
                + sq(rule.value.ptrn));
        }
    }
    s += indent() + a.join(',\n' + indent()) + '\n';
    indentDepth -= indentWidth;
    s += indent() + '}))';

    return s;
};
<|endoftext|>


<commit_before>const fs = require('fs');

var outfilename = 'output.tex'

file = fs.readFileSync('templates/template-header.tex', {encoding: 'utf8'})
fs.writeFileSync(outfilename, file)

function output_left() {
	file = fs.readFileSync('templates/template-page-left.tex', {encoding: 'utf8'})
	fs.appendFileSync(outfilename, file)
}

function output_day( day, dayofweek ) {
	var offset = 27 + 17 * dayofweek
	var date = '\\PlaceText{132mm}{' + offset + 'mm}{\\huge{' + day + '}}\n'
	fs.appendFileSync(outfilename, date)
}

function output_name( name, dayofweek ) {
	var offset = 31 + 17 * dayofweek
	var name = '\\PlaceText{132mm}{' + offset + 'mm}{\\emph{\\tiny{' + name + '}}}\n'
	fs.appendFileSync(outfilename, name)
}

function output_photo( photo ) {
	fs.appendFileSync(outfilename, '\\begin{tikzpicture}[remember picture,overlay]')
	fs.appendFileSync(outfilename, '  \\node[outer sep=0pt,inner sep=0pt,anchor=north]')
	fs.appendFileSync(outfilename, '    at ([xshift=67mm,yshift=-26mm]current page.north west)')
	fs.appendFileSync(outfilename, '    {\\includegraphics[max width=104mm, max height=104mm]{' + photo + '}};')
	fs.appendFileSync(outfilename, '\\end{tikzpicture}')
}

function output_new_page() {
	fs.appendFileSync(outfilename, '\\newpage')
}

var moment = require('moment');
require('moment/locale/cs')

var date = moment("2017-01-01");

var startweekday = date.weekday()

date.add(-startweekday, 'days')

var namedays = require('./namedays.json')
var photos = require('./photos.json')

for(var day = 0 ; day < 14+startweekday; day++ )
{
	var dayofweek = date.weekday()
	if ( day % 7 == 0 ) {
		output_left()
		photo = photos[date.week().toString()]
		if ( photo != undefined ) output_photo(photo)
		console.log("=== Week " + date.week().toString())
	}
	output_day(date.format('D'), day % 7)
	nameday = namedays[date.format('D.M.')]
	if ( nameday != undefined) output_name(nameday, day % 7)
	if ( dayofweek == 6 )
	{
		output_new_page()
	}
	date.add(1, 'days')
}

file = fs.readFileSync('templates/template-footer.tex', {encoding: 'utf8'})
fs.appendFileSync(outfilename, file)
<commit_msg>Implemented generation of whole year<commit_after>const fs = require('fs');

var outfilename = 'output.tex'

var arrange_template = 'templates/template-page-left.tex';
var arrange_text_pos = 132;
var arrange_photo_pos = 67;

var moment = require('moment');
require('moment/locale/cs')

var namedays = require('./namedays.json')
var photos = require('./photos.json')

function set_output_left() {
	arrange_template = 'templates/template-page-left.tex';
	arrange_text_pos = 132;
	arrange_photo_pos = 67;
}

function set_output_right() {
	arrange_template = 'templates/template-page-right.tex';
	arrange_text_pos = 25;
	arrange_photo_pos = 143;
}

function output_template() {
	file = fs.readFileSync(arrange_template, {encoding: 'utf8'})
	fs.appendFileSync(outfilename, file)
}

function output_day( day, dayofweek ) {
	var offset = 27 + 17 * dayofweek
	var date = '\\PlaceText{' + arrange_text_pos + 'mm}{' + offset + 'mm}{\\huge{' + day + '}}\n'
	fs.appendFileSync(outfilename, date)
}

function output_name( name, dayofweek ) {
	var offset = 31 + 17 * dayofweek
	var name = '\\PlaceText{' + arrange_text_pos + 'mm}{' + offset + 'mm}{\\emph{\\tiny{' + name + '}}}\n'
	fs.appendFileSync(outfilename, name)
}

function output_photo( photo ) {
	fs.appendFileSync(outfilename, '\\begin{tikzpicture}[remember picture,overlay]')
	fs.appendFileSync(outfilename, '  \\node[outer sep=0pt,inner sep=0pt,anchor=north]')
	fs.appendFileSync(outfilename, '    at ([xshift=' + arrange_photo_pos + 'mm,yshift=-26mm]current page.north west)')
	fs.appendFileSync(outfilename, '    {\\includegraphics[max width=104mm, max height=104mm]{' + photo + '}};')
	fs.appendFileSync(outfilename, '\\end{tikzpicture}')
}

function output_new_page() {
	fs.appendFileSync(outfilename, '\\newpage')
}

function get_week( week ) {
	var date = moment("2017-01-01");
	var startweekday = date.weekday()
	date.add(-startweekday + week*7, 'days')
	return date
}

function output_week( week ) {
	var date = get_week( week );

	output_template()
	photo = photos[date.week().toString()]
	if ( photo != undefined ) output_photo(photo)
	console.log("=== Week " + date.week().toString())
	for(var day = 0 ; day < 7; day++ )
	{
		output_day(date.format('D'), day % 7)
		nameday = namedays[date.format('D.M.')]
		if ( nameday != undefined) output_name(nameday, day % 7)
		date.add(1, 'days')
	}
	output_new_page()
}

file = fs.readFileSync('templates/template-header.tex', {encoding: 'utf8'})
fs.writeFileSync(outfilename, file)

for ( var week = 0; week < 26; week+=2 ) {
	set_output_left();
	output_week( week );
	output_week( week+1 );
	set_output_right();
	output_week( 51-week );
	output_week( 51-week-1 );
}

file = fs.readFileSync('templates/template-footer.tex', {encoding: 'utf8'})
fs.appendFileSync(outfilename, file)
<|endoftext|>


<commit_before>/*jslint es5: true */

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

define(
        "joynr/messaging/websocket/SharedWebSocket",
        [
            "global/Promise",
            "global/WebSocket",
            "joynr/util/Typing",
            "joynr/util/JSONSerializer",
            "joynr/util/LongTimer",
            "joynr/system/LoggerFactory"
        ],
        function(Promise, WebSocket, Typing, JSONSerializer, LongTimer, LoggerFactory) {
            var log = LoggerFactory.getLogger("joynr.messaging.websocket.SharedWebSocket");
            /**
             * @param address
             * @param {WebSocketAddress}
             *            address to which messages are sent on the clustercontroller.
             * @returns {String} a url
             */
            function webSocketAddressToUrl(address) {
                var url = address.protocol + "://" + address.host + ":" + address.port;
                if (address.path) {
                    url += address.path;
                }
                return url;
            }

            /**
             * @param {WebSocket}
             *            websocket to use for the initialization
             * @param {String}
             *            localAddress address used by the cluster controller to contact this
             *            libjoynr
             */
            function initializeConnection(websocket, localAddress) {
                websocket.send(WebSocket.encodeString(JSON.stringify(localAddress)), {binary: true});
            }

            /**
             * @param {WebSocket}
             *            websocket to use for sending messages
             * @param {Array}
             *            queuedMessages
             */
            function sendQueuedMessages(websocket, queuedMessages) {
                var queued;
                while (queuedMessages.length) {
                    queued = queuedMessages.shift();
                    try {
                        websocket.send(WebSocket.marshalJoynrMessage(queued.message), {binary: true});
                        queued.resolve();
                        // Error is thrown if the socket is no longer open
                    } catch (e) {
                        // so add the message back to the front of the queue
                        queuedMessages.unshift(queued);
                        throw e;
                    }
                }
            }

            function sendMessage(websocket, joynrMessage, queuedMessages) {
                return new Promise(function(resolve, reject){
                    if (websocket.readyState === WebSocket.OPEN) {
                        try {
                            websocket.send(WebSocket.marshalJoynrMessage(joynrMessage), {binary: true});
                            resolve();
                            // Error is thrown if the socket is no longer open, so requeue to the front
                        } catch (e) {
                            // add the message back to the front of the queue
                            queuedMessages.unshift({
                                message : joynrMessage,
                                resolve : resolve
                            });
                            throw e;
                        }
                    } else {
                        // push new messages onto the back of the queue
                        queuedMessages.push({
                            message : joynrMessage,
                            resolve : resolve
                        });
                    }
                });
            }

            /**
             * @name SharedWebSocket
             * @constructor
             * @param {Object}
             *            settings
             * @param {WebSocketClientAddress}
             *            settings.localAddress address used by the websocket server to contact this
             *            client. This address is used in in the init phase on the websocket, and
             *            then registered with the message router on the remote side
             * @param {WebSocketAddress}
             *            settings.remoteAddress to which messages are sent on the websocket server.
             * @param {Object} settings.provisioning
             * @param {Number} settings.provisioning.reconnectSleepTimeMs
             */
            var SharedWebSocket =
                    function SharedWebSocket(settings) {
                        Typing.checkProperty(settings, "Object", "settings");
                        Typing.checkProperty(
                                settings.localAddress,
                                "WebSocketClientAddress",
                                "localAddress");
                        Typing.checkProperty(
                                settings.remoteAddress,
                                "WebSocketAddress",
                                "remoteAddress");

                        var websocket = null;
                        var provisioning = settings.provisioning || {};
                        var reconnectSleepTimeMs = provisioning.reconnectSleepTimeMs || 1000; // default value = 1000ms
                        var localAddress = settings.localAddress;
                        var remoteUrl = webSocketAddressToUrl(settings.remoteAddress);
                        var onmessageCallback = null;
                        var queuedMessages = [];
                        var onOpen;
                        var onError;
                        var onClose;
                        var closed = false;
                        var reconnectTimer;

                        var resetConnection = function resetConnection() {
                            reconnectTimer = undefined;
                            if (closed) {
                                return;
                            }
                            websocket = new WebSocket(remoteUrl);
                            websocket.onopen = onOpen;
                            websocket.onclose = onClose;
                            websocket.onerror = onError;
                            if (onmessageCallback !== null) {
                                websocket.onmessage = onmessageCallback;
                            }
                        };

                        onError = function onError(event) {
                            log.error("error in websocket: "
                                    + event.code
                                    + (event.reason !== undefined ? " reason: "
                                    + event.reason : "")
                                    + ". Resetting connection.");
                            if (reconnectTimer !== undefined) {
                                LongTimer.clearTimeout(reconnectTimer);
                            }
                            reconnectTimer = LongTimer.setTimeout(resetConnection, reconnectSleepTimeMs);
                        };

                        onClose = function onClose(event) {
                            if (event.code !== SharedWebSocket.EVENT_CODE_SHUTDOWN ) {
                                log.info("connection closed unexpectedly. code: "
                                    + event.code
                                    + " reason: "
                                    + event.reason
                                    + ". Trying to reconnect...");
                                if (reconnectTimer !== undefined) {
                                    LongTimer.clearTimeout(reconnectTimer);
                                }
                                reconnectTimer = LongTimer.setTimeout(resetConnection, reconnectSleepTimeMs);
                            } else {
                                log.info("connection closed. reason: " + event.reason);
                            }
                        };

                        // send all queued messages, requeuing to the front in case of a problem
                        onOpen = function onOpen() {
                            try {
                                initializeConnection(websocket, localAddress);
                                sendQueuedMessages(websocket, queuedMessages);
                            } catch (e) {
                                resetConnection();
                            }
                        };

                        resetConnection();

                        /**
                         * @name SharedWebSocket#send
                         * @function
                         * @param {JoynrMessage}
                         *            joynrMessage the joynr message to transmit
                         */
                        this.send = function send(joynrMessage) {
                            return sendMessage(websocket, joynrMessage, queuedMessages).catch(function(e1) {
                                    resetConnection();
                                });
                        };

                        /**
                         * @name SharedWebSocket#close
                         * @function
                         */
                        this.close = function close() {
                            closed = true;
                            if (reconnectTimer !== undefined) {
                                LongTimer.clearTimeout(reconnectTimer);
                                reconnectTimer = undefined;
                            }
                            if (websocket !== null) {
                                websocket.close(SharedWebSocket.EVENT_CODE_SHUTDOWN, "shutdown");
                            }
                        };

                        // using the defineProperty syntax for onmessage to be able to keep
                        // the same API as WebSocket but have a setter function called when
                        // the attribute is set.
                        Object.defineProperty(this, "onmessage", {
                            set : function(newCallback) {
                                if (typeof newCallback === "function") {
                                    onmessageCallback = function(data) {
                                        WebSocket.unmarshalJoynrMessage(data, newCallback);
                                    };
                                    websocket.onmessage = onmessageCallback;
                                } else {
                                    throw new Error(
                                            "onmessage callback must be a function, but instead was of type "
                                                + typeof newCallback);
                                }
                            },
                            get : function() {
                                return onmessageCallback;
                            },
                            enumerable : false,
                            configurable : false
                        });

                    };
            SharedWebSocket.EVENT_CODE_SHUTDOWN = 4000;
            return SharedWebSocket;
        });
<commit_msg>[JS] Prefer static functions: SharedWebSocket<commit_after>/*jslint es5: true */

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

define(
        "joynr/messaging/websocket/SharedWebSocket",
        [
            "global/Promise",
            "global/WebSocket",
            "joynr/util/Typing",
            "joynr/util/JSONSerializer",
            "joynr/util/LongTimer",
            "joynr/system/LoggerFactory"
        ],
        function(Promise, WebSocket, Typing, JSONSerializer, LongTimer, LoggerFactory) {
            var log = LoggerFactory.getLogger("joynr.messaging.websocket.SharedWebSocket");
            /**
             * @param address
             * @param {WebSocketAddress}
             *            address to which messages are sent on the clustercontroller.
             * @returns {String} a url
             */
            function webSocketAddressToUrl(address) {
                var url = address.protocol + "://" + address.host + ":" + address.port;
                if (address.path) {
                    url += address.path;
                }
                return url;
            }

            /**
             * @param {WebSocket}
             *            websocket to use for the initialization
             * @param {String}
             *            localAddress address used by the cluster controller to contact this
             *            libjoynr
             */
            function initializeConnection(websocket, localAddress) {
                websocket.send(WebSocket.encodeString(JSON.stringify(localAddress)), { binary: true });
            }

            /**
             * @param {WebSocket}
             *            websocket to use for sending messages
             * @param {Array}
             *            queuedMessages
             */
            function sendQueuedMessages(websocket, queuedMessages) {
                var queued;
                while (queuedMessages.length) {
                    queued = queuedMessages.shift();
                    try {
                        websocket.send(WebSocket.marshalJoynrMessage(queued.message), { binary: true });
                        queued.resolve();
                        // Error is thrown if the socket is no longer open
                    } catch (e) {
                        // so add the message back to the front of the queue
                        queuedMessages.unshift(queued);
                        throw e;
                    }
                }
            }

            function sendMessage(websocket, joynrMessage, queuedMessages) {

                function sendMessageResolver(resolve, reject){
                    if (websocket.readyState === WebSocket.OPEN) {
                        try {
                            websocket.send(WebSocket.marshalJoynrMessage(joynrMessage), { binary: true });
                            resolve();
                            // Error is thrown if the socket is no longer open, so requeue to the front
                        } catch (e) {
                            // add the message back to the front of the queue
                            queuedMessages.unshift({
                                message: joynrMessage,
                                resolve: resolve
                            });
                            throw e;
                        }
                    } else {
                        // push new messages onto the back of the queue
                        queuedMessages.push({
                            message: joynrMessage,
                            resolve: resolve
                        });
                    }
                }

                return new Promise(sendMessageResolver);
            }

            /**
             * @name SharedWebSocket
             * @constructor
             * @param {Object}
             *            settings
             * @param {WebSocketClientAddress}
             *            settings.localAddress address used by the websocket server to contact this
             *            client. This address is used in in the init phase on the websocket, and
             *            then registered with the message router on the remote side
             * @param {WebSocketAddress}
             *            settings.remoteAddress to which messages are sent on the websocket server.
             * @param {Object} settings.provisioning
             * @param {Number} settings.provisioning.reconnectSleepTimeMs
             */
            var SharedWebSocket =
                    function SharedWebSocket(settings) {
                        Typing.checkProperty(settings, "Object", "settings");
                        Typing.checkProperty(
                                settings.localAddress,
                                "WebSocketClientAddress",
                                "localAddress");
                        Typing.checkProperty(
                                settings.remoteAddress,
                                "WebSocketAddress",
                                "remoteAddress");

                        var websocket = null;
                        var provisioning = settings.provisioning || {};
                        var reconnectSleepTimeMs = provisioning.reconnectSleepTimeMs || 1000; // default value = 1000ms
                        var localAddress = settings.localAddress;
                        var remoteUrl = webSocketAddressToUrl(settings.remoteAddress);
                        var onmessageCallback = null;
                        var queuedMessages = [];
                        var onOpen;
                        var onError;
                        var onClose;
                        var closed = false;
                        var reconnectTimer;

                        var resetConnection = function resetConnection() {
                            reconnectTimer = undefined;
                            if (closed) {
                                return;
                            }
                            websocket = new WebSocket(remoteUrl);
                            websocket.onopen = onOpen;
                            websocket.onclose = onClose;
                            websocket.onerror = onError;
                            if (onmessageCallback !== null) {
                                websocket.onmessage = onmessageCallback;
                            }
                        };

                        onError = function onError(event) {
                            log.error("error in websocket: "
                                    + event.code
                                    + (event.reason !== undefined ? " reason: "
                                    + event.reason : "")
                                    + ". Resetting connection.");
                            if (reconnectTimer !== undefined) {
                                LongTimer.clearTimeout(reconnectTimer);
                            }
                            reconnectTimer = LongTimer.setTimeout(resetConnection, reconnectSleepTimeMs);
                        };

                        onClose = function onClose(event) {
                            if (event.code !== SharedWebSocket.EVENT_CODE_SHUTDOWN ) {
                                log.info("connection closed unexpectedly. code: "
                                    + event.code
                                    + " reason: "
                                    + event.reason
                                    + ". Trying to reconnect...");
                                if (reconnectTimer !== undefined) {
                                    LongTimer.clearTimeout(reconnectTimer);
                                }
                                reconnectTimer = LongTimer.setTimeout(resetConnection, reconnectSleepTimeMs);
                            } else {
                                log.info("connection closed. reason: " + event.reason);
                            }
                        };

                        // send all queued messages, requeuing to the front in case of a problem
                        onOpen = function onOpen() {
                            try {
                                initializeConnection(websocket, localAddress);
                                sendQueuedMessages(websocket, queuedMessages);
                            } catch (e) {
                                resetConnection();
                            }
                        };

                        resetConnection();

                        /**
                         * @name SharedWebSocket#send
                         * @function
                         * @param {JoynrMessage}
                         *            joynrMessage the joynr message to transmit
                         */
                        this.send = function send(joynrMessage) {

                            function sendMessageOnError(e1) {
                                resetConnection();
                            }

                            return sendMessage(websocket, joynrMessage, queuedMessages).catch(sendMessageOnError);
                        };

                        /**
                         * @name SharedWebSocket#close
                         * @function
                         */
                        this.close = function close() {
                            closed = true;
                            if (reconnectTimer !== undefined) {
                                LongTimer.clearTimeout(reconnectTimer);
                                reconnectTimer = undefined;
                            }
                            if (websocket !== null) {
                                websocket.close(SharedWebSocket.EVENT_CODE_SHUTDOWN, "shutdown");
                            }
                        };

                        // using the defineProperty syntax for onmessage to be able to keep
                        // the same API as WebSocket but have a setter function called when
                        // the attribute is set.
                        Object.defineProperty(this, "onmessage", {
                            set: function(newCallback) {
                                if (typeof newCallback === "function") {
                                    onmessageCallback = function(data) {
                                        WebSocket.unmarshalJoynrMessage(data, newCallback);
                                    };
                                    websocket.onmessage = onmessageCallback;
                                } else {
                                    throw new Error(
                                            "onmessage callback must be a function, but instead was of type "
                                                + typeof newCallback);
                                }
                            },
                            get: function() {
                                return onmessageCallback;
                            },
                            enumerable  : false,
                            configurable: false
                        });

                    };
            SharedWebSocket.EVENT_CODE_SHUTDOWN = 4000;
            return SharedWebSocket;
        });
<|endoftext|>


<commit_before>/**
 * Players Game Flow
 */
'use strict';

import * as async from 'async';

/**
 * Players game flow class.
 *
 * @class Players
 */
export default class {
  constructor(app) {
    this.app = app;

    /**
     * List with players currently on the server.
     * Includes fetched data from database.
     *
     * Key: login
     * Value: Player object
     *
     * @type {{}}
     */
    this.list = {};
  }

  boot() {
    // Get all current players, controller just boot.
    return new Promise((resolve, reject) => {
      this.app.serverFacade.client.gbx.query('GetPlayerList', [-1, 0], (err, players) => {
        // Loop and fetch players.
        async.eachSeries(players, (player, callback) => {
          if (player.PlayerId === 0) {
            return callback();
          }

          let isSpectator =       player.SpectatorStatus           % 10;
          let isTempSpectator =  (player.SpectatorStatus / 10)     % 10;
          let isPureSpectator =  (player.SpectatorStatus / 100)    % 10;
          let autoTarget =       (player.SpectatorStatus / 1000)   % 10;
          let targetId =         (player.SpectatorStatus / 10000)      ;
          let info = {
            login: player.Login,
            nickName: player.NickName,
            playerId: player.PlayerId,
            teamId: player.TeamId,
            spectatorStatus: player.SpectatorStatus,
            flags: player.Flags,

            isSpectator: isSpectator,
            isTempSpectator: isTempSpectator,
            isPureSpectator: isPureSpectator,
            autoTarget: autoTarget,
            targetId: targetId
          };

          // Fetch from database
          this.update(player.Login, player.NickName, info)
            .then(() => {
              callback();
            })
            .catch((err) => {
              callback(err);
            });
        }, (err) => {
          if (err) {
            return reject(err);
          }
          return resolve();
        });
      });
    });
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countPlayers() {
    return this.list.filter((value) => {
      return value.hasOwnProperty('info') && ! value.info.isSpectator;
    }).length;
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countSpectators() {
    return this.list.filter((value) => {
      return value.hasOwnProperty('info') && value.info.isSpectator;
    }).length;
  }

  /**
   * Call when player connect event is given.
   *
   * @param login
   * @returns {Promise.<T>}
   */
  connect(login) {
    return Promise.resolve();
  }

  /**
   * Call when info changed.
   *
   * @param login
   * @param nickname
   * @param info
   * @returns {Promise}
   */
  update(login, nickname, info) {
    info = info || {};

    let Player = this.app.models.Player;

    return new Promise((resolve, reject) => {
      if (! this.list.hasOwnProperty(login)) {
        // Fetch or create from db.
        Player.findOne({
          where: {
            login: login
          }
        }).then((player) => {
          if (! player) {
            // Create
            return Player.create({
              login: login,
              nickname: nickname
            }).then((player) => {
              player.info = info;
              this.list[login] = player;

              return resolve();
            }).catch((err) => {
              return reject(err);
            });
          }

          if (player.nickname === nickname) {
            player.info = info;
            this.list[login] = player;
            return resolve();
          }

          // Update
          player.set('nickname', nickname);
          player.save()
            .then((player) => {
              player.info = info;
              this.list[login] = player;
              resolve();
            })
            .catch((err) => {
              reject(err);
            });

        }).catch((err) => {
          reject(err);
        });
      } else {
        // Update info only.
        this.list[login].info = info;
      }
    });
  }

  /**
   * Call disconnected
   * @param login
   */
  disconnect(login) {
    // Remove from this.list (after 5 seconds);
    setTimeout(() => {
      if (this.list.hasOwnProperty(login)) {
        delete this.list[login];
      }
    }, 5000);
  }
}<commit_msg>Adding permission functions to players game class.<commit_after>/**
 * Players Game Flow
 */
'use strict';

import * as async from 'async';

/**
 * Players game flow class.
 *
 * @class Players
 */
export default class {
  constructor(app) {
    this.app = app;

    /**
     * List with players currently on the server.
     * Includes fetched data from database.
     *
     * Key: login
     * Value: Player object
     *
     * @type {{}}
     */
    this.list = {};
  }

  boot() {
    // Get all current players, controller just boot.
    return new Promise((resolve, reject) => {
      this.app.serverFacade.client.gbx.query('GetPlayerList', [-1, 0], (err, players) => {
        // Loop and fetch players.
        async.eachSeries(players, (player, callback) => {
          if (player.PlayerId === 0) {
            return callback();
          }
          let isSpectator =       player.SpectatorStatus           % 10;
          let isTempSpectator =  (player.SpectatorStatus / 10)     % 10;
          let isPureSpectator =  (player.SpectatorStatus / 100)    % 10;
          let autoTarget =       (player.SpectatorStatus / 1000)   % 10;
          let targetId =         (player.SpectatorStatus / 10000)      ;
          let info = {
            login: player.Login,
            nickName: player.NickName,
            playerId: player.PlayerId,
            teamId: player.TeamId,
            spectatorStatus: player.SpectatorStatus,
            flags: player.Flags,

            isSpectator: isSpectator,
            isTempSpectator: isTempSpectator,
            isPureSpectator: isPureSpectator,
            autoTarget: autoTarget,
            targetId: targetId
          };

          // Fetch from database
          this.update(player.Login, player.NickName, info)
            .then(() => {
              callback();
            })
            .catch((err) => {
              callback(err);
            });
        }, (err) => {
          if (err) {
            return reject(err);
          }
          return resolve();
        });
      });
    });
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countPlayers() {
    return this.list.filter((value) => {
      return value.hasOwnProperty('info') && ! value.info.isSpectator;
    }).length;
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countSpectators() {
    return this.list.filter((value) => {
      return value.hasOwnProperty('info') && value.info.isSpectator;
    }).length;
  }

  /**
   * Is Login Player?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isPlayer(login) {
    return this.isLevel(login, 0);
  }

  /**
   * Is Login Operator?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isOperator(login) {
    return this.isLevel(login, 1);
  }

  /**
   * Is Login Admin?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isAdmin(login) {
    return this.isLevel(login, 2);
  }

  /**
   * Is Login MasterAdmin?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isMasterAdmin(login) {
    return this.isLevel(login, 3);
  }

  /**
   * Is Login Minimum Level?
   *
   * @param {string} login
   * @param {number} level Mininum level, 0, 1, 2 or 3.
   * @returns {boolean}
   */
  isMinimal(login, level) {
    return this.isLevel(login, level, true);
  }

  /**
   * Is Login Level.
   *
   * @private
   * @param login
   * @param level
   * @param minimum
   * @returns {boolean}
   */
  isLevel(login, level, minimum) {
    minimum = minimum || false;
    if (this.list.hasOwnProperty(login)) {
      if (minimum) {
        return (this.list[login].level >= level);
      }
      return (this.list[login].level === level);
    }
    return false;
  }

  /**
   * Set Player Level.
   *
   * @param {string} login
   * @param {number} level
   * @returns {Promise}
   */
  setLevel(login, level) {
    if (this.list.hasOwnProperty(login)) {
      this.list[login].set('level', level);
      return this.list[login].save();
    }
    return Promise.reject(new Error('Player not in list!'));
  }

  /**
   * GAME FLOW FUNCTIONS
   */

  /**
   * Call when player connect event is given.
   *
   * @param login
   * @returns {Promise.<T>}
   */
  connect(login) {
    return Promise.resolve();
  }

  /**
   * Call when info changed.
   *
   * @param login
   * @param nickname
   * @param info
   * @returns {Promise}
   */
  update(login, nickname, info) {
    info = info || {};

    let Player = this.app.models.Player;

    return new Promise((resolve, reject) => {
      if (! this.list.hasOwnProperty(login)) {
        // Fetch or create from db.
        Player.findOne({
          where: {
            login: login
          }
        }).then((player) => {
          if (! player) {
            // Create
            return Player.create({
              login: login,
              nickname: nickname
            }).then((player) => {
              player.info = info;
              this.list[login] = player;

              return resolve();
            }).catch((err) => {
              return reject(err);
            });
          }

          if (player.nickname === nickname) {
            player.info = info;
            this.list[login] = player;
            return resolve();
          }

          // Update
          player.set('nickname', nickname);
          player.save()
            .then((player) => {
              player.info = info;
              this.list[login] = player;
              resolve();
            })
            .catch((err) => {
              reject(err);
            });

        }).catch((err) => {
          reject(err);
        });
      } else {
        // Update info only.
        this.list[login].info = info;
      }
    });
  }

  /**
   * Call disconnected
   * @param login
   */
  disconnect(login) {
    // Remove from this.list (after 5 seconds);
    setTimeout(() => {
      if (this.list.hasOwnProperty(login)) {
        delete this.list[login];
      }
    }, 5000);
  }
}<|endoftext|>


<commit_before>/**
 * Players Game Flow
 */
'use strict';

import * as async from 'async';

/**
 * Players game flow class.
 *
 * @class Players
 */
export default class {
  constructor(app) {
    this.app = app;

    /**
     * List with players currently on the server.
     * Includes fetched data from database.
     *
     * Key: login
     * Value: Player object
     *
     * @type {{}}
     */
    this.list = {};
  }

  boot() {
    // Get all current players, controller just boot.
    return new Promise((resolve, reject) => {
      this.app.serverFacade.client.gbx.query('GetPlayerList', [-1, 0], (err, players) => {
        // Loop and fetch players.
        async.eachSeries(players, (player, callback) => {
          if (player.PlayerId === 0) {
            return callback();
          }
          let isSpectator =       player.SpectatorStatus           % 10;
          let isTempSpectator =  (player.SpectatorStatus / 10)     % 10;
          let isPureSpectator =  (player.SpectatorStatus / 100)    % 10;
          let autoTarget =       (player.SpectatorStatus / 1000)   % 10;
          let targetId =         (player.SpectatorStatus / 10000)      ;
          let info = {
            login: player.Login,
            nickName: player.NickName,
            playerId: player.PlayerId,
            teamId: player.TeamId,
            spectatorStatus: player.SpectatorStatus,
            flags: player.Flags,

            isSpectator: isSpectator,
            isTempSpectator: isTempSpectator,
            isPureSpectator: isPureSpectator,
            autoTarget: autoTarget,
            targetId: targetId
          };

          // Fetch from database
          this.update(player.Login, player.NickName, info)
            .then(() => {
              callback();
            })
            .catch((err) => {
              callback(err);
            });
        }, (err) => {
          if (err) {
            return reject(err);
          }
          return resolve();
        });
      });
    });
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countPlayers() {
    return this.list.filter((value) => {
      return value.hasOwnProperty('info') && ! value.info.isSpectator;
    }).length;
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countSpectators() {
    return this.list.filter((value) => {
      return value.hasOwnProperty('info') && value.info.isSpectator;
    }).length;
  }

  /**
   * Is Login Player?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isPlayer(login) {
    return this.isLevel(login, 0);
  }

  /**
   * Is Login Operator?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isOperator(login) {
    return this.isLevel(login, 1);
  }

  /**
   * Is Login Admin?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isAdmin(login) {
    return this.isLevel(login, 2);
  }

  /**
   * Is Login MasterAdmin?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isMasterAdmin(login) {
    return this.isLevel(login, 3);
  }

  /**
   * Is Login Minimum Level?
   *
   * @param {string} login
   * @param {number} level Mininum level, 0, 1, 2 or 3.
   * @returns {boolean}
   */
  isMinimal(login, level) {
    return this.isLevel(login, level, true);
  }

  /**
   * Is Login Level.
   *
   * @private
   * @param login
   * @param level
   * @param minimum
   * @returns {boolean}
   */
  isLevel(login, level, minimum) {
    minimum = minimum || false;
    if (this.list.hasOwnProperty(login)) {
      if (minimum) {
        return (this.list[login].level >= level);
      }
      return (this.list[login].level === level);
    }
    return false;
  }

  /**
   * Set Player Level.
   *
   * @param {string} login
   * @param {number} level
   * @returns {Promise}
   */
  setLevel(login, level) {
    if (this.list.hasOwnProperty(login)) {
      this.list[login].set('level', level);
      return this.list[login].save();
    }
    return Promise.reject(new Error('Player not in list!'));
  }

  /**
   * GAME FLOW FUNCTIONS
   */

  /**
   * Call when player connect event is given.
   *
   * @param login
   * @returns {Promise.<T>}
   */
  connect(login) {
    return Promise.resolve();
  }

  /**
   * Call when info changed.
   *
   * @param login
   * @param nickname
   * @param info
   * @returns {Promise}
   */
  update(login, nickname, info) {
    info = info || {};

    let Player = this.app.models.Player;

    return new Promise((resolve, reject) => {
      if (! this.list.hasOwnProperty(login)) {
        // Fetch or create from db.
        Player.findOne({
          where: {
            login: login
          }
        }).then((player) => {
          if (! player) {
            // Create
            return Player.create({
              login: login,
              nickname: nickname
            });
          }

          if (player.nickname === nickname) {
            return resolve(player);
          }

          // Update
          player.set('nickname', nickname);
          return player.save();
        }).catch((err) => {
          return reject(err);
        });
      } else {
        // Update info only.
        this.list[login].info = info;
        return resolve(false);
      }
    }).then((player) => {
      if (! player) {
        // No update!
        return;
      }

      // Update needed, save to local list.
      player.info = info;
      this.list[login] = player;

      // Maybe this player is the masteradmin? (see config).
      if (this.app.config.hasOwnProperty('masteradmins') && this.app.config.masteradmins) {
        if (this.app.config.masteradmins.filter((adminLogin => adminLogin === login)).length > 0) {
          // Yes! Make the player admin!
          return this.setLevel(login, 3);
        }
      }
    });
  }

  /**
   * Call disconnected
   * @param login
   */
  disconnect(login) {
    // Remove from this.list (after 5 seconds);
    setTimeout(() => {
      if (this.list.hasOwnProperty(login)) {
        delete this.list[login];
      }
    }, 5000);
  }
}<commit_msg>Bugfix in the player and spec counters<commit_after>/**
 * Players Game Flow
 */
'use strict';

import * as async from 'async';

/**
 * Players game flow class.
 *
 * @class Players
 */
export default class {
  constructor(app) {
    this.app = app;

    /**
     * List with players currently on the server.
     * Includes fetched data from database.
     *
     * Key: login
     * Value: Player object
     *
     * @type {object}
     */
    this.list = {};
  }

  boot() {
    // Get all current players, controller just boot.
    return new Promise((resolve, reject) => {
      this.app.serverFacade.client.gbx.query('GetPlayerList', [-1, 0], (err, players) => {
        // Loop and fetch players.
        async.eachSeries(players, (player, callback) => {
          if (player.PlayerId === 0) {
            return callback();
          }
          let isSpectator =       player.SpectatorStatus           % 10;
          let isTempSpectator =  (player.SpectatorStatus / 10)     % 10;
          let isPureSpectator =  (player.SpectatorStatus / 100)    % 10;
          let autoTarget =       (player.SpectatorStatus / 1000)   % 10;
          let targetId =         (player.SpectatorStatus / 10000)      ;
          let info = {
            login: player.Login,
            nickName: player.NickName,
            playerId: player.PlayerId,
            teamId: player.TeamId,
            spectatorStatus: player.SpectatorStatus,
            flags: player.Flags,

            isSpectator: isSpectator,
            isTempSpectator: isTempSpectator,
            isPureSpectator: isPureSpectator,
            autoTarget: autoTarget,
            targetId: targetId
          };

          // Fetch from database
          this.update(player.Login, player.NickName, info)
            .then(() => {
              callback();
            })
            .catch((err) => {
              callback(err);
            });
        }, (err) => {
          if (err) {
            return reject(err);
          }
          return resolve();
        });
      });
    });
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countPlayers() {
    var num = 0;
    if (! this.list) return num;

    for (let login in this.list) {
      let one = this.list[login];
      if (one.info && ! one.info.isSpectator) {
        num++;
      }
    }
    return num;
  }

  /**
   * Count players (non-spectators).
   * @returns {int}
   */
  countSpectators() {
    var num = 0;
    if (! this.list) return num;

    for (let login in this.list) {
      let one = this.list[login];
      if (one.info && one.info.isSpectator) {
        num++;
      }
    }
    return num;
  }

  /**
   * Is Login Player?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isPlayer(login) {
    return this.isLevel(login, 0);
  }

  /**
   * Is Login Operator?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isOperator(login) {
    return this.isLevel(login, 1);
  }

  /**
   * Is Login Admin?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isAdmin(login) {
    return this.isLevel(login, 2);
  }

  /**
   * Is Login MasterAdmin?
   *
   * @param {string} login
   * @returns {boolean}
   */
  isMasterAdmin(login) {
    return this.isLevel(login, 3);
  }

  /**
   * Is Login Minimum Level?
   *
   * @param {string} login
   * @param {number} level Mininum level, 0, 1, 2 or 3.
   * @returns {boolean}
   */
  isMinimal(login, level) {
    return this.isLevel(login, level, true);
  }

  /**
   * Is Login Level.
   *
   * @private
   * @param login
   * @param level
   * @param minimum
   * @returns {boolean}
   */
  isLevel(login, level, minimum) {
    minimum = minimum || false;
    if (this.list.hasOwnProperty(login)) {
      if (minimum) {
        return (this.list[login].level >= level);
      }
      return (this.list[login].level === level);
    }
    return false;
  }

  /**
   * Set Player Level.
   *
   * @param {string} login
   * @param {number} level
   * @returns {Promise}
   */
  setLevel(login, level) {
    if (this.list.hasOwnProperty(login)) {
      this.list[login].set('level', level);
      return this.list[login].save();
    }
    return Promise.reject(new Error('Player not in list!'));
  }

  /**
   * GAME FLOW FUNCTIONS
   */

  /**
   * Call when player connect event is given.
   *
   * @param login
   * @returns {Promise.<T>}
   */
  connect(login) {
    return Promise.resolve();
  }

  /**
   * Call when info changed.
   *
   * @param login
   * @param nickname
   * @param info
   * @returns {Promise}
   */
  update(login, nickname, info) {
    info = info || {};

    let Player = this.app.models.Player;

    return new Promise((resolve, reject) => {
      if (! this.list.hasOwnProperty(login)) {
        // Fetch or create from db.
        Player.findOne({
          where: {
            login: login
          }
        }).then((player) => {
          if (! player) {
            // Create
            return Player.create({
              login: login,
              nickname: nickname
            });
          }

          if (player.nickname === nickname) {
            return resolve(player);
          }

          // Update
          player.set('nickname', nickname);
          return player.save();
        }).catch((err) => {
          return reject(err);
        });
      } else {
        // Update info only.
        this.list[login].info = info;
        return resolve(false);
      }
    }).then((player) => {
      if (! player) {
        // No update!
        return;
      }

      // Update needed, save to local list.
      player.info = info;
      this.list[login] = player;

      // Maybe this player is the masteradmin? (see config).
      if (this.app.config.hasOwnProperty('masteradmins') && this.app.config.masteradmins) {
        if (this.app.config.masteradmins.filter((adminLogin => adminLogin === login)).length > 0) {
          // Yes! Make the player admin!
          return this.setLevel(login, 3);
        }
      }
    });
  }

  /**
   * Call disconnected
   * @param login
   */
  disconnect(login) {
    // Remove from this.list (after 5 seconds);
    setTimeout(() => {
      if (this.list.hasOwnProperty(login)) {
        delete this.list[login];
      }
    }, 5000);
  }
}<|endoftext|>


<commit_before>(function(){
	"use strict";

	var html         = document.documentElement;
	var touchEnabled = "ontouchstart" in html;

	/** Event types */
	var START     = touchEnabled ? "touchstart"  : "mousedown";
	var MOVE      = touchEnabled ? "touchmove"   : "mousemove";
	var END       = touchEnabled ? "touchend"    : "mouseup";
	var CANCEL    = touchEnabled ? "touchcancel" : null;

	function Gesture(el, options){
		options           = options || {};
		var THIS          = this;
		var _tracking     = false;

		var startCallback = options.onStart;
		var moveCallback  = options.onMove;
		var endCallback   = options.onEnd;

		Object.defineProperties(THIS, {
			getCoords: { value: getCoords },
			distance:  { value: distance  },

			/** Whether the gesture's currently being made */
			tracking: {
				get: function(){ return _tracking },
				set: function(i){
					if((i = !!i) !== _tracking){
						_tracking = i;

						if(i){
							html.addEventListener(MOVE, onMove);
							html.addEventListener(END,  onEnd);

							CANCEL && html.addEventListener(CANCEL, onEnd);
							window.addEventListener("blur", onEnd);
						}

						else{
							html.removeEventListener(MOVE, onMove);
							html.removeEventListener(END,  onEnd);

							CANCEL && html.removeEventListener(CANCEL, onEnd);
							window.removeEventListener("blur", onEnd);
						}
					}
				}
			}
		});

		/** Measure the distance between two points */
		function distance(a, b){
			return Math.sqrt(Math.pow(b[0] - a[0], 2) + Math.pow(b[1] - a[1], 2));
		}

		/**
		 * Return an array of [x,y] coordinates for an event instance.
		 *
		 * For desktop devices, the array will generally hold one element only.
		 * Touch-enabled devices may return more depending on how many fingers
		 * triggered the event.
		 *
		 * @param {Event} event
		 * @return {Array}
		 */
		function getCoords(event){

			/** Touch-enabled device */
			if(touches = event.touches){
				var touches, result  = [];
				for(var t, i = 0, l = touches.length; i < l; ++i){
					t = touches[i];
					result.push([t.pageX, t.pageY]);
				}
				return result;
			}

			/** MouseEvent or something similar */
			else return [[event.pageX, event.pageY]];
		}

		function onMove(event){
			event.preventDefault();

			moveCallback && moveCallback.call(null, event, THIS);
		};

		function onEnd(event){
			THIS.tracking = false;
			event.preventDefault();

			endCallback && endCallback.call(null, event, THIS);
		};

		el.addEventListener(START, function(event){

			if(startCallback && false === startCallback.call(null, event, THIS))
				return;

			THIS.tracking = true;
			event.preventDefault();
		});
	}

	/** Export */
	window.Gesture = Gesture;
}());
<commit_msg>Revert "Add utility method to measure distance between points"<commit_after>(function(){
	"use strict";

	var html         = document.documentElement;
	var touchEnabled = "ontouchstart" in html;

	/** Event types */
	var START     = touchEnabled ? "touchstart"  : "mousedown";
	var MOVE      = touchEnabled ? "touchmove"   : "mousemove";
	var END       = touchEnabled ? "touchend"    : "mouseup";
	var CANCEL    = touchEnabled ? "touchcancel" : null;

	function Gesture(el, options){
		options           = options || {};
		var THIS          = this;
		var _tracking     = false;

		var startCallback = options.onStart;
		var moveCallback  = options.onMove;
		var endCallback   = options.onEnd;

		Object.defineProperties(THIS, {
			getCoords: { value: getCoords },

			/** Whether the gesture's currently being made */
			tracking: {
				get: function(){ return _tracking },
				set: function(i){
					if((i = !!i) !== _tracking){
						_tracking = i;

						if(i){
							html.addEventListener(MOVE, onMove);
							html.addEventListener(END,  onEnd);

							CANCEL && html.addEventListener(CANCEL, onEnd);
							window.addEventListener("blur", onEnd);
						}

						else{
							html.removeEventListener(MOVE, onMove);
							html.removeEventListener(END,  onEnd);

							CANCEL && html.removeEventListener(CANCEL, onEnd);
							window.removeEventListener("blur", onEnd);
						}
					}
				}
			}
		});

		/**
		 * Return an array of [x,y] coordinates for an event instance.
		 *
		 * For desktop devices, the array will generally hold one element only.
		 * Touch-enabled devices may return more depending on how many fingers
		 * triggered the event.
		 *
		 * @param {Event} event
		 * @return {Array}
		 */
		function getCoords(event){

			/** Touch-enabled device */
			if(touches = event.touches){
				var touches, result  = [];
				for(var t, i = 0, l = touches.length; i < l; ++i){
					t = touches[i];
					result.push([t.pageX, t.pageY]);
				}
				return result;
			}

			/** MouseEvent or something similar */
			else return [[event.pageX, event.pageY]];
		}

		function onMove(event){
			event.preventDefault();

			moveCallback && moveCallback.call(null, event, THIS);
		};

		function onEnd(event){
			THIS.tracking = false;
			event.preventDefault();

			endCallback && endCallback.call(null, event, THIS);
		};

		el.addEventListener(START, function(event){

			if(startCallback && false === startCallback.call(null, event, THIS))
				return;

			THIS.tracking = true;
			event.preventDefault();
		});
	}

	/** Export */
	window.Gesture = Gesture;
}());
<|endoftext|>


<commit_before><commit_msg>Fix variable declaration order<commit_after><|endoftext|>


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

'use strict';

// MODULES //

var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var pow = require( '@stdlib/math/base/special/pow' );
var round = require( '@stdlib/math/base/special/round' );
var filledarray = require( '@stdlib/array/filled' );
var pkg = require( './../package.json' ).name;
var quaternary = require( './../lib/ndarray.js' );

// VARIABLES //

var types = [ 'float64' ];

// FUNCTIONS //

/**
* Returns the sum.
*
* @private
* @param {number} x - value
* @param {number} y - value
* @param {number} z - value
* @param {number} w - value
* @returns {number} sum
*/
function add( x, y, z, w ) {
	return x + y + z + w;
}

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @param {string} xtype - input array data type
* @param {string} ytype - input array data type
* @param {string} ztype - input array data type
* @param {string} wtype - input array data type
* @param {string} otype - output array data type
* @returns {Function} benchmark function
*/
function createBenchmark( len, xtype, ytype, ztype, wtype, otype ) {
	var strides;
	var offsets;
	var arrays;
	var shape;
	var x;
	var y;
	var z;
	var w;
	var o;
	var i;

	x = filledarray( 0.0, len, xtype );
	y = filledarray( 0.0, len, ytype );
	z = filledarray( 0.0, len, ztype );
	w = filledarray( 0.0, len, ztype );
	o = filledarray( 0.0, len, otype );
	for ( i = 0; i < len; i++ ) {
		x[ i ] = round( ( randu()*200.0 ) - 100.0 );
		y[ i ] = round( ( randu()*200.0 ) - 100.0 );
		z[ i ] = round( ( randu()*200.0 ) - 100.0 );
		w[ i ] = round( ( randu()*200.0 ) - 100.0 );
	}
	arrays = [ x, y, z, w, o ];
	shape = [ len ];
	strides = [ 1, 1, 1, 1, 1 ];
	offsets = [ 0, 0, 0, 0, 0 ];

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var i;

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			quaternary( arrays, shape, strides, offsets, add );
			if ( isnan( o[ i%len ] ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( arrays[ 4 ][ i%len ] ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );
		b.end();
	}
}

// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
	var len;
	var min;
	var max;
	var t1;
	var t2;
	var t3;
	var t4;
	var t5;
	var f;
	var i;
	var j;

	min = 1; // 10^min
	max = 6; // 10^max

	for ( j = 0; j < types.length; j++ ) {
		t1 = types[ j ];
		t2 = types[ j ];
		t3 = types[ j ];
		t4 = types[ j ];
		t5 = types[ j ];
		for ( i = min; i <= max; i++ ) {
			len = pow( 10, i );
			f = createBenchmark( len, t1, t2, t3, t4, t5 );
			bench( pkg+':ndarray:len='+len+',xtype='+t1+',ytype='+t2+',ztype='+t3+',wtype='+t4+',otype='+t5, f );
		}
	}
}

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

'use strict';

// MODULES //

var bench = require( '@stdlib/bench' );
var randu = require( '@stdlib/random/base/randu' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var pow = require( '@stdlib/math/base/special/pow' );
var round = require( '@stdlib/math/base/special/round' );
var filledarray = require( '@stdlib/array/filled' );
var pkg = require( './../package.json' ).name;
var quaternary = require( './../lib/ndarray.js' );

// VARIABLES //

var types = [ 'float64' ];

// FUNCTIONS //

/**
* Returns the sum.
*
* @private
* @param {number} x - value
* @param {number} y - value
* @param {number} z - value
* @param {number} w - value
* @returns {number} sum
*/
function add( x, y, z, w ) {
	return x + y + z + w;
}

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @param {string} xtype - input array data type
* @param {string} ytype - input array data type
* @param {string} ztype - input array data type
* @param {string} wtype - input array data type
* @param {string} otype - output array data type
* @returns {Function} benchmark function
*/
function createBenchmark( len, xtype, ytype, ztype, wtype, otype ) {
	var strides;
	var offsets;
	var arrays;
	var shape;
	var x;
	var y;
	var z;
	var w;
	var o;
	var i;

	x = filledarray( 0.0, len, xtype );
	y = filledarray( 0.0, len, ytype );
	z = filledarray( 0.0, len, ztype );
	w = filledarray( 0.0, len, wtype );
	o = filledarray( 0.0, len, otype );
	for ( i = 0; i < len; i++ ) {
		x[ i ] = round( ( randu()*200.0 ) - 100.0 );
		y[ i ] = round( ( randu()*200.0 ) - 100.0 );
		z[ i ] = round( ( randu()*200.0 ) - 100.0 );
		w[ i ] = round( ( randu()*200.0 ) - 100.0 );
	}
	arrays = [ x, y, z, w, o ];
	shape = [ len ];
	strides = [ 1, 1, 1, 1, 1 ];
	offsets = [ 0, 0, 0, 0, 0 ];

	return benchmark;

	/**
	* Benchmark function.
	*
	* @private
	* @param {Benchmark} b - benchmark instance
	*/
	function benchmark( b ) {
		var i;

		b.tic();
		for ( i = 0; i < b.iterations; i++ ) {
			quaternary( arrays, shape, strides, offsets, add );
			if ( isnan( o[ i%len ] ) ) {
				b.fail( 'should not return NaN' );
			}
		}
		b.toc();
		if ( isnan( arrays[ 4 ][ i%len ] ) ) {
			b.fail( 'should not return NaN' );
		}
		b.pass( 'benchmark finished' );
		b.end();
	}
}

// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
	var len;
	var min;
	var max;
	var t1;
	var t2;
	var t3;
	var t4;
	var t5;
	var f;
	var i;
	var j;

	min = 1; // 10^min
	max = 6; // 10^max

	for ( j = 0; j < types.length; j++ ) {
		t1 = types[ j ];
		t2 = types[ j ];
		t3 = types[ j ];
		t4 = types[ j ];
		t5 = types[ j ];
		for ( i = min; i <= max; i++ ) {
			len = pow( 10, i );
			f = createBenchmark( len, t1, t2, t3, t4, t5 );
			bench( pkg+':ndarray:len='+len+',xtype='+t1+',ytype='+t2+',ztype='+t3+',wtype='+t4+',otype='+t5, f );
		}
	}
}

main();
<|endoftext|>


<commit_before>trackerdash.views.ResultTablePane = Backbone.View.extend({
    el: '.result-table-pane',

    initialize: function (settings) {
        this.results = settings.percentErrorByDataset;
        if (this.results === undefined) {
            console.error('No error percentages defined.');
        }
        this.render();
    },

    render: function () {

        _.each(this.results, function (result) {
            result.id = result.dataset.replace(".","_");
        });

        var resultsByDataset = _.groupBy(this.results, function (result) {
            return result.dataset;
        });

        this.$el.html(jade.templates.tablePane({
            resultsByDataset: resultsByDataset
        }));

        this.$el.promise().done(_.bind(function () {
            _.each(this.results, function (result) {
                new trackerdash.views.ErrorBulletWidget({
                    el: '#' + result.id + '-' + result.metric + ' svg',
                    result: result
                });
            });
        }, this));
    }

});
<commit_msg>Replace all occurrences of dot, not just the first<commit_after>trackerdash.views.ResultTablePane = Backbone.View.extend({
    el: '.result-table-pane',

    initialize: function (settings) {
        this.results = settings.percentErrorByDataset;
        if (this.results === undefined) {
            console.error('No error percentages defined.');
        }
        this.render();
    },

    render: function () {

        _.each(this.results, function (result) {
            result.id = result.dataset.replace(/\./g, "_");
        });

        var resultsByDataset = _.groupBy(this.results, function (result) {
            return result.dataset;
        });

        this.$el.html(jade.templates.tablePane({
            resultsByDataset: resultsByDataset
        }));

        this.$el.promise().done(_.bind(function () {
            _.each(this.results, function (result) {
                new trackerdash.views.ErrorBulletWidget({
                    el: '#' + result.id + '-' + result.metric + ' svg',
                    result: result
                });
            });
        }, this));
    }

});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';

import Queue from './Queue';

class SearchBooksText extends Component {
  constructor() {
    super();

    this.queue = new Queue();
  }

  static propTypes = {
    search: PropTypes.func.isRequired
  }

  state = {
    searchText: ""
  }

  setSearchText = (event) => {
    var searchText = event.target.value;
    this.setState({ searchText });

    this.queue.push(() => {
      return new Promise((resolve, reject) => {
        this.props.search(searchText).then((res) => {
          resolve(res);
        });
      });
    });
  }

  render() {
    return (
      <input type="text" onChange={this.setSearchText} value={this.state.searchText} placeholder="Search by title or author" />
    );
  }
}

export default SearchBooksText;<commit_msg>SearchBookText > Added localStorage for searchText<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';

import Queue from './Queue';

class SearchBooksText extends Component {
  constructor(props) {
    super(props);

    this.queue = new Queue();

    var searchText = localStorage.getItem("searchText");

    if (searchText) {
      this.state = {
        searchText: searchText
      };
      this.search(searchText);
    }
  }

  static propTypes = {
    search: PropTypes.func.isRequired
  }

  state = {
    searchText: ""
  }

  search(searchText) {
    this.queue.push(() => {
      return new Promise((resolve, reject) => {
        this.props.search(searchText).then((res) => {
          resolve(res);
        });
      });
    });
  }

  setSearchText = (event) => {
    var searchText = event.target.value;

    localStorage.setItem("searchText", searchText);

    this.setState({ searchText });
    this.search(searchText);
  }

  render() {
    return (
      <input type="text" onChange={this.setSearchText} value={this.state.searchText} placeholder="Search by title or author" />
    );
  }
}

export default SearchBooksText;<|endoftext|>


<commit_before>// @flow weak

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import withStyles from '../styles/withStyles';

export const styles = (theme: Object) => ({
  root: {
    display: 'inline-block',
    fill: 'currentColor',
    height: 24,
    width: 24,
    userSelect: 'none',
    transition: theme.transitions.create('fill', {
      duration: theme.transitions.duration.shorter,
    }),
  },
});

function SvgIcon(props) {
  const { children, classes, className, titleAccess, viewBox, ...other } = props;

  return (
    <svg
      className={classNames(classes.root, className)}
      focusable={false}
      viewBox={viewBox}
      aria-hidden={titleAccess ? 'false' : 'true'}
      {...other}
    >
      {titleAccess ? <title>{titleAccess}</title> : null}
      {children}
    </svg>
  );
}

SvgIcon.propTypes = {
  /**
   * Elements passed into the SVG Icon.
   */
  children: PropTypes.node,
  /**
   * Useful to extend the style applied to components.
   */
  classes: PropTypes.object.isRequired,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * Provides a human-readable title for the element that contains it.
   * https://www.w3.org/TR/SVG-access/#Equivalent
   */
  titleAccess: PropTypes.string,
  /**
   * Allows you to redefine what the coordinates without units mean inside an svg element.
   * For example, if the SVG element is 500 (width) by 200 (height),
   * and you pass viewBox="0 0 50 20",
   * this means that the coordinates inside the svg will go from the top left corner (0,0)
   * to bottom right (50,20) and each unit will be worth 10px.
   */
  viewBox: PropTypes.string,
};

SvgIcon.defaultProps = {
  viewBox: '0 0 24 24',
};

SvgIcon.muiName = 'SvgIcon';

export default withStyles(styles, { name: 'MuiSvgIcon' })(SvgIcon);
<commit_msg>Fixes issue in react@16 where SvgIcon would log an error to the console (#8102)<commit_after>// @flow weak

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import withStyles from '../styles/withStyles';

export const styles = (theme: Object) => ({
  root: {
    display: 'inline-block',
    fill: 'currentColor',
    height: 24,
    width: 24,
    userSelect: 'none',
    transition: theme.transitions.create('fill', {
      duration: theme.transitions.duration.shorter,
    }),
  },
});

function SvgIcon(props) {
  const { children, classes, className, titleAccess, viewBox, ...other } = props;

  return (
    <svg
      className={classNames(classes.root, className)}
      focusable="false"
      viewBox={viewBox}
      aria-hidden={titleAccess ? 'false' : 'true'}
      {...other}
    >
      {titleAccess ? <title>{titleAccess}</title> : null}
      {children}
    </svg>
  );
}

SvgIcon.propTypes = {
  /**
   * Elements passed into the SVG Icon.
   */
  children: PropTypes.node,
  /**
   * Useful to extend the style applied to components.
   */
  classes: PropTypes.object.isRequired,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * Provides a human-readable title for the element that contains it.
   * https://www.w3.org/TR/SVG-access/#Equivalent
   */
  titleAccess: PropTypes.string,
  /**
   * Allows you to redefine what the coordinates without units mean inside an svg element.
   * For example, if the SVG element is 500 (width) by 200 (height),
   * and you pass viewBox="0 0 50 20",
   * this means that the coordinates inside the svg will go from the top left corner (0,0)
   * to bottom right (50,20) and each unit will be worth 10px.
   */
  viewBox: PropTypes.string,
};

SvgIcon.defaultProps = {
  viewBox: '0 0 24 24',
};

SvgIcon.muiName = 'SvgIcon';

export default withStyles(styles, { name: 'MuiSvgIcon' })(SvgIcon);
<|endoftext|>


<commit_before>function Broadcaster(){
  this.broadcasting = false;
  this.wave = $('.radio-wave');
  this.broadcastingWaves = $('.broadcast');
  this.init();
}

Broadcaster.prototype ={
  broadcast: function(animationDelay, broadcastDelay){
    var self = this;
    if (!this.broadcasting){
      console.log('broadcasting');
      self.wave.addClass('broadcast');
      this.broadcasting = true;
      setTimeout(function(){
        self.wave.addClass('show');
      }, animationDelay);
    }else{
      this.broadcasting = false;
      self.wave.removeClass('broadcast');
    }
  },
  rebroadcast: function(animationDelay, broadcastDelay){
    console.log('rebroadcasting');
    var self = this;
    this.reset();
    this.quietBtn();
    setTimeout(function(){
      self.wave.addClass('broadcast');
      setTimeout(function(){
        self.wave.addClass('show');
        self.activateBtn();
      }, animationDelay);
    }, broadcastDelay);
  },
  reset: function(){
    this.wave.removeClass('broadcast');
    this.wave.removeClass('show');
  },
  quietBtn: function(){
    console.log('off');
    $('.btn-broadcast').off('click');
  },
  activateBtn: function(){
    var self = this;
    $('.btn-broadcast').click(function(){
      self.broadcast(750,0);
    });
  },
  init: function(){
    this.activateBtn();
  }
};
function startChasing(){
  $('.radio-wave').addClass('broadcast');
  $('.robot-message').addClass('show broadcast');
  $('.left-leg').addClass('chase');
  $('.right-arm').addClass('shake');
  $('.left-arm').addClass('shake');
  setTimeout(function(){
    $('.right-leg').addClass('chase');
  }, 750);
  $('.buttons').addClass('hide');
}

function wave(){
  $('.right-arm').addClass('wave');
}

function getClass(btn){
  return btn.attr('class').split(' ')[1].split('-')[1];
}

$(function(){
  var broadcaster = new Broadcaster();

  $(window).scroll(function() {
    var topOfWindow = $(window).scrollTop();
    console.log(topOfWindow);
    $('.radio-wave').each(function(){
      var imagePos = $(this).offset().top;

      if (imagePos < topOfWindow+400 && !broadcaster.broadcasting) {
        broadcaster.broadcast(1250,0);
      }
    });
    $('.btn').each(function(){
      var imagePos = $(this).offset().top;

      if (imagePos < topOfWindow+400) {
        var styleClass = getClass($(this));
        $(this).addClass(styleClass);
      }
    });
  });
  $('.btn-wave').click(function(){
    $('.right-arm').removeClass('wave');
    setTimeout(function(){wave();}, 500);
  });
  $('.btn-chase').click(function(){startChasing();});
});
<commit_msg>removed button animations on scroll<commit_after>function Broadcaster(){
  this.broadcasting = false;
  this.wave = $('.radio-wave');
  this.broadcastingWaves = $('.broadcast');
  this.init();
}

Broadcaster.prototype ={
  broadcast: function(animationDelay, broadcastDelay){
    var self = this;
    if (!this.broadcasting){
      console.log('broadcasting');
      self.wave.addClass('broadcast');
      this.broadcasting = true;
      setTimeout(function(){
        self.wave.addClass('show');
      }, animationDelay);
    }else{
      this.broadcasting = false;
      self.wave.removeClass('broadcast');
    }
  },
  rebroadcast: function(animationDelay, broadcastDelay){
    console.log('rebroadcasting');
    var self = this;
    this.reset();
    this.quietBtn();
    setTimeout(function(){
      self.wave.addClass('broadcast');
      setTimeout(function(){
        self.wave.addClass('show');
        self.activateBtn();
      }, animationDelay);
    }, broadcastDelay);
  },
  reset: function(){
    this.wave.removeClass('broadcast');
    this.wave.removeClass('show');
  },
  quietBtn: function(){
    console.log('off');
    $('.btn-broadcast').off('click');
  },
  activateBtn: function(){
    var self = this;
    $('.btn-broadcast').click(function(){
      self.broadcast(750,0);
    });
  },
  init: function(){
    this.activateBtn();
  }
};
function startChasing(){
  $('.radio-wave').addClass('broadcast');
  $('.robot-message').addClass('show broadcast');
  $('.left-leg').addClass('chase');
  $('.right-arm').addClass('shake');
  $('.left-arm').addClass('shake');
  setTimeout(function(){
    $('.right-leg').addClass('chase');
  }, 750);
  $('.buttons').addClass('hide');
}

function wave(){
  $('.right-arm').addClass('wave');
}

$(function(){
  var broadcaster = new Broadcaster();

  $(window).scroll(function() {
    var topOfWindow = $(window).scrollTop();
    console.log(topOfWindow);
    $('.radio-wave').each(function(){
      var imagePos = $(this).offset().top;

      if (imagePos < topOfWindow+400 && !broadcaster.broadcasting) {
        broadcaster.broadcast(1250,0);
      }
    });
  });
  $('.btn-wave').click(function(){
    $('.right-arm').removeClass('wave');
    setTimeout(function(){wave();}, 500);
  });
  $('.btn-chase').click(function(){startChasing();});
});
<|endoftext|>