<commit_before>const electron = require('electron');
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;
const Menu = electron.Menu;
const ipc = electron.ipcMain;
const dialog = electron.dialog;
const clipboard = electron.clipboard;
const autoUpdater = electron.autoUpdater;
const os = require('os');
const path = require('path');
const isReachable = require('is-reachable');
const categoriesModalPath = path.join('file://', __dirname, 'modals/categories.html');
const iconModalPath = path.join('file://', __dirname, 'modals/icons.html');
const setMaxPath = path.join('file://', __dirname, 'modals/setMax.html');
const version = app.getVersion();
const platform = os.platform() + '_' + os.arch();
const winston = require('winston');
const logger = new(winston.Logger)({
    transports:[
        new (winston.transports.File)({ filename: 'main.log', json: false })
    ]
});
const debug = false;

//Squirrle Events Handeling

// this should be placed at top of main.js to handle setup events quickly
if (handleSquirrelEvent()) {
    // squirrel event handled and app will exit in 1000ms, so don't do anything else
    return;
}

function handleSquirrelEvent() {
    if (process.argv.length === 1) {
        return false;
    }

    const ChildProcess = require('child_process');

    const appFolder = path.resolve(process.execPath, '..');
    const rootAtomFolder = path.resolve(appFolder, '..');
    const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
    const exeName = path.basename(process.execPath);

    const spawn = function(command, args) {
        let spawnedProcess, error;

        try {
            spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
        } catch (error) {
        }

        return spawnedProcess;
    };

    const spawnUpdate = function(args) {
        return spawn(updateDotExe, args);
    };

    const squirrelEvent = process.argv[1];
    switch (squirrelEvent) {
        case '--squirrel-install':
        case '--squirrel-updated':
            // Optionally do things such as:
            // - Add your .exe to the PATH
            // - Write to the registry for things like file associations and
            //   explorer context menus

            // Install desktop and start menu shortcuts
            try {
                spawnUpdate(['--createShortcut', exeName]);
            }catch(e){

            }

            setTimeout(app.quit, 1000);
            return true;

        case '--squirrel-uninstall':
            // Undo anything you did in the --squirrel-install and
            // --squirrel-updated handlers

            // Remove desktop and start menu shortcuts
            try {
                spawnUpdate(['--removeShortcut', exeName]);
            }catch(e){

            }

            setTimeout(app.quit, 1000);
            return true;

        case '--squirrel-obsolete':
            // This is called on the outgoing version of your app before
            // we update to the new version - it's the opposite of
            // --squirrel-updated

            app.quit();
            return true;
    }
}

function update() {

    //Auto Update Handling

    isReachable("quest.gamestailer94.de/update/",function (e,reachable) {
        //can we connect to update server ?
        if(reachable) {
            try {
                autoUpdater.setFeedURL('https://quest.gamestailer94.de/update/' + platform + '/' + version);
                try {
                    autoUpdater.checkForUpdates();
                } catch (Exception) {
                    logger.info("Error downloading Updates");
                    logger.info("Is App not Installed?");
                    logger.info(Exception);
                    //looks like app is not installed, skip update check.
                }
            }catch(Exception){
                logger.error("Error Requesting Updates");
                logger.error(Exception);
            }
        }else{
            logger.info("No Internet, Skip Update Check");
        }
    });
}

autoUpdater.on('update-downloaded', function(){
    const options = {
        type: 'question',
        title: 'Update',
        message: "A newer Version of this Editor and JS Plugin is available, do you want to close and update?",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {

        if(index == 0) {
            autoUpdater.quitAndInstall();
        }
    });
});

autoUpdater.on('error',function(error) {
    logger.error('Error from AutoUpdater');
    logger.error('Message is Suppressed...');
    logger.error(error);
});

//Windows and other persistent stuff

let categoriesWin;
let IconWin;
let setMaxWin;
let iconId;
let icons;
let quests;
let newMax;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

let menuTemplate = [{
    label: 'File',
    submenu: [{
        label: 'Set Project Directory',
        click: showProjectDirDialog
    },{
        label: 'Reload Quests',
        click: reloadQuests
    }]
},{
    label: "Help",
    submenu: [{
        label: "Version "+version,
        enabled: false
    },{
        label: "Check for Update",
        click: update
    },{
        label: 'About',
        click: displayAbout
    }]
}
];

function createWindow () {
    update();
    const menu = Menu.buildFromTemplate(menuTemplate);
    Menu.setApplicationMenu(menu);
    // Create the browser window.
    mainWindow = new BrowserWindow({width: 800, height: 600});

    // and load the index.html of the app.
    mainWindow.loadURL(`file://${__dirname}/index.html`);

    // Open the DevTools.
    if(debug) mainWindow.webContents.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null
    })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
});

app.on('activate', function () {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null) {
        createWindow()
    }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
ipc.on('setProjectDirectory',showProjectDirDialog);

ipc.on('getCategories', function(){
    mainWindow.webContents.send('getCategories');
});

ipc.on('sendCategories', function (event, data) {
   categoriesWin.webContents.send('sendCategories', data);
});

ipc.on('openCategories', openCategoriesWindow);
ipc.on('saveCategories', function(events, data){
    mainWindow.webContents.send('saveCategories', data);
    categoriesWin.close();
});

ipc.on('openIconWindow', openIconWindow);

ipc.on('saveIcon', function(event, id, iconId){
    mainWindow.webContents.send('saveIcon', id, iconId);
    IconWin.close();
});

ipc.on('getIcons', function(){
    IconWin.webContents.send('setIconId', iconId, icons);
});

ipc.on('setMax', setMax);

ipc.on('getMax', function(){
   setMaxWin.webContents.send('setMax', quests, newMax);
});

ipc.on('updateMaxProgress', function(event, progress){
    mainWindow.webContents.send('updateMaxProgress', progress)
});

ipc.on('returnMax', function(event, newQuests){
    mainWindow.webContents.send('returnMax', newQuests);
    setMaxWin.close();
});

ipc.on('updatePluginDialog', function(event){
    const options = {
        type: 'question',
        title: 'Update JS Plugin',
        message: "Update JS Plugin",
        detail: "The Plugin Version in the Project is different then the one included in the Editor.\nUpdate it?",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {
        event.sender.send('updatePluginDialogReturn', index)
    })
});

ipc.on('installPluginDialog', function(event){
    const options = {
        type: 'question',
        title: 'Install JS Plugin',
        message: "No Plugin JS found!",
        detail: "Install the included one?\nRemember to active it.",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {
        event.sender.send('installPluginDialogReturn', index)
    })
});

ipc.on('replacePluginDialog', function(event){
    const options = {
        type: 'question',
        title: 'Replace JS Plugin',
        message: "Gameus Quest System JS Plugin Found.",
        detail: "It seems that you use the Gameus Quest System JS Plugin.\nDo you want to Replace it with the included Version of GS Quest System?\nThis WILL reset you Plugin settings, but not your Quests.\nRemember to active it.",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {
        event.sender.send('replacePluginDialogReturn', index)
    })
});

ipc.on('showError', function (event, stack) {
    logger.error("Error via ipc:");
    logger.error(stack);
    clipboard.writeText(stack);
    dialog.showErrorBox('Error', 'Please Report this Error in GitHub or at the Forums Topic.\nThis Error has been Copied to your Clipboard.\nThe Logfile is here: '+path.join(app.getAppPath(),"renderer.log")+'\n\nThe Application will now exit.\n\nTrace:\n\n'+stack);
    if(!debug){
        mainWindow.close();
        app.quit();
    }
});

ipc.on("showInfo", function(event, text){
    const options = {
        type: 'info',
        title: 'Info',
        message: text,
        buttons: ['OK'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index){});
});

function displayAbout(){
    const options = {
        type: 'info',
        title: 'About',
        message: "About this Editor and the JS Plugin",
        detail: "Version: "+app.getVersion()+"\nThis Editor has been Made by: gamestailer94\nFixes and addition Features for the JS Plugin by: gamestailer94\nProgram Icon by: BlueDragon\nData Format and original JS Plugin by: gameus",
        buttons: ['Close'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index){});
}

function showProjectDirDialog(event){
    dialog.showOpenDialog({
        properties: ['openDirectory']
    },function(dir){
        if (dir) mainWindow.webContents.send('setProjectDirectory', dir)
    });
}

function reloadQuests(){
    mainWindow.webContents.send('reloadQuests');
}

function openCategoriesWindow(){
    categoriesWin = new BrowserWindow({ width: 400, height: 320 });
    categoriesWin.on('closed', function () { categoriesWin = null });
    categoriesWin.loadURL(categoriesModalPath);
    categoriesWin.setMenuBarVisibility(false);
    categoriesWin.show();
    if (debug) categoriesWin.webContents.openDevTools();
}

function openIconWindow(event, id, Icons){
    iconId = id;
    icons = Icons;
    IconWin = new BrowserWindow({ width: 700, height: 400 });
    IconWin.on('closed', function () { IconWin = null });
    IconWin.loadURL(iconModalPath);
    IconWin.setMenuBarVisibility(false);
    IconWin.show();
    if (debug) IconWin.webContents.openDevTools();
}

function setMax(event, Quests, NewMax){
    quests = Quests;
    newMax = NewMax;
    setMaxWin = new BrowserWindow({show: false ,width: 400, height: 320});
    setMaxWin.on('closed', function () { setMaxWin = null });
    setMaxWin.loadURL(setMaxPath);
}
<commit_msg>added check for running update<commit_after>const electron = require('electron');
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;
const Menu = electron.Menu;
const ipc = electron.ipcMain;
const dialog = electron.dialog;
const clipboard = electron.clipboard;
const autoUpdater = electron.autoUpdater;
const os = require('os');
const path = require('path');
const isReachable = require('is-reachable');
const categoriesModalPath = path.join('file://', __dirname, 'modals/categories.html');
const iconModalPath = path.join('file://', __dirname, 'modals/icons.html');
const setMaxPath = path.join('file://', __dirname, 'modals/setMax.html');
const version = app.getVersion();
const platform = os.platform() + '_' + os.arch();
const winston = require('winston');
const logger = new(winston.Logger)({
    transports:[
        new (winston.transports.File)({ filename: 'main.log', json: false })
    ]
});
var checking = false;
const debug = false;

//Squirrle Events Handeling

// this should be placed at top of main.js to handle setup events quickly
if (handleSquirrelEvent()) {
    // squirrel event handled and app will exit in 1000ms, so don't do anything else
    return;
}

function handleSquirrelEvent() {
    if (process.argv.length === 1) {
        return false;
    }

    const ChildProcess = require('child_process');

    const appFolder = path.resolve(process.execPath, '..');
    const rootAtomFolder = path.resolve(appFolder, '..');
    const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
    const exeName = path.basename(process.execPath);

    const spawn = function(command, args) {
        let spawnedProcess, error;

        try {
            spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
        } catch (error) {
        }

        return spawnedProcess;
    };

    const spawnUpdate = function(args) {
        return spawn(updateDotExe, args);
    };

    const squirrelEvent = process.argv[1];
    switch (squirrelEvent) {
        case '--squirrel-install':
        case '--squirrel-updated':
            // Optionally do things such as:
            // - Add your .exe to the PATH
            // - Write to the registry for things like file associations and
            //   explorer context menus

            // Install desktop and start menu shortcuts
            try {
                spawnUpdate(['--createShortcut', exeName]);
            }catch(e){

            }

            setTimeout(app.quit, 1000);
            return true;

        case '--squirrel-uninstall':
            // Undo anything you did in the --squirrel-install and
            // --squirrel-updated handlers

            // Remove desktop and start menu shortcuts
            try {
                spawnUpdate(['--removeShortcut', exeName]);
            }catch(e){

            }

            setTimeout(app.quit, 1000);
            return true;

        case '--squirrel-obsolete':
            // This is called on the outgoing version of your app before
            // we update to the new version - it's the opposite of
            // --squirrel-updated

            app.quit();
            return true;
    }
}

function update() {

    //Auto Update Handling

    isReachable("quest.gamestailer94.de/update/",function (e,reachable) {
        //can we connect to update server ?
        if(reachable && !checking) {
            try {
                autoUpdater.setFeedURL('https://quest.gamestailer94.de/update/' + platform + '/' + version);
                try {
                    autoUpdater.checkForUpdates();
                } catch (Exception) {
                    logger.info("Error downloading Updates");
                    logger.info("Is App not Installed?");
                    logger.info(Exception);
                    //looks like app is not installed, skip update check.
                }
            }catch(Exception){
                logger.error("Error Requesting Updates");
                logger.error(Exception);
            }
        }else{
            logger.info("No Internet, Skip Update Check");
        }
    });
}

autoUpdater.on('update-downloaded', function(){
    checking = false;
    const options = {
        type: 'question',
        title: 'Update',
        message: "A newer Version of this Editor and JS Plugin is available, do you want to close and update?",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {

        if(index == 0) {
            autoUpdater.quitAndInstall();
        }
    });
});

autoUpdater.on('checking-for-update',function(){
    checking = true;
});

autoUpdater.on('update-not-available',function(){
    checking = false;
});

autoUpdater.on('error',function(error) {
    logger.error('Error from AutoUpdater');
    logger.error('Message is Suppressed...');
    logger.error(error);
});

//Windows and other persistent stuff

let categoriesWin;
let IconWin;
let setMaxWin;
let iconId;
let icons;
let quests;
let newMax;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

let menuTemplate = [{
    label: 'File',
    submenu: [{
        label: 'Set Project Directory',
        click: showProjectDirDialog
    },{
        label: 'Reload Quests',
        click: reloadQuests
    }]
},{
    label: "Help",
    role: 'help',
    submenu: [{
        label: "Version "+version,
        enabled: false
    },{
        label: "Check for Update",
        click: update
    },{
        label: 'About',
        click: displayAbout
    }]
}
];

function createWindow () {
    update();
    const menu = Menu.buildFromTemplate(menuTemplate);
    Menu.setApplicationMenu(menu);
    // Create the browser window.
    mainWindow = new BrowserWindow({width: 800, height: 600});

    // and load the index.html of the app.
    mainWindow.loadURL(`file://${__dirname}/index.html`);

    // Open the DevTools.
    if(debug) mainWindow.webContents.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null
    })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
});

app.on('activate', function () {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null) {
        createWindow()
    }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
ipc.on('setProjectDirectory',showProjectDirDialog);

ipc.on('getCategories', function(){
    mainWindow.webContents.send('getCategories');
});

ipc.on('sendCategories', function (event, data) {
   categoriesWin.webContents.send('sendCategories', data);
});

ipc.on('openCategories', openCategoriesWindow);
ipc.on('saveCategories', function(events, data){
    mainWindow.webContents.send('saveCategories', data);
    categoriesWin.close();
});

ipc.on('openIconWindow', openIconWindow);

ipc.on('saveIcon', function(event, id, iconId){
    mainWindow.webContents.send('saveIcon', id, iconId);
    IconWin.close();
});

ipc.on('getIcons', function(){
    IconWin.webContents.send('setIconId', iconId, icons);
});

ipc.on('setMax', setMax);

ipc.on('getMax', function(){
   setMaxWin.webContents.send('setMax', quests, newMax);
});

ipc.on('updateMaxProgress', function(event, progress){
    mainWindow.webContents.send('updateMaxProgress', progress)
});

ipc.on('returnMax', function(event, newQuests){
    mainWindow.webContents.send('returnMax', newQuests);
    setMaxWin.close();
});

ipc.on('updatePluginDialog', function(event){
    const options = {
        type: 'question',
        title: 'Update JS Plugin',
        message: "Update JS Plugin",
        detail: "The Plugin Version in the Project is different then the one included in the Editor.\nUpdate it?",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {
        event.sender.send('updatePluginDialogReturn', index)
    })
});

ipc.on('installPluginDialog', function(event){
    const options = {
        type: 'question',
        title: 'Install JS Plugin',
        message: "No Plugin JS found!",
        detail: "Install the included one?\nRemember to active it.",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {
        event.sender.send('installPluginDialogReturn', index)
    })
});

ipc.on('replacePluginDialog', function(event){
    const options = {
        type: 'question',
        title: 'Replace JS Plugin',
        message: "Gameus Quest System JS Plugin Found.",
        detail: "It seems that you use the Gameus Quest System JS Plugin.\nDo you want to Replace it with the included Version of GS Quest System?\nThis WILL reset you Plugin settings, but not your Quests.\nRemember to active it.",
        buttons: ['Yes', 'No'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index) {
        event.sender.send('replacePluginDialogReturn', index)
    })
});

ipc.on('showError', function (event, stack) {
    logger.error("Error via ipc:");
    logger.error(stack);
    clipboard.writeText(stack);
    dialog.showErrorBox('Error', 'Please Report this Error in GitHub or at the Forums Topic.\nThis Error has been Copied to your Clipboard.\nThe Logfile is here: '+path.join(app.getAppPath(),"renderer.log")+'\n\nThe Application will now exit.\n\nTrace:\n\n'+stack);
    if(!debug){
        mainWindow.close();
        app.quit();
    }
});

ipc.on("showInfo", function(event, text){
    const options = {
        type: 'info',
        title: 'Info',
        message: text,
        buttons: ['OK'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index){});
});

function displayAbout(){
    const options = {
        type: 'info',
        title: 'About',
        message: "About this Editor and the JS Plugin",
        detail: "Version: "+app.getVersion()+"\nThis Editor has been Made by: gamestailer94\nFixes and addition Features for the JS Plugin by: gamestailer94\nProgram Icon by: BlueDragon\nData Format and original JS Plugin by: gameus",
        buttons: ['Close'],
        defaultId: 0
    };
    dialog.showMessageBox(options, function (index){});
}

function showProjectDirDialog(event){
    dialog.showOpenDialog({
        properties: ['openDirectory']
    },function(dir){
        if (dir) mainWindow.webContents.send('setProjectDirectory', dir)
    });
}

function reloadQuests(){
    mainWindow.webContents.send('reloadQuests');
}

function openCategoriesWindow(){
    categoriesWin = new BrowserWindow({ width: 400, height: 320 });
    categoriesWin.on('closed', function () { categoriesWin = null });
    categoriesWin.loadURL(categoriesModalPath);
    categoriesWin.setMenuBarVisibility(false);
    categoriesWin.show();
    if (debug) categoriesWin.webContents.openDevTools();
}

function openIconWindow(event, id, Icons){
    iconId = id;
    icons = Icons;
    IconWin = new BrowserWindow({ width: 700, height: 400 });
    IconWin.on('closed', function () { IconWin = null });
    IconWin.loadURL(iconModalPath);
    IconWin.setMenuBarVisibility(false);
    IconWin.show();
    if (debug) IconWin.webContents.openDevTools();
}

function setMax(event, Quests, NewMax){
    quests = Quests;
    newMax = NewMax;
    setMaxWin = new BrowserWindow({show: false ,width: 400, height: 320});
    setMaxWin.on('closed', function () { setMaxWin = null });
    setMaxWin.loadURL(setMaxPath);
}
<|endoftext|>


<commit_before>var Game = require("./Game.js").Game,
    winston = require("winston"),
    counter = 0;

var ConnectionHost = function(io){

    var self = this;

    var players = {}; //the current players

    io.on("connection", function(socket){

        //Make a socket.
        var socket = socket;

        //Create a new socket
        socket.emit("log", "Connection established! ");

        socket.once("lobby_begin", function(name){
            //we have a name.
            var name = name;

            if(!name){
                name = " Player #"+(counter++);
            }

            socket.on("lobby_list", function(){
                var lobbies = [];

                for(var lobby in players){
                    if(players.hasOwnProperty(lobby)){
                        lobbies.push([lobby, players[lobby].game_type]);
                    }
                }

                socket.emit("lobby_list", lobbies);
            })

            socket.on("lobby_new", function(game_type){
                //we want to create a new one, so no longer accept connections.
                players[name] = {"conn": socket, "name": name, "game_type": game_type};

                //delete on disconect.
                socket.on("disconnect", function(){
                    winston.info("Disconnected", name);
                    delete players[name];
                });
            });

            socket.on("lobby_request_join", function(lby){
                if(!players.hasOwnProperty(lby)){
                    //lobby does not exist => do the joining now
                    socket.emit("lobby_request_join", false);
                    winston.info(name, " can not join", lby, "Does not exist. ");
                } else {
                    //Lobby exists => ask the other person
                    var other = players[lby];

                    other.conn.once("lobby_answer_request", function(response){
                        //we have our answer
                        if(!response){
                            //we do not want to join
                            socket.emit("lobby_request_join", false);
                            winston.info(name, " can not join", lby, "Denied. ")
                        } else {
                            //we want to join
                            socket.emit("lobby_request_join", true);
                            winston.info(name, " joined", lby);

                            //get the game type
                            var game_type = other["game_type"];
                            delete other["game_type"];

                            //the other player is gone now.
                            delete players[lby];

                            //and start a game
                            self.startGame(other, {"conn": socket, "name": name}, game_type);
                        }
                    });

                    other.conn.emit("lobby_answer_request", name);

                }
            });
        });

    });
}

ConnectionHost.prototype.startGame = function(player1, player2, game_type){
    //Log on the client side
    player1.conn.emit("log", "You are player1! ");
    player2.conn.emit("log", "You are player2! ");

    player1.conn.on("disconnect", function(){
        Match.end();
    });

    player2.conn.on("disconnect", function(){
        Match.end();
    });

    //Create a new match
    var Match = new Game(player1, player2, game_type);

    //Start the game after the intial delay
    setTimeout(function(){
        Match.start();
    }, Match.start_delay);
}

module.exports.ConnectionHost = ConnectionHost;
<commit_msg>Yes @kpj, I fixed it.<commit_after>var Game = require("./Game.js").Game,
    winston = require("winston"),
    counter = 0;

var ConnectionHost = function(io){

    var self = this;

    var players = {}; //the current players

    io.on("connection", function(socket){

        //Make a socket.
        var socket = socket;

        //Create a new socket
        socket.emit("log", "Connection established! ");

        socket.once("lobby_begin", function(name){
            //we have a name.
            var name = name;

            if(!name){
                name = "Player #"+(counter++);
            }

            socket.on("lobby_list", function(){
                var lobbies = [];

                for(var lobby in players){
                    if(players.hasOwnProperty(lobby)){
                        lobbies.push([lobby, players[lobby].game_type]);
                    }
                }

                socket.emit("lobby_list", lobbies);
            })

            socket.on("lobby_new", function(game_type){
                //we want to create a new one, so no longer accept connections.
                players[name] = {"conn": socket, "name": name, "game_type": game_type};

                //delete on disconect.
                socket.on("disconnect", function(){
                    winston.info("Disconnected", name);
                    delete players[name];
                });
            });

            socket.on("lobby_request_join", function(lby){
                if(!players.hasOwnProperty(lby)){
                    //lobby does not exist => do the joining now
                    socket.emit("lobby_request_join", false);
                    winston.info(name, " can not join", lby, "Does not exist. ");
                } else {
                    //Lobby exists => ask the other person
                    var other = players[lby];

                    other.conn.once("lobby_answer_request", function(response){
                        //we have our answer
                        if(!response){
                            //we do not want to join
                            socket.emit("lobby_request_join", false);
                            winston.info(name, " can not join", lby, "Denied. ")
                        } else {
                            //we want to join
                            socket.emit("lobby_request_join", true);
                            winston.info(name, " joined", lby);

                            //get the game type
                            var game_type = other["game_type"];
                            delete other["game_type"];

                            //the other player is gone now.
                            delete players[lby];

                            //and start a game
                            self.startGame(other, {"conn": socket, "name": name}, game_type);
                        }
                    });

                    other.conn.emit("lobby_answer_request", name);

                }
            });
        });

    });
}

ConnectionHost.prototype.startGame = function(player1, player2, game_type){
    //Log on the client side
    player1.conn.emit("log", "You are player1! ");
    player2.conn.emit("log", "You are player2! ");

    player1.conn.on("disconnect", function(){
        Match.end();
    });

    player2.conn.on("disconnect", function(){
        Match.end();
    });

    //Create a new match
    var Match = new Game(player1, player2, game_type);

    //Start the game after the intial delay
    setTimeout(function(){
        Match.start();
    }, Match.start_delay);
}

module.exports.ConnectionHost = ConnectionHost;
<|endoftext|>


<commit_before>requirejs.config({
    baseUrl: 'app/',
    paths: {
        jquery: '../vendors/jquery.min',
        jqueryui: '../vendors/jquery-ui.min',
        jqpagination: '../vendors/jquery.jqpagination.min',
        underscore: '../vendors/underscore.min',
        backbone: '../vendors/backbone.min',
        classify: '../vendors/classify.min',
        dateformat: '../vendors/date.format',
        jqflot: '../vendors/jquery.flot',
        jqflotaddon: '../vendors/jquery.flot.axislabels',
        jqflotpie: '../vendors/jquery.flot.pie'
    },
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            exports: 'backbone'
        },
        waitSeconds: 15
    }
});
require(['underscore', 'jquery', 'jqueryui'], function () {
    require(['backbone', 'classify', 'dateformat', 'jqflot', 'jqpagination', 'CATS'], function () {
        require([
            'adapters/cats',
            'adapters/cats_xml_hist',
            'adapters/cats_rank_table',
            'adapters/ifmo',
            'adapters/codeforces',
            'adapters/myicpc',
            'adapters/aizu',
            'adapters/domjudge',
            'adapters/default',
            'controller',
            'jqflotaddon',
            'jqflotpie'
        ], function () {
            require(['models/entity'], function () {
                require(['models/event'], function () {
                    require([
                        'tests/cats_xml_data',
                        'tests/ifmo_html_data',
                        'tests/cats_rank_table_json_data',
                        'models/version',
                        'models/chat',
                        'models/compiler',
                        'models/contest',
                        'models/prize',
                        'models/problem',
                        'models/run',
                        'models/results_table',
                        'models/chart',
                        'models/user',
                        'rules/base',
                        'rules/acm',
                        'rules/school',
                        'adapters/ifmo_xml',
                        'view',
                        'utils',
                        'extentions',
                        'templates/langs',
                    ], function () {
                        require([//we cant use skins_names array because optimization module works only with hardcoded array constant. Proof http://requirejs.org/docs/optimization.html
                            'text!templates/header_rank_table.html',
                            'text!templates/header_contests_list.html',
                            'text!templates/pagination.html',
                            'text!templates/footer.html',
                            //pages
                            'text!templates/pages/charts.html',
                            //filters
                            'text!templates/pages/filters/table.html',
                            'text!templates/pages/filters/contests.html',
                            //skins
                            //default
                            'text!templates/pages/skins/default/table_acm.html',
                            'text!templates/pages/skins/default/table_school.html',
                            'text!templates/pages/skins/default/history.html',
                            'text!templates/pages/skins/default/contests.html',
                            //ifmo
                            'text!templates/pages/skins/ifmo/table_acm.html',
                            'text!templates/pages/skins/ifmo/table_school.html',
                            'text!templates/pages/skins/ifmo/history.html',
                            'text!templates/pages/skins/ifmo/contests.html',
                            //CF
                            'text!templates/pages/skins/codeforces/table_acm.html',
                            'text!templates/pages/skins/codeforces/table_school.html',
                            'text!templates/pages/skins/codeforces/history.html',
                            'text!templates/pages/skins/codeforces/contests.html',
                            //CATS
                            'text!templates/pages/skins/cats/table_acm.html',
                            'text!templates/pages/skins/cats/table_school.html',
                            'text!templates/pages/skins/cats/history.html',
                            'text!templates/pages/skins/cats/contests.html',
                            //OPENCUP
                            'text!templates/pages/skins/opencup/table_acm.html',
                            'text!templates/pages/skins/opencup/table_school.html',
                            'text!templates/pages/skins/opencup/history.html',
                            'text!templates/pages/skins/opencup/contests.html',
                            //MyICPC
                            'text!templates/pages/skins/myicpc/table_acm.html',
                            'text!templates/pages/skins/myicpc/table_school.html',
                            'text!templates/pages/skins/myicpc/history.html',
                            'text!templates/pages/skins/myicpc/contests.html',
                            //DOMJudge
                            'text!templates/pages/skins/domjudge/table_acm.html',
                            'text!templates/pages/skins/domjudge/table_school.html',
                            'text!templates/pages/skins/domjudge/history.html',
                            'text!templates/pages/skins/domjudge/contests.html',
                            //Kattis
                            'text!templates/pages/skins/kattis/table_acm.html',
                            'text!templates/pages/skins/kattis/table_school.html',
                            'text!templates/pages/skins/kattis/history.html',
                            'text!templates/pages/skins/kattis/contests.html',
                            //URI Online Judge
                            'text!templates/pages/skins/uri/table_acm.html',
                            //AIZU Online Judge
                            'text!templates/pages/skins/aizu/table_acm.html'
                            //after add new skin make sure add new item in index.js
                        ], cats_score_init);
                    });
                });
            });
        });
    });
});

<commit_msg>fix bug with rules base loading order<commit_after>requirejs.config({
    baseUrl: 'app/',
    paths: {
        jquery: '../vendors/jquery.min',
        jqueryui: '../vendors/jquery-ui.min',
        jqpagination: '../vendors/jquery.jqpagination.min',
        underscore: '../vendors/underscore.min',
        backbone: '../vendors/backbone.min',
        classify: '../vendors/classify.min',
        dateformat: '../vendors/date.format',
        jqflot: '../vendors/jquery.flot',
        jqflotaddon: '../vendors/jquery.flot.axislabels',
        jqflotpie: '../vendors/jquery.flot.pie'
    },
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            exports: 'backbone'
        },
        waitSeconds: 15
    }
});
require(['underscore', 'jquery', 'jqueryui'], function () {
    require(['backbone', 'classify', 'dateformat', 'jqflot', 'jqpagination', 'CATS'], function () {
        require([
            'adapters/cats',
            'adapters/cats_xml_hist',
            'adapters/cats_rank_table',
            'adapters/ifmo',
            'adapters/codeforces',
            'adapters/myicpc',
            'adapters/aizu',
            'adapters/domjudge',
            'adapters/default',
            'rules/base',
            'controller',
            'jqflotaddon',
            'jqflotpie'
        ], function () {
            require(['models/entity'], function () {
                require(['models/event'], function () {
                    require([
                        'tests/cats_xml_data',
                        'tests/ifmo_html_data',
                        'tests/cats_rank_table_json_data',
                        'models/version',
                        'models/chat',
                        'models/compiler',
                        'models/contest',
                        'models/prize',
                        'models/problem',
                        'models/run',
                        'models/results_table',
                        'models/chart',
                        'models/user',
                        'rules/acm',
                        'rules/school',
                        'adapters/ifmo_xml',
                        'view',
                        'utils',
                        'extentions',
                        'templates/langs',
                    ], function () {
                        require([//we cant use skins_names array because optimization module works only with hardcoded array constant. Proof http://requirejs.org/docs/optimization.html
                            'text!templates/header_rank_table.html',
                            'text!templates/header_contests_list.html',
                            'text!templates/pagination.html',
                            'text!templates/footer.html',
                            //pages
                            'text!templates/pages/charts.html',
                            //filters
                            'text!templates/pages/filters/table.html',
                            'text!templates/pages/filters/contests.html',
                            //skins
                            //default
                            'text!templates/pages/skins/default/table_acm.html',
                            'text!templates/pages/skins/default/table_school.html',
                            'text!templates/pages/skins/default/history.html',
                            'text!templates/pages/skins/default/contests.html',
                            //ifmo
                            'text!templates/pages/skins/ifmo/table_acm.html',
                            'text!templates/pages/skins/ifmo/table_school.html',
                            'text!templates/pages/skins/ifmo/history.html',
                            'text!templates/pages/skins/ifmo/contests.html',
                            //CF
                            'text!templates/pages/skins/codeforces/table_acm.html',
                            'text!templates/pages/skins/codeforces/table_school.html',
                            'text!templates/pages/skins/codeforces/history.html',
                            'text!templates/pages/skins/codeforces/contests.html',
                            //CATS
                            'text!templates/pages/skins/cats/table_acm.html',
                            'text!templates/pages/skins/cats/table_school.html',
                            'text!templates/pages/skins/cats/history.html',
                            'text!templates/pages/skins/cats/contests.html',
                            //OPENCUP
                            'text!templates/pages/skins/opencup/table_acm.html',
                            'text!templates/pages/skins/opencup/table_school.html',
                            'text!templates/pages/skins/opencup/history.html',
                            'text!templates/pages/skins/opencup/contests.html',
                            //MyICPC
                            'text!templates/pages/skins/myicpc/table_acm.html',
                            'text!templates/pages/skins/myicpc/table_school.html',
                            'text!templates/pages/skins/myicpc/history.html',
                            'text!templates/pages/skins/myicpc/contests.html',
                            //DOMJudge
                            'text!templates/pages/skins/domjudge/table_acm.html',
                            'text!templates/pages/skins/domjudge/table_school.html',
                            'text!templates/pages/skins/domjudge/history.html',
                            'text!templates/pages/skins/domjudge/contests.html',
                            //Kattis
                            'text!templates/pages/skins/kattis/table_acm.html',
                            'text!templates/pages/skins/kattis/table_school.html',
                            'text!templates/pages/skins/kattis/history.html',
                            'text!templates/pages/skins/kattis/contests.html',
                            //URI Online Judge
                            'text!templates/pages/skins/uri/table_acm.html',
                            //AIZU Online Judge
                            'text!templates/pages/skins/aizu/table_acm.html'
                            //after add new skin make sure add new item in index.js
                        ], cats_score_init);
                    });
                });
            });
        });
    });
});

<|endoftext|>


<commit_before>'use strict';

// A global object makes it easy to reach windows and functions
// from BrowserWindows via Electron remote
global.main = {}

// Version
main.MAJOR = 2
main.MINOR = 1
main.PATCH = 0
main.BUILD = 'beta2'

// This one is burned in by scripts
main.TIMESTAMP = 'Wed May 25 11:28:08 CEST 2016'

// Don't edit below
main.VERSION = main.MAJOR + '.' + main.MINOR
main.FULLVERSION = main.VERSION + '.' + main.PATCH + '-' + main.BUILD
main.BASE = 'https://evothings.com/' + main.VERSION
main.DOC = main.BASE + "/doc"
main.EXAMPLES = main.BASE + "/examples"
main.LIBRARIES = main.BASE + "/libraries"

const electron = require('electron')
const app = electron.app
const DIALOG = require('electron').dialog;

// First we need to handle Squirrel installer events and exit fast.
if (handleSquirrelEvent()) {
  // squirrel event handled and app will exit in 1000ms, so don't do anything else
  return;
}

function handleSquirrelEvent() {
  if (process.argv.length === 1) {
    return false;
  }

  const ChildProcess = require('child_process');
  const path = require('path');

  const appFolder = path.resolve(process.execPath, '..');
  const rootAtomFolder = path.resolve(appFolder, '..');
  const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
  const exeName = path.basename(process.execPath);

  const spawn = function(command, args) {
    let spawnedProcess, error;

    try {
      spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
    } catch (error) {}

    return spawnedProcess;
  };

  const spawnUpdate = function(args) {
    return spawn(updateDotExe, args);
  };

  const squirrelEvent = process.argv[1];
  switch (squirrelEvent) {
    case '--squirrel-install':
    case '--squirrel-updated':
      // Optionally do things such as:
      // - Add your .exe to the PATH
      // - Write to the registry for things like file associations and
      //   explorer context menus

      // Install desktop and start menu shortcuts
      spawnUpdate(['--createShortcut', exeName]);

      setTimeout(app.quit, 1000);
      return true;

    case '--squirrel-uninstall':
      // Undo anything you did in the --squirrel-install and
      // --squirrel-updated handlers

      // Remove desktop and start menu shortcuts
      spawnUpdate(['--removeShortcut', exeName]);

      setTimeout(app.quit, 1000);
      return true;

    case '--squirrel-obsolete':
      // This is called on the outgoing version of your app before
      // we update to the new version - it's the opposite of
      // --squirrel-updated

      app.quit();
      return true;
  }
};

// Some more things we want
const Menu = electron.Menu
const MenuItem = electron.MenuItem
const Shell = electron.shell
const dialog = electron.dialog
const ipcMain = electron.ipcMain
const BrowserWindow = electron.BrowserWindow

// Keeping track of Windows (windowID) listening to each channel
main.listeners = new Map()

main.addMenu = function() {
  var template = [
    {
      label: 'File',
      submenu: [
        {
          label: 'New App...',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'newApp'}) }
        },
        {
          label: 'Getting Started',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'gettingStarted'}) }
        },
        {
          label: 'Share in Social Media',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'shareInSocialMedia'}) }
        }
      ]
    },
    {
      label: 'Edit',
      submenu: [
        {
          label: 'Undo',
          accelerator: 'CmdOrCtrl+Z',
          role: 'undo'
        },
        {
          label: 'Redo',
          accelerator: 'Shift+CmdOrCtrl+Z',
          role: 'redo'
        },
        {
          type: 'separator'
        },
        {
          label: 'Cut',
          accelerator: 'CmdOrCtrl+X',
          role: 'cut'
        },
        {
          label: 'Copy',
          accelerator: 'CmdOrCtrl+C',
          role: 'copy'
        },
        {
          label: 'Paste',
          accelerator: 'CmdOrCtrl+V',
          role: 'paste'
        },
        {
          label: 'Select All',
          accelerator: 'CmdOrCtrl+A',
          role: 'selectall'
        },
        {
          type: 'separator'
        },
        {
          label: 'Settings',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'openSettingsDialog'}) }
        }
      ]
    },
    {
      label: 'Viewers',
      submenu: [
        {
          label: 'Disconnect all Viewers',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'disconnectAllViewers'}) }
        }
      ]
    },
    {
      label: 'Tools',
      role: 'tools',
      submenu: [
        {
          label: 'JavaScript Console',
          accelerator: 'CmdOrCtrl+J',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'openConsoleWindow'}) }
        },
        {
          label: 'Viewers Explorer',
          accelerator: 'CmdOrCtrl+E',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'openViewersWindow'}) }
        },
      ]
    },
    {
      label: 'Window',
      role: 'window',
      submenu: [
        {
          label: 'Minimize',
          accelerator: 'CmdOrCtrl+M',
          role: 'minimize'
        },
        {
          label: 'Close',
          accelerator: 'CmdOrCtrl+W',
          role: 'close'
        },
        {
          label: 'Toggle Full Screen',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Ctrl+Command+F';
            else
              return 'F11';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
          }
        }
      ]
    },
    {
      label: 'Documentation',
      role: 'documentation',
      submenu: [
        {
          label: 'Index',
          click: function() { Shell.openExternal(main.DOC) }
        },
        {
          label: 'Examples',
          click: function() { Shell.openExternal(main.DOC + '/examples/examples.html') }
        },
        {
          label: 'ECMAScript 6',
          click: function() { Shell.openExternal(main.DOC + '/tutorials/ecmascript6.html') }
        },
        {
          label: 'Release Notes',
          click: function() { Shell.openExternal(main.DOC + '/studio/release-notes.html') }
        }
      ]
    },
    {
      label: 'Help',
      role: 'help',
      submenu: [
        {
          label: 'Chat on Gitter',
          click: function() { Shell.openExternal('https://gitter.im/evothings/evothings') }
        },
        {
          label: 'Support',
          submenu: [
            {
              label: 'Discussions',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/discussions') }
            },
            {
              label: 'Private Feedback',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/discussions/topics/new?forum_id=14000130317') }
            },
            {
              label: 'Feature Request',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/discussions/topics/new?forum_id=14000128400') }
            },
            {
              type: 'separator'
            },
            {
              label: 'Knowledge Base',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/solutions') }
            },
            {
              label: 'Frequently Asked Questions',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/solution/folders/14000103190') }
            },
            {
              label: 'New Support Ticket',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/tickets/new') }
            },
            {
              label: 'My Tickets',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/tickets') }
            },
          ]
        },
        {
          label: 'Old forum',
          click: function() { Shell.openExternal('https://evothings.com/forum/') }
        },
        {
          type: 'separator'
        },
        {
          label: 'Toggle Developer Tools',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Alt+Command+I';
            else
              return 'Ctrl+Shift+I';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.toggleDevTools();
          }
        },
        {
          type: 'separator'
        },
        {
          label: 'About Evothings Studio',
          click: function() { dialog.showMessageBox({
            type: "info",
            title: "Evothings Studio " + main.FULLVERSION,
            buttons: ["Close"],
            message: "Evothings Studio " + main.FULLVERSION,
            detail: "Evothings Studio is a development environment tailored for making hybrid mobile apps in the IoT domain.\n" +
              "\nBuilt: " + main.TIMESTAMP +
              "\nElectron: " + process.versions['electron'] +
              "\nChrome: " + process.versions['chrome'] +
              "\nNode: " + process.versions['node'] +
              "\nLicense: Apache License version 2.0" +
              "\n\nCopyright (c) 2016 Evothings AB"}) }
        }
      ]
    },
  ];

  if (process.platform == 'darwin') {
    template.unshift({
      label: 'Evothings Studio',
      submenu: [
        /*{
          label: 'About ' + name,
          role: 'about'
        },
        {
          type: 'separator'
        },*/
        {
          label: 'Services',
          role: 'services',
          submenu: []
        },
        {
          type: 'separator'
        },
        {
          label: 'Hide Evothings Studio',
          accelerator: 'Command+H',
          role: 'hide'
        },
        {
          label: 'Hide Others',
          accelerator: 'Command+Alt+H',
          role: 'hideothers'
        },
        {
          label: 'Show All',
          role: 'unhide'
        },
        {
          type: 'separator'
        },
        {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: function() { app.quit(); }
        }
      ]
    })
    // Window menu.
    template[5].submenu.push(
      {
        type: 'separator'
      },
      {
        label: 'Bring All to Front',
        role: 'front'
      }
    );
  } else {
    // Quit for Linux/Windows
    template[0].submenu.push(
      {
        label: 'Quit',
        accelerator: 'CmdOrCtrl+Q',
        click: function() { app.quit(); }
      }
    )
  }

  var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
}

//
//  TODO: Create a generic way to hold app state
//
main.setCurrentViewers = function(data)
{
  main.currentViewers = data
}

main.getCurrentViewers = function()
{
  return main.currentViewers
}
//
//
//

main.getRootDir = function() {
  return __dirname
}

main.createWorkbenchWindow = function() {
  main.workbenchWindow = new BrowserWindow({
    title: 'Evothings Studio ' + main.FULLVERSION + ' - Workbench',
    icon: 'hyper/ui/images/app-icon.png',
    width: 850, height: 720, webSecurity: false, show: false
  });

  main.workbenchWindow.on('closed', function() {
    main.workbenchWindow = null;
  });

  main.workbenchWindow.loadURL('file://' + __dirname + '/hyper/ui/index.html');
  main.addMenu();
  main.workbenchWindow.center()
}
main.showWorkbenchWindow = function() {
    main.workbenchWindow.show()
}

main.openConsoleWindow = function() {
  if (main.consoleWindow) {
    main.consoleWindow.show()
  } else {
    main.consoleWindow = new BrowserWindow({
      title: 'Javascript Console',
      width: 800,
      height: 600,
      show: false
    })

    main.consoleWindow.on('closed', function() {
      main.consoleWindow = null;
    });

    main.consoleWindow.loadURL('file://' + __dirname + '/hyper/ui/tools-window.html')
    main.consoleWindow.center()
  }
}
main.showConsoleWindow = function() {
  main.consoleWindow.show()
}

main.openViewersWindow = function() {
  if (main.viewersWindow) {
    main.viewersWindow.show()
  } else {
    main.viewersWindow = new BrowserWindow({
      title: 'Viewers Explorer',
      width: 800,
      height: 600,
      show: false
    })

    main.viewersWindow.on('closed', function() {
      main.viewersWindow = null;
    });

    main.viewersWindow.loadURL('file://' + __dirname + '/hyper/ui/hyper-viewers.html')
    main.viewersWindow.center()

  }
}
main.showViewersWindow = function() {
  main.viewersWindow.show()
}

main.selectOrCreateFolder = function(title, defaultDir) {
  return DIALOG.showOpenDialog({ title: title,
        defaultPath: defaultDir, properties: [ 'openDirectory', 'createDirectory']})
}

// Work as relay between our BrowserWindows since they can not talk to
// each other directly. We simply have one relay handler per window.
ipcMain.on('workbench-window', function(event, arg) {
  if (main.workbenchWindow) {
    main.workbenchWindow.webContents.send('msg', arg);
  }
});
ipcMain.on('console-window', function(event, arg) {
  if (main.consoleWindow) {
    main.consoleWindow.webContents.send('msg', arg);
  }
});
ipcMain.on('viewers-window', function(event, arg) {
  if (main.viewersWindow) {
    main.viewersWindow.webContents.send('msg', arg);
  }
});

// This is yet another means of communicating between BrowserWindows
// but using a publish subscribe model, this was the previous EVENTS module
ipcMain.on('events-subscribe', function(event, channel, windowID) {
  var listeners = main.listeners[channel] || new Set()
  //console.log("Subscribed window " + windowID + " to " + channel)
  listeners.add(windowID)
  main.listeners[channel] = listeners
});
ipcMain.on('events-unsubscribe', function(event, channel, windowID) {
  var listeners = main.listeners[channel]
  if (listeners) {
    listeners.delete(windowID)
    console.log("Unsubscribed window " + windowID + " from " + channel)
  }
});
// Forward the event to all registered windows for this channel
ipcMain.on('events-publish', function(event, channel, obj) {
  var listeners = main.listeners[channel]
  //console.log("Published "+ JSON.stringify(obj) + " to " + JSON.stringify(channel))
  if (listeners) {
    for (let windowID of listeners) {
      var window = BrowserWindow.fromId(windowID)
      if (window) {
        //console.log("Sending " + JSON.stringify(obj) + " to " + channel + " in window " + windowID)
        window.webContents.send('events-event', channel, obj);
      }
    }
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', main.createWorkbenchWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (main.workbenchWindow === null) {
    main.createWorkbenchWindow();
  }
});
<commit_msg>Fixed timestamp marker<commit_after>'use strict';

// A global object makes it easy to reach windows and functions
// from BrowserWindows via Electron remote
global.main = {}

// Version
main.MAJOR = 2
main.MINOR = 1
main.PATCH = 0
main.BUILD = 'beta2'

// This one is burned in by scripts
main.TIMESTAMP = '<timestamp>'

// Don't edit below
main.VERSION = main.MAJOR + '.' + main.MINOR
main.FULLVERSION = main.VERSION + '.' + main.PATCH + '-' + main.BUILD
main.BASE = 'https://evothings.com/' + main.VERSION
main.DOC = main.BASE + "/doc"
main.EXAMPLES = main.BASE + "/examples"
main.LIBRARIES = main.BASE + "/libraries"

const electron = require('electron')
const app = electron.app
const DIALOG = require('electron').dialog;

// First we need to handle Squirrel installer events and exit fast.
if (handleSquirrelEvent()) {
  // squirrel event handled and app will exit in 1000ms, so don't do anything else
  return;
}

function handleSquirrelEvent() {
  if (process.argv.length === 1) {
    return false;
  }

  const ChildProcess = require('child_process');
  const path = require('path');

  const appFolder = path.resolve(process.execPath, '..');
  const rootAtomFolder = path.resolve(appFolder, '..');
  const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
  const exeName = path.basename(process.execPath);

  const spawn = function(command, args) {
    let spawnedProcess, error;

    try {
      spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
    } catch (error) {}

    return spawnedProcess;
  };

  const spawnUpdate = function(args) {
    return spawn(updateDotExe, args);
  };

  const squirrelEvent = process.argv[1];
  switch (squirrelEvent) {
    case '--squirrel-install':
    case '--squirrel-updated':
      // Optionally do things such as:
      // - Add your .exe to the PATH
      // - Write to the registry for things like file associations and
      //   explorer context menus

      // Install desktop and start menu shortcuts
      spawnUpdate(['--createShortcut', exeName]);

      setTimeout(app.quit, 1000);
      return true;

    case '--squirrel-uninstall':
      // Undo anything you did in the --squirrel-install and
      // --squirrel-updated handlers

      // Remove desktop and start menu shortcuts
      spawnUpdate(['--removeShortcut', exeName]);

      setTimeout(app.quit, 1000);
      return true;

    case '--squirrel-obsolete':
      // This is called on the outgoing version of your app before
      // we update to the new version - it's the opposite of
      // --squirrel-updated

      app.quit();
      return true;
  }
};

// Some more things we want
const Menu = electron.Menu
const MenuItem = electron.MenuItem
const Shell = electron.shell
const dialog = electron.dialog
const ipcMain = electron.ipcMain
const BrowserWindow = electron.BrowserWindow

// Keeping track of Windows (windowID) listening to each channel
main.listeners = new Map()

main.addMenu = function() {
  var template = [
    {
      label: 'File',
      submenu: [
        {
          label: 'New App...',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'newApp'}) }
        },
        {
          label: 'Getting Started',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'gettingStarted'}) }
        },
        {
          label: 'Share in Social Media',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'shareInSocialMedia'}) }
        }
      ]
    },
    {
      label: 'Edit',
      submenu: [
        {
          label: 'Undo',
          accelerator: 'CmdOrCtrl+Z',
          role: 'undo'
        },
        {
          label: 'Redo',
          accelerator: 'Shift+CmdOrCtrl+Z',
          role: 'redo'
        },
        {
          type: 'separator'
        },
        {
          label: 'Cut',
          accelerator: 'CmdOrCtrl+X',
          role: 'cut'
        },
        {
          label: 'Copy',
          accelerator: 'CmdOrCtrl+C',
          role: 'copy'
        },
        {
          label: 'Paste',
          accelerator: 'CmdOrCtrl+V',
          role: 'paste'
        },
        {
          label: 'Select All',
          accelerator: 'CmdOrCtrl+A',
          role: 'selectall'
        },
        {
          type: 'separator'
        },
        {
          label: 'Settings',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'openSettingsDialog'}) }
        }
      ]
    },
    {
      label: 'Viewers',
      submenu: [
        {
          label: 'Disconnect all Viewers',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'disconnectAllViewers'}) }
        }
      ]
    },
    {
      label: 'Tools',
      role: 'tools',
      submenu: [
        {
          label: 'JavaScript Console',
          accelerator: 'CmdOrCtrl+J',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'openConsoleWindow'}) }
        },
        {
          label: 'Viewers Explorer',
          accelerator: 'CmdOrCtrl+E',
          click: function() { main.workbenchWindow.webContents.send('command', {message: 'openViewersWindow'}) }
        },
      ]
    },
    {
      label: 'Window',
      role: 'window',
      submenu: [
        {
          label: 'Minimize',
          accelerator: 'CmdOrCtrl+M',
          role: 'minimize'
        },
        {
          label: 'Close',
          accelerator: 'CmdOrCtrl+W',
          role: 'close'
        },
        {
          label: 'Toggle Full Screen',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Ctrl+Command+F';
            else
              return 'F11';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
          }
        }
      ]
    },
    {
      label: 'Documentation',
      role: 'documentation',
      submenu: [
        {
          label: 'Index',
          click: function() { Shell.openExternal(main.DOC) }
        },
        {
          label: 'Examples',
          click: function() { Shell.openExternal(main.DOC + '/examples/examples.html') }
        },
        {
          label: 'ECMAScript 6',
          click: function() { Shell.openExternal(main.DOC + '/tutorials/ecmascript6.html') }
        },
        {
          label: 'Release Notes',
          click: function() { Shell.openExternal(main.DOC + '/studio/release-notes.html') }
        }
      ]
    },
    {
      label: 'Help',
      role: 'help',
      submenu: [
        {
          label: 'Chat on Gitter',
          click: function() { Shell.openExternal('https://gitter.im/evothings/evothings') }
        },
        {
          label: 'Support',
          submenu: [
            {
              label: 'Discussions',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/discussions') }
            },
            {
              label: 'Private Feedback',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/discussions/topics/new?forum_id=14000130317') }
            },
            {
              label: 'Feature Request',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/discussions/topics/new?forum_id=14000128400') }
            },
            {
              type: 'separator'
            },
            {
              label: 'Knowledge Base',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/solutions') }
            },
            {
              label: 'Frequently Asked Questions',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/solution/folders/14000103190') }
            },
            {
              label: 'New Support Ticket',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/tickets/new') }
            },
            {
              label: 'My Tickets',
              click: function() { Shell.openExternal('https://evothings.freshdesk.com/support/tickets') }
            },
          ]
        },
        {
          label: 'Old forum',
          click: function() { Shell.openExternal('https://evothings.com/forum/') }
        },
        {
          type: 'separator'
        },
        {
          label: 'Toggle Developer Tools',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Alt+Command+I';
            else
              return 'Ctrl+Shift+I';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.toggleDevTools();
          }
        },
        {
          type: 'separator'
        },
        {
          label: 'About Evothings Studio',
          click: function() { dialog.showMessageBox({
            type: "info",
            title: "Evothings Studio " + main.FULLVERSION,
            buttons: ["Close"],
            message: "Evothings Studio " + main.FULLVERSION,
            detail: "Evothings Studio is a development environment tailored for making hybrid mobile apps in the IoT domain.\n" +
              "\nBuilt: " + main.TIMESTAMP +
              "\nElectron: " + process.versions['electron'] +
              "\nChrome: " + process.versions['chrome'] +
              "\nNode: " + process.versions['node'] +
              "\nLicense: Apache License version 2.0" +
              "\n\nCopyright (c) 2016 Evothings AB"}) }
        }
      ]
    },
  ];

  if (process.platform == 'darwin') {
    template.unshift({
      label: 'Evothings Studio',
      submenu: [
        /*{
          label: 'About ' + name,
          role: 'about'
        },
        {
          type: 'separator'
        },*/
        {
          label: 'Services',
          role: 'services',
          submenu: []
        },
        {
          type: 'separator'
        },
        {
          label: 'Hide Evothings Studio',
          accelerator: 'Command+H',
          role: 'hide'
        },
        {
          label: 'Hide Others',
          accelerator: 'Command+Alt+H',
          role: 'hideothers'
        },
        {
          label: 'Show All',
          role: 'unhide'
        },
        {
          type: 'separator'
        },
        {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: function() { app.quit(); }
        }
      ]
    })
    // Window menu.
    template[5].submenu.push(
      {
        type: 'separator'
      },
      {
        label: 'Bring All to Front',
        role: 'front'
      }
    );
  } else {
    // Quit for Linux/Windows
    template[0].submenu.push(
      {
        label: 'Quit',
        accelerator: 'CmdOrCtrl+Q',
        click: function() { app.quit(); }
      }
    )
  }

  var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
}

//
//  TODO: Create a generic way to hold app state
//
main.setCurrentViewers = function(data)
{
  main.currentViewers = data
}

main.getCurrentViewers = function()
{
  return main.currentViewers
}
//
//
//

main.getRootDir = function() {
  return __dirname
}

main.createWorkbenchWindow = function() {
  main.workbenchWindow = new BrowserWindow({
    title: 'Evothings Studio ' + main.FULLVERSION + ' - Workbench',
    icon: 'hyper/ui/images/app-icon.png',
    width: 850, height: 720, webSecurity: false, show: false
  });

  main.workbenchWindow.on('closed', function() {
    main.workbenchWindow = null;
  });

  main.workbenchWindow.loadURL('file://' + __dirname + '/hyper/ui/index.html');
  main.addMenu();
  main.workbenchWindow.center()
}
main.showWorkbenchWindow = function() {
    main.workbenchWindow.show()
}

main.openConsoleWindow = function() {
  if (main.consoleWindow) {
    main.consoleWindow.show()
  } else {
    main.consoleWindow = new BrowserWindow({
      title: 'Javascript Console',
      width: 800,
      height: 600,
      show: false
    })

    main.consoleWindow.on('closed', function() {
      main.consoleWindow = null;
    });

    main.consoleWindow.loadURL('file://' + __dirname + '/hyper/ui/tools-window.html')
    main.consoleWindow.center()
  }
}
main.showConsoleWindow = function() {
  main.consoleWindow.show()
}

main.openViewersWindow = function() {
  if (main.viewersWindow) {
    main.viewersWindow.show()
  } else {
    main.viewersWindow = new BrowserWindow({
      title: 'Viewers Explorer',
      width: 800,
      height: 600,
      show: false
    })

    main.viewersWindow.on('closed', function() {
      main.viewersWindow = null;
    });

    main.viewersWindow.loadURL('file://' + __dirname + '/hyper/ui/hyper-viewers.html')
    main.viewersWindow.center()

  }
}
main.showViewersWindow = function() {
  main.viewersWindow.show()
}

main.selectOrCreateFolder = function(title, defaultDir) {
  return DIALOG.showOpenDialog({ title: title,
        defaultPath: defaultDir, properties: [ 'openDirectory', 'createDirectory']})
}

// Work as relay between our BrowserWindows since they can not talk to
// each other directly. We simply have one relay handler per window.
ipcMain.on('workbench-window', function(event, arg) {
  if (main.workbenchWindow) {
    main.workbenchWindow.webContents.send('msg', arg);
  }
});
ipcMain.on('console-window', function(event, arg) {
  if (main.consoleWindow) {
    main.consoleWindow.webContents.send('msg', arg);
  }
});
ipcMain.on('viewers-window', function(event, arg) {
  if (main.viewersWindow) {
    main.viewersWindow.webContents.send('msg', arg);
  }
});

// This is yet another means of communicating between BrowserWindows
// but using a publish subscribe model, this was the previous EVENTS module
ipcMain.on('events-subscribe', function(event, channel, windowID) {
  var listeners = main.listeners[channel] || new Set()
  //console.log("Subscribed window " + windowID + " to " + channel)
  listeners.add(windowID)
  main.listeners[channel] = listeners
});
ipcMain.on('events-unsubscribe', function(event, channel, windowID) {
  var listeners = main.listeners[channel]
  if (listeners) {
    listeners.delete(windowID)
    console.log("Unsubscribed window " + windowID + " from " + channel)
  }
});
// Forward the event to all registered windows for this channel
ipcMain.on('events-publish', function(event, channel, obj) {
  var listeners = main.listeners[channel]
  //console.log("Published "+ JSON.stringify(obj) + " to " + JSON.stringify(channel))
  if (listeners) {
    for (let windowID of listeners) {
      var window = BrowserWindow.fromId(windowID)
      if (window) {
        //console.log("Sending " + JSON.stringify(obj) + " to " + channel + " in window " + windowID)
        window.webContents.send('events-event', channel, obj);
      }
    }
  }
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', main.createWorkbenchWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (main.workbenchWindow === null) {
    main.createWorkbenchWindow();
  }
});
<|endoftext|>


<commit_before>const path = require('path')
const fs = require('fs')
const YAML = require('yamljs')
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

// Kill screenwerk processes if any ...
fs.readdirSync(path.resolve(__dirname, '..', 'local')).forEach((filename) => {
  console.log(filename.split('.'))
  if (filename.split('.')[2] !== 'pid') { return }
  let pid = filename.split('.')[1]
  console.log('must terminate ' + pid)
  var isWin = /^win/.test(process.platform)
  try {
    if(!isWin) {
      process.kill(pid, 'SIGTERM')
    } else {
      cp.exec('taskkill /PID ' + pid + ' /T /F')
    }
  } catch (e) {
    fs.unlinkSync(path.resolve(__dirname, '..', 'local', '.' + pid + '.pid'))
  }
})
// ... and create my own
let pidFilePath = path.resolve(__dirname, '..', 'local', '.' + process.pid + '.pid')
fs.writeFileSync(pidFilePath, process.pid, 'utf8')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

let displayNum = 1
let devMode = false
function createWindow () {

  let confFilePath = path.resolve(__dirname, '..', 'local', 'screen.yml')
  try {
    let data = fs.readFileSync(confFilePath, 'utf8')
    let conf = YAML.parse(data)
    displayNum = conf.DISPLAY_NUM
    devMode = conf.DEV_MODE
  }
  catch (e) {
    console.log('Cant read from configuration file from ' + confFilePath + '. Not a problem (yet).', e)
  }

  // Create the browser window.
  let electronScreen = electron.screen
  let displays = electronScreen.getAllDisplays()
  if (displays.length < displayNum) {
    displayNum = 1
  }
  // displayNum should be either 0 (main screen) or the number set in configuration minus one.
  displayNum --
  let display = displays[displayNum]

  mainWindow = new BrowserWindow({ x: display.bounds.x, y: display.bounds.y, width: 900, height: 600 })
  mainWindow.setKiosk(true)
  mainWindow.setMenu(null)
  // and load the index.html of the app.
  mainWindow.loadURL('file://' + __dirname + '/index.html')

  // Open the DevTools.
  if (devMode === true) {
    mainWindow.webContents.openDevTools()
    process.env.DEBUG = '*'
  }
  const debug = require('debug')('main')
  debug('Running in DEBUG=* mode')

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    let pidFilePath = path.resolve(__dirname, '..', 'local', '.' + process.pid + '.pid')
    console.log('Unlink ' + pidFilePath)
    let result = fs.unlinkSync(pidFilePath)
    if (result instanceof Error) {
      console.log("Can't unlink " + pidFilePath, result)
    }
    mainWindow = null
    app.quit()
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<commit_msg>test process.kill on win<commit_after>const path = require('path')
const fs = require('fs')
const YAML = require('yamljs')
const electron = require('electron')
// Module to control application life.
const app = electron.app
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow

// Kill screenwerk processes if any ...
fs.readdirSync(path.resolve(__dirname, '..', 'local')).forEach((filename) => {
  console.log(filename.split('.'))
  if (filename.split('.')[2] !== 'pid') { return }
  let pid = filename.split('.')[1]
  console.log('must terminate ' + pid)
  var isWin = /^win/.test(process.platform)
  try {
    // if(!isWin) {
      process.kill(pid, 'SIGTERM')
    // } else {
      // cp.exec('taskkill /PID ' + pid + ' /T /F')
    // }
  } catch (e) {
    console.log('Kill failed ' + path.resolve(__dirname, '..', 'local', '.' + pid + '.pid'))
    // fs.unlinkSync(path.resolve(__dirname, '..', 'local', '.' + pid + '.pid'))
  }
})
// ... and create my own
let pidFilePath = path.resolve(__dirname, '..', 'local', '.' + process.pid + '.pid')
fs.writeFileSync(pidFilePath, process.pid, 'utf8')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow

let displayNum = 1
let devMode = false
function createWindow () {

  let confFilePath = path.resolve(__dirname, '..', 'local', 'screen.yml')
  try {
    let data = fs.readFileSync(confFilePath, 'utf8')
    let conf = YAML.parse(data)
    displayNum = conf.DISPLAY_NUM
    devMode = conf.DEV_MODE
  }
  catch (e) {
    console.log('Cant read from configuration file from ' + confFilePath + '. Not a problem (yet).', e)
  }

  // Create the browser window.
  let electronScreen = electron.screen
  let displays = electronScreen.getAllDisplays()
  if (displays.length < displayNum) {
    displayNum = 1
  }
  // displayNum should be either 0 (main screen) or the number set in configuration minus one.
  displayNum --
  let display = displays[displayNum]

  mainWindow = new BrowserWindow({ x: display.bounds.x, y: display.bounds.y, width: 900, height: 600 })
  mainWindow.setKiosk(true)
  mainWindow.setMenu(null)
  // and load the index.html of the app.
  mainWindow.loadURL('file://' + __dirname + '/index.html')

  // Open the DevTools.
  if (devMode === true) {
    mainWindow.webContents.openDevTools()
    process.env.DEBUG = '*'
  }
  const debug = require('debug')('main')
  debug('Running in DEBUG=* mode')

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    let pidFilePath = path.resolve(__dirname, '..', 'local', '.' + process.pid + '.pid')
    console.log('Unlink ' + pidFilePath)
    try {
      let result = fs.unlinkSync(pidFilePath)
      if (result instanceof Error) {
        console.log("Can't unlink " + pidFilePath, result)
      }
    } catch (e) {
      console.log(e)
    }
    mainWindow = null
    app.quit()
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<|endoftext|>


<commit_before>import {Observable} from 'rx';
import Cycle from '@cycle/core';
import {h, makeDOMDriver} from '@cycle/dom';
import {sample} from 'lodash';
import draw from './logoGenerator';

const main = () => {

  const REFRESH_RATE = 800;

  const PALETTE = [
    '#fc000',
    '#0038CC',
    '#215CFF',
    '#FFD605',
    '#FF7D05'
  ];

  const intent = Observable.interval(REFRESH_RATE)
    .startWith(0)
    .map(i => i+1);

  const model = intent.map(() => {
      return sample(PALETTE, 4);
  });

  const svg = model
    .map(colours => {

      const data = {
        colour1: colours[0],
        colour2: colours[1],
        colour3: colours[2],
        colour4: colours[3]
      };

      const output = draw(data);

      return output;
    });

  const DOM = Observable.just(
    h('button', 'Refresh')
  );

  return {
    svg,
    DOM
  };
};

const makeCanvasDriver = (canvasId) => {
  return svgStr$ => {
    svgStr$.subscribe(svgStr => {
      canvg(canvasId, svgStr, {
        ignoreMouse: true,
        ignoreAnimation: true
      });
    })
  };
};

const drivers = {
  DOM: makeDOMDriver('#app'),
  svg: makeCanvasDriver('display')
};

Cycle.run(main, drivers);
<commit_msg>Minor tweaks<commit_after>import {Observable, Subject} from 'rx';
import Cycle from '@cycle/core';
import {h, makeDOMDriver} from '@cycle/dom';
import {sample} from 'lodash';
import draw from './logoGenerator';

const main = ({DOM}) => {

  const REFRESH_RATE = 1000;

  const PALETTE = [
    '#0038CC',
    '#215CFF',
    '#FFD605',
    '#FF7D05'
  ];

  const togglePlay$ = DOM.select('input.toggle')
    .events('change')
    .map(ev => ev.target.checked)
    .startWith(true);

  const intent = Observable.interval(REFRESH_RATE);

  const speed$ = DOM.select('input.speed')
    .events('input')
    .startWith(1000)
    .map(value => {
      refreshInterval.onNext(value);
    });

  const model = intent.map(() => {
      return sample(PALETTE, 4);
  });

  const svg = model
    .map(colours => {

      const data = {
        colour1: colours[0],
        colour2: colours[1],
        colour3: colours[2],
        colour4: colours[3]
      };

      const output = draw(data);

      return output;
    });

  const vTree$ = togglePlay$.map(
    shouldPlay => {
      return h('div', [

        //h('input.toggle', {
        //  type: 'checkbox',
        //  checked: shouldPlay
        //}, 'Play?'),

        //h('input.speed', {
        //  type: 'range',
        //  min: 200,
        //  max: 2000
        //})
      ])
    }
  );

  return {
    svg,
    DOM: vTree$
  };
};

const makeCanvasDriver = (canvasId) => {
  return svgStr$ => {
    svgStr$.subscribe(svgStr => {
      canvg(canvasId, svgStr, {
        ignoreMouse: true,
        ignoreAnimation: true
      });
    })
  };
};

const drivers = {
  DOM: makeDOMDriver('#app'),
  svg: makeCanvasDriver('display')
};

Cycle.run(main, drivers);
<|endoftext|>


<commit_before><commit_msg>Oops, this is what the config is called now<commit_after><|endoftext|>


<commit_before>const boss = require ('./boss')

const initPromise = new Promise ((resolve, reject) => {
  boss.onRuntimeInitialized = resolve
})

const wrapBoss = (args) => {
  return initPromise
    .then (() => {
      args = args || [];

      var nFiles = 0, filePrefix = 'FILE'
      const wrappedArgs = args.map ((opt) => {
	if (typeof(opt) !== 'string') {
	  const fileBuffer = JSON.stringify (opt)
	  const filename = filePrefix + (++nFiles)
	  boss.FS.writeFile (filename, new Uint8Array(fileBuffer))
	  return filename
	} else
	  return opt
      })

      boss.stdout = []
      boss.callMain (wrappedArgs)
      const result = JSON.parse (boss.stdout.join(''))
      delete boss.stdout
      return result
    })
}

module.exports = { initialized: initPromise,
		   run: wrapBoss,
		   boss: boss }
<commit_msg>wasm/jsonwrap.js<commit_after>const boss = require ('./boss')

const initPromise = new Promise ((resolve, reject) => {
  boss.onRuntimeInitialized = resolve
})

const wrapBoss = (args) => {
  return initPromise
    .then (() => {
      args = args || [];

      let nFiles = 0, filePrefix = 'FILE'
      const wrappedArgs = args.map ((opt) => {
	if (typeof(opt) !== 'string') {
	  const fileBuffer = JSON.stringify (opt)
	  const filename = filePrefix + (++nFiles)
	  boss.FS.writeFile (filename, new Uint8Array(fileBuffer))
	  return filename
	} else
	  return opt
      })

      boss.stdout = []
      boss.callMain (wrappedArgs)
      const result = JSON.parse (boss.stdout.join(''))
      delete boss.stdout
      return result
    })
}

module.exports = { initialized: initPromise,
		   run: wrapBoss,
		   boss: boss }
<|endoftext|>