<commit_before>exports.yo = function() {
    const express = require('express');
    const app = express();
    const bodyParser = require('body-parser');
    const faker = require('faker');
    const API_ROOT = '/x/comment';

    // Fake comments
    let comments = [];
    const commentsCount = Math.floor(Math.random() * 20) + 5;
    for (let i = 0; i < commentsCount; i++) {
        comments.push({
            uuid: faker.random.uuid(),
            author: faker.random.number(),
            msg: faker.lorem.sentences(),
            creationDate: faker.date.past(),
            lastModified: faker.date.recent(),
            authorDisplayName: faker.name.findName()
        });
    }
    const myId = 'me';
    const myDisplayName = faker.name.findName();

    comments.push({
        uuid: faker.random.uuid(),
        author: myId,
        msg: faker.lorem.sentences(),
        creationDate: faker.date.past(),
        lastModified: faker.date.recent(),
        authorDisplayName: myDisplayName
    });

    comments = comments.sort(function compare(a, b) {
        return a.creationDate.getTime() - b.creationDate.getTime();
    });

    const avatars = comments.reduce(function reduceComments(result, comment) {
        result[comment.author] = faker.image.avatar();
        return result;
    }, {[myId]: faker.image.avatar()});

    // Middlewares

    app.use(function corsMiddleware(req, res, next) {
        res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
        res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
        res.header('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,DELETE');
        res.header('Access-Control-Allow-Credentials', 'true');
        res.header('Content-Type', 'application/json');
        next();
    });
    app.use(bodyParser.json());

    app.get(API_ROOT + '/api/comments', function getComments(req, res) {
        setTimeout(function defer() {
            res.json(comments);
        }, 500);
    });

    app.post(API_ROOT + '/api/comments', function publishComment(req, res) {
        const comment = req.body;
        comment.uuid = faker.random.uuid();
        comment.creationDate = new Date();
        comment.lastModified = new Date();
        comment.author = myId;
        comment.authorDisplayName = myDisplayName;
        comments.push(comment);
        res.end();
    });

    app.put(API_ROOT + '/api/comments/:uuid', function updateComment(req, res) {
        const uuid = req.params.uuid;
        comments = comments.map(function updateComment(comment) {
            if (comment.uuid === uuid) {
                comment = req.body;
                comment.uuid = uuid;
                comment.lastModified = new Date();
            }
            return comment;
        });
        res.end();
    });

    app.get('/x/account/api/accounts/:authorId/photo', function getAvatar(req, res) {
        const authorId = req.params.authorId;
        res.redirect(avatars[authorId]);
    });
    console.log('MAN');
}
<commit_msg>Remove useless log<commit_after>exports.yo = function() {
    const express = require('express');
    const app = express();
    const bodyParser = require('body-parser');
    const faker = require('faker');
    const API_ROOT = '/x/comment';

    // Fake comments
    let comments = [];
    const commentsCount = Math.floor(Math.random() * 20) + 5;
    for (let i = 0; i < commentsCount; i++) {
        comments.push({
            uuid: faker.random.uuid(),
            author: faker.random.number(),
            msg: faker.lorem.sentences(),
            creationDate: faker.date.past(),
            lastModified: faker.date.recent(),
            authorDisplayName: faker.name.findName()
        });
    }
    const myId = 'me';
    const myDisplayName = faker.name.findName();

    comments.push({
        uuid: faker.random.uuid(),
        author: myId,
        msg: faker.lorem.sentences(),
        creationDate: faker.date.past(),
        lastModified: faker.date.recent(),
        authorDisplayName: myDisplayName
    });

    comments = comments.sort(function compare(a, b) {
        return a.creationDate.getTime() - b.creationDate.getTime();
    });

    const avatars = comments.reduce(function reduceComments(result, comment) {
        result[comment.author] = faker.image.avatar();
        return result;
    }, {[myId]: faker.image.avatar()});

    // Middlewares

    app.use(function corsMiddleware(req, res, next) {
        res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
        res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
        res.header('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,DELETE');
        res.header('Access-Control-Allow-Credentials', 'true');
        res.header('Content-Type', 'application/json');
        next();
    });
    app.use(bodyParser.json());

    app.get(API_ROOT + '/api/comments', function getComments(req, res) {
        setTimeout(function defer() {
            res.json(comments);
        }, 500);
    });

    app.post(API_ROOT + '/api/comments', function publishComment(req, res) {
        const comment = req.body;
        comment.uuid = faker.random.uuid();
        comment.creationDate = new Date();
        comment.lastModified = new Date();
        comment.author = myId;
        comment.authorDisplayName = myDisplayName;
        comments.push(comment);
        res.end();
    });

    app.put(API_ROOT + '/api/comments/:uuid', function updateComment(req, res) {
        const uuid = req.params.uuid;
        comments = comments.map(function updateComment(comment) {
            if (comment.uuid === uuid) {
                comment = req.body;
                comment.uuid = uuid;
                comment.lastModified = new Date();
            }
            return comment;
        });
        res.end();
    });

    app.get('/x/account/api/accounts/:authorId/photo', function getAvatar(req, res) {
        const authorId = req.params.authorId;
        res.redirect(avatars[authorId]);
    });
}
<|endoftext|>


<commit_before>module.exports = function() {
  var element = document.createElement('h1');

  element.className = 'pure-button';
  element.innerHTML = 'Hello worlds';

  return element;
};
<commit_msg>remove old hello world<commit_after><|endoftext|>


<commit_before>//global variables
var stage;
var text;
var pixelMatrix; // 3D array of the row and columns with an area of rectSize^2
var rawPixelData; // array of pixel objects
var blackRects;
//setting variables
var canBackground, fps;
var rectSize, thresholdAlpha, resolution;
var innerText, outerText;
//variables vor animated drawing
var animatedK;
var animatedO;
var fpsLabel;
var guiElements; // data object for gui
var gui; // actual gui object (dat.gui)
/////////////////////////////////
/// Start Point
$(document).ready(function() {
    preInit();
    init();
});
// PreInit
function preInit() {
    //Initialise GUI
    guiElements = {
        Message: "",
        InnerText: "1",
        OuterText: "0",
        IsAnimated: false,
        Start: startVisualisation,
        ExportJPG: exportJPEG
    };
    gui = new dat.GUI();
    gui.add(guiElements, 'Message').name("Your text: ");
    gui.add(guiElements, 'InnerText').name("Inner text: ");
    gui.add(guiElements, 'OuterText').name("Outer text: ");
    gui.add(guiElements, 'IsAnimated').name("Animated Drawing");
    gui.add(guiElements, 'Start').name("Start");
    gui.add(guiElements, 'ExportJPG').name("Export");
    // set canvas size
    $("#demoCanvas").attr({
        width: $("body").width(),
        height: $("body").height()
    });
};
//initialize the project
function init() {
    /*
     * SETTINGS
     */
    canBackground = "RGB(255,255,255)";
    fps = 500;
    rectSize = 10;
    thresholdAlpha = 250;
    /*
     * SETTINGS END
     */
    //create stage
    stage = new createjs.Stage("demoCanvas");
    stage.canvas.style.background = canBackground;
    resolution = Math.floor((rectSize * rectSize) / 2);
    rectResolution = {
        x: Math.floor(stage.canvas.width / rectSize),
        y: Math.floor(stage.canvas.height / rectSize)
    };
    //calculate array size by rectSize
    rawPixelData = [];
    pixelMatrix = createEmpty3DArray(rectResolution.x + 1, rectResolution.y + 1);
    blackRects = createFilled2DArray(rectResolution.x, rectResolution.y);
    //fps label to show the fps
    fpsLabel = new createjs.Text("-- fps", "bold 18px Arial", "#000");
    fpsLabel.visible = guiElements.IsAnimated;
    fpsLabel.x = 10;
    fpsLabel.y = 10;
    stage.addChild(fpsLabel);
    stage.update();
}
//ticker, which controls the drawing
function tick() {
    if (!createjs.Ticker.paused) {
        drawAnimated();
        fpsLabel.text = Math.round(createjs.Ticker.getMeasuredFPS()) + " fps";
        console.log(fpsLabel.text);
        //update on every row
        if (animatedO == 0) {
            stage.update();
        }
    }
}

function startVisualisation() {
    createjs.Ticker.paused = false;
    stage.removeAllChildren();
    fpsLabel.visible = guiElements.IsAnimated;
    stage.addChild(fpsLabel); //add fps label again
    showText(guiElements.Message, stage.canvas.width / 2, stage.canvas.height / 2, 20, true);
    rawPixelData = getPixels();
    stage.removeChild(text);
    for (i = 0; i < rawPixelData.length; i++) {
        for (j = 0; j < rawPixelData[i].length; j++) {
            x = Math.floor(i / rectSize);
            y = Math.floor(j / rectSize);
            pixelMatrix[x][y].push(rawPixelData[i][j]);
        }
    }
    blackRects = calcFilledAreas(pixelMatrix, resolution);
    if (guiElements.IsAnimated) {
        animatedO = 0;
        animatedK = 0;
        createjs.Ticker.addEventListener("tick", tick);
        createjs.Ticker.setFPS(fps);
    } else {
        draw();
    }
}

function getPixels() {
    var imageData = stage.canvas.getContext('2d').getImageData(0, 0, stage.canvas.width, stage.canvas.height).data;
    var arr = [];
    for (i = 0; i < imageData.length; i = i + 4) {
        arr.push({
            r: imageData[i],
            g: imageData[i + 1],
            b: imageData[i + 2],
            a: imageData[i + 3]
        });
    }
    var matrix = createFilled2DArray(stage.canvas.width, stage.canvas.height);
    var index = 0;
    for (i = 0; i < stage.canvas.height; i++) {
        for (j = 0; j < stage.canvas.width; j++) {
            matrix[j][i] = arr[index];
            index++;
        }
    }
    return matrix;
}

function showText(msg, x, y, scale, update) {
    text = new createjs.Text();
    text.set({
        text: msg,
        textAlign: 'center',
        textBaseline: 'middle'
    });
    //scale text
    text.scaleX = scale;
    text.scaleY = scale;
    //move text to mid of canvas
    b = text.getBounds();
    text.x = x;
    text.y = y;
    text.snapToPixel = true;
    stage.addChild(text);
    if (update) stage.update(); //update stage to show text
}

function createEmpty3DArray(xSize, ySize) {
    var array3D = new Array(xSize);
    for (i = 0; i < array3D.length; i++) {
        array3D[i] = new Array(ySize);
        for (j = 0; j < array3D[i].length; j++) {
            array3D[i][j] = [];
        }
    }
    return array3D;
}

function createFilled2DArray(xSize, ySize) {
    var array2D = new Array(xSize);
    for (i = 0; i < array2D.length; i++) {
        array2D[i] = new Array(ySize);
    }
    return array2D;
}

function calcFilledAreas(pM, res) {
    var blackPixelCounter;
    var matrixWithBlackAreas = createFilled2DArray(pM.length, pM[0].length);
    for (i = 0; i < pM.length; i++) {
        for (j = 0; j < pM[i].length; j++) {
            for (k = 0; k < pM[i][j].length; k++) {
                if (pM[i][j][k].a >= thresholdAlpha) {
                    blackPixelCounter++;
                }
            }
            if (blackPixelCounter >= res) {
                matrixWithBlackAreas[i][j] = true;
            } else {
                matrixWithBlackAreas[i][j] = false;
            }
            blackPixelCounter = 0;
        }
    }
    return matrixWithBlackAreas;
}

function draw() {
    innerText = guiElements.InnerText;
    outterText = guiElements.OuterText;
    for (k = 0; k < blackRects.length; k++) {
        for (o = 0; o < blackRects[k].length; o++) {
            if (blackRects[k][o] == true) {
                showText(innerText, k * rectSize, o * rectSize, 1, false);
            } else {
                showText(outterText, k * rectSize, o * rectSize, 1, false);
            }
        }
    }
    stage.update();
    createjs.Ticker.paused = true;
}
cacheCon = new createjs.Shape();

function drawAnimated() {
    innerText = guiElements.InnerText;
    outterText = guiElements.OuterText;
    if (animatedK < blackRects.length) {
        if (animatedO < blackRects[animatedK].length) {
            if (blackRects[animatedK][animatedO] == true) {
                showText(innerText, animatedK * rectSize, animatedO * rectSize, 1, false);
            } else {
                showText(outterText, animatedK * rectSize, animatedO * rectSize, 1, false);
            }
            animatedO++;
        } else {
            animatedK++;
            animatedO = 0;
            cacheCon.uncache();
            cacheCon.cache(0, 0, animatedK * rectSize, stage.canvas.height);
        }
    } else {
        createjs.Ticker.paused = true;
        animatedK = 0;
        animatedO = 0;
    }
}

function exportJPEG() {
    stage.removeChild(fpsLabel);
    //generate the url using toDataURL
    canvas = document.getElementById("demoCanvas");
    var img = canvas.toDataURL("image/png;base64;");
    //img = img.replace("image/png","image/octet-stream"); // force download, user would have to give the file name.
    // you can also use anchor tag with download attribute to force download the canvas with file name.
    window.open(img, "", "width=500,height=500");
}
<commit_msg>removed fps log. theres an label<commit_after>//global variables
var stage;
var text;
var pixelMatrix; // 3D array of the row and columns with an area of rectSize^2
var rawPixelData; // array of pixel objects
var blackRects;
//setting variables
var canBackground, fps;
var rectSize, thresholdAlpha, resolution;
var innerText, outerText;
//variables vor animated drawing
var animatedK;
var animatedO;
var fpsLabel;
var guiElements; // data object for gui
var gui; // actual gui object (dat.gui)
/////////////////////////////////
/// Start Point
$(document).ready(function() {
    preInit();
    init();
});
// PreInit
function preInit() {
    //Initialise GUI
    guiElements = {
        Message: "",
        InnerText: "1",
        OuterText: "0",
        IsAnimated: false,
        Start: startVisualisation,
        ExportJPG: exportJPEG
    };
    gui = new dat.GUI();
    gui.add(guiElements, 'Message').name("Your text: ");
    gui.add(guiElements, 'InnerText').name("Inner text: ");
    gui.add(guiElements, 'OuterText').name("Outer text: ");
    gui.add(guiElements, 'IsAnimated').name("Animated Drawing");
    gui.add(guiElements, 'Start').name("Start");
    gui.add(guiElements, 'ExportJPG').name("Export");
    // set canvas size
    $("#demoCanvas").attr({
        width: $("body").width(),
        height: $("body").height()
    });
};
//initialize the project
function init() {
    /*
     * SETTINGS
     */
    canBackground = "RGB(255,255,255)";
    fps = 500;
    rectSize = 10;
    thresholdAlpha = 250;
    /*
     * SETTINGS END
     */
    //create stage
    stage = new createjs.Stage("demoCanvas");
    stage.canvas.style.background = canBackground;
    resolution = Math.floor((rectSize * rectSize) / 2);
    rectResolution = {
        x: Math.floor(stage.canvas.width / rectSize),
        y: Math.floor(stage.canvas.height / rectSize)
    };
    //calculate array size by rectSize
    rawPixelData = [];
    pixelMatrix = createEmpty3DArray(rectResolution.x + 1, rectResolution.y + 1);
    blackRects = createFilled2DArray(rectResolution.x, rectResolution.y);
    //fps label to show the fps
    fpsLabel = new createjs.Text("-- fps", "bold 18px Arial", "#000");
    fpsLabel.visible = guiElements.IsAnimated;
    fpsLabel.x = 10;
    fpsLabel.y = 10;
    stage.addChild(fpsLabel);
    stage.update();
}
//ticker, which controls the drawing
function tick() {
    if (!createjs.Ticker.paused) {
        drawAnimated();
        fpsLabel.text = Math.round(createjs.Ticker.getMeasuredFPS()) + " fps";
        //update on every row
        if (animatedO == 0) {
            stage.update();
        }
    }
}

function startVisualisation() {
    createjs.Ticker.paused = false;
    stage.removeAllChildren();
    fpsLabel.visible = guiElements.IsAnimated;
    stage.addChild(fpsLabel); //add fps label again
    showText(guiElements.Message, stage.canvas.width / 2, stage.canvas.height / 2, 20, true);
    rawPixelData = getPixels();
    stage.removeChild(text);
    for (i = 0; i < rawPixelData.length; i++) {
        for (j = 0; j < rawPixelData[i].length; j++) {
            x = Math.floor(i / rectSize);
            y = Math.floor(j / rectSize);
            pixelMatrix[x][y].push(rawPixelData[i][j]);
        }
    }
    blackRects = calcFilledAreas(pixelMatrix, resolution);
    if (guiElements.IsAnimated) {
        animatedO = 0;
        animatedK = 0;
        createjs.Ticker.addEventListener("tick", tick);
        createjs.Ticker.setFPS(fps);
    } else {
        draw();
    }
}

function getPixels() {
    var imageData = stage.canvas.getContext('2d').getImageData(0, 0, stage.canvas.width, stage.canvas.height).data;
    var arr = [];
    for (i = 0; i < imageData.length; i = i + 4) {
        arr.push({
            r: imageData[i],
            g: imageData[i + 1],
            b: imageData[i + 2],
            a: imageData[i + 3]
        });
    }
    var matrix = createFilled2DArray(stage.canvas.width, stage.canvas.height);
    var index = 0;
    for (i = 0; i < stage.canvas.height; i++) {
        for (j = 0; j < stage.canvas.width; j++) {
            matrix[j][i] = arr[index];
            index++;
        }
    }
    return matrix;
}

function showText(msg, x, y, scale, update) {
    text = new createjs.Text();
    text.set({
        text: msg,
        textAlign: 'center',
        textBaseline: 'middle'
    });
    //scale text
    text.scaleX = scale;
    text.scaleY = scale;
    //move text to mid of canvas
    b = text.getBounds();
    text.x = x;
    text.y = y;
    text.snapToPixel = true;
    stage.addChild(text);
    if (update) stage.update(); //update stage to show text
}

function createEmpty3DArray(xSize, ySize) {
    var array3D = new Array(xSize);
    for (i = 0; i < array3D.length; i++) {
        array3D[i] = new Array(ySize);
        for (j = 0; j < array3D[i].length; j++) {
            array3D[i][j] = [];
        }
    }
    return array3D;
}

function createFilled2DArray(xSize, ySize) {
    var array2D = new Array(xSize);
    for (i = 0; i < array2D.length; i++) {
        array2D[i] = new Array(ySize);
    }
    return array2D;
}

function calcFilledAreas(pM, res) {
    var blackPixelCounter = 0;
    var matrixWithBlackAreas = createFilled2DArray(pM.length, pM[0].length);
    for (i = 0; i < pM.length; i++) {
        for (j = 0; j < pM[i].length; j++) {
            for (k = 0; k < pM[i][j].length; k++) {
                if (pM[i][j][k].a >= thresholdAlpha) {
                    blackPixelCounter++;
                }
            }
            if (blackPixelCounter >= res) {
                matrixWithBlackAreas[i][j] = true;
            } else {
                matrixWithBlackAreas[i][j] = false;
            }
            blackPixelCounter = 0;
        }
    }
    return matrixWithBlackAreas;
}

function draw() {
    innerText = guiElements.InnerText;
    outterText = guiElements.OuterText;
    for (k = 0; k < blackRects.length; k++) {
        for (o = 0; o < blackRects[k].length; o++) {
            if (blackRects[k][o] == true) {
                showText(innerText, k * rectSize, o * rectSize, 1, false);
            } else {
                showText(outterText, k * rectSize, o * rectSize, 1, false);
            }
        }
    }
    stage.update();
    createjs.Ticker.paused = true;
}
cacheCon = new createjs.Shape();

function drawAnimated() {
    innerText = guiElements.InnerText;
    outterText = guiElements.OuterText;
    if (animatedK < blackRects.length) {
        if (animatedO < blackRects[animatedK].length) {
            if (blackRects[animatedK][animatedO] == true) {
                showText(innerText, animatedK * rectSize, animatedO * rectSize, 1, false);
            } else {
                showText(outterText, animatedK * rectSize, animatedO * rectSize, 1, false);
            }
            animatedO++;
        } else {
            animatedK++;
            animatedO = 0;
            cacheCon.uncache();
            cacheCon.cache(0, 0, animatedK * rectSize, stage.canvas.height);
        }
    } else {
        createjs.Ticker.paused = true;
        animatedK = 0;
        animatedO = 0;
    }
}

function exportJPEG() {
    stage.removeChild(fpsLabel);
    //generate the url using toDataURL
    canvas = document.getElementById("demoCanvas");
    var img = canvas.toDataURL("image/png;base64;");
    //img = img.replace("image/png","image/octet-stream"); // force download, user would have to give the file name.
    // you can also use anchor tag with download attribute to force download the canvas with file name.
    window.open(img, "", "width=500,height=500");
}
<|endoftext|>


<commit_before>'use strict';

var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })
var express = require('express');
var Polls = require('../models/polls.js');
var handlebars  = require('handlebars');
var fs = require('fs');

//For creating polls

module.exports = function (app, db, passport) {

var bodyParser = require('body-parser')
app.use(bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
}));

app.route('/create')
  .get(function (req, res) {
    var loggedin;
    if (req.isAuthenticated()) {
        loggedin = true;

     } else {
        loggedin =false;
    }
     var data = {
              loggedin: loggedin
           }

        fs.readFile('public/create.html', 'utf-8', function(error, source){
                var template = handlebars.compile(source);
                var html = template(data);
                res.send(html);

                });
});

app.post('/create',  upload.array(), function (req, res, next) {

    console.log(req.body)
    var categories = [];

    //TO DO Add in authorship. Add in vote

    // finds how many fields there are transforms all answer fields into an array of objects
    for (var i=1; i< Object.keys(req.body).length; i++){
      categories[i-1] = {"category":req.body["field"+i], "voters":[] };
    }
    //while fields exis t

    //Puts creation in callback. Will count # of records and then give new record ID of count+1
    Polls.count({}, function(err, count){
      if (err){ throw err;}
        console.log( "Number of docs: ", count );

           var newDoc = new Polls({ 'question': req.body['question'],
           choices: categories,
           id: count+1,
           creator: req.user.username,
           });
           newDoc.save(function (err, doc) {
         if (err) { throw err; }
          res.redirect('/polls/'+doc.id);
    });
    });

	  //res.status(204).end();
});

//user visits poll creation page

};<commit_msg>delete working<commit_after>'use strict';

var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })
var express = require('express');
var Polls = require('../models/polls.js');
var handlebars  = require('handlebars');
var fs = require('fs');

//For creating polls

module.exports = function (app, db, passport) {

var bodyParser = require('body-parser')
app.use(bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
}));

app.route('/create')
  .get(function (req, res) {
    var loggedin;
    if (req.isAuthenticated()) {
        loggedin = true;

     } else {
        loggedin =false;
    }
     var data = {
              loggedin: loggedin
           }

        fs.readFile('public/create.html', 'utf-8', function(error, source){
                var template = handlebars.compile(source);
                var html = template(data);
                res.send(html);

                });
});

app.post('/create',  upload.array(), function (req, res, next) {

    console.log(req.body)
    var categories = [];

    //TO DO Add in authorship. Add in vote

    // finds how many fields there are transforms all answer fields into an array of objects
    for (var i=1; i< Object.keys(req.body).length; i++){
      categories[i-1] = {"category":req.body["field"+i], "voters":[] };
    }
    //while fields exis t

    //Puts creation in callback. Will count # of records and then give new record ID of count+1
    Polls.count({}, function(err, count){
      if (err){ throw err;}
        console.log( "Number of docs: ", count );

           var newDoc = new Polls({ 'question': req.body['question'],
           choices: categories,
           id: count+1,
           creator: req.user.username,
           });
           newDoc.save(function (err, doc) {
         if (err) { throw err; }
          res.redirect('/polls/'+doc.id);
    });
    });

});

//user visits poll creation page

};<|endoftext|>


<commit_before>// Allow starting numerals with decimal point:
/* jshint -W008 */
import Ember from 'ember';
import config from '../config/environment';

export default Ember.Route.extend({
  actions: {
    beforeResize: function() {
      this.clearVariantConnectors();
    },
    afterResize: function() {
      this.positionVariants();
    }
  },
  model: function(params) {
    return Ember.$.ajax({
      url: config.solrURL,
      data: {
        wt: 'json',
        q: `id:${params.letter_id} or (doc_id:${params.letter_id} and type:variante)`,
        rows: 9999
      },
      dataType: 'jsonp',
      jsonp: 'json.wrf'
    }).then( function(json) {
      var letter = {};
      if ( json.response.docs.length > 0 ) {
        // TODO: Is letter always the first doc in response?
        letter = json.response.docs[0];
        letter.volltext = letter.volltext;
        letter.variants = json.response.docs.slice(1);
        // Determine variant type from ID
        // TODO: Would be nice to use for ( ... of ... ) here, but breaks tests
        letter.variants.forEach( function(variant) {
          var typeHint = variant.id.substr(0, 4);
          switch ( typeHint ) {
            case 'vara':
              variant.type = 'addition';
              break;
            case 'varc':
              variant.type = 'variant';
              break;
          }
        });
      } else {
        letter.id = params.letter_id;
      }

      // NOTE: query-params can only use this string if it is correctly URL-encoded
      letter.viewQuery = params.view;
      try {
        letter.view = Ember.$.parseJSON(params.view);
      } catch (e) {
        letter.view = null;
      }

      return letter;
    });
  },
  renderTemplate: function() {
    this.render({ outlet: 'letter' });
    this.controller.set('rendered', false);
  },
  setupController: function (controller, model) {
    this._super(controller, model);
    controller.set('rendered', true);
  },
  afterModel: function() {
    Ember.run.next( () => {
      this.activateLinks();

      // Convert image references to SVG images
      Ember.$('.transcript').find('.reference.-image').each( (index, ref) => {
        var imageID = Ember.$(ref).data('id');
        this.loadSVG(imageID).then( function(svg) {
          Ember.$(ref).html(svg);
        });
      });

      // Render MathJax, then position variants
      this.renderMathJax().then( () => {
        this.positionVariants();
        Ember.$('.content').resize( () => {
          Ember.run.debounce(this, this.clearVariantConnectors, 250, true);
          Ember.run.debounce(this, this.positionVariants, 250);
        });
        this.controller.set('rendered', true);
      });
    });
  },
  // Turn static links into ember transition links
  activateLinks: function() {
    var route = this;
    // TODO: Get a elements directly
    Ember.$('.metadata').find('a').click( function(e) {
      e.preventDefault();
      var letterID = Ember.$(this).attr('href');
      route.transitionTo('letter', letterID);
    });
  },
  loadSVG: function(id) {
    return new Ember.RSVP.Promise( function(resolve) {
      Ember.$.ajax({
        url: config.solrURL,
        data: {
          wt: 'json',
          q: `id:${id}`
        },
        dataType: 'jsonp',
        jsonp: 'json.wrf'
      }).then( function(json) {
        if ( json.response.docs.length > 0 && json.response.docs[0].hasOwnProperty('svg_code')) {
          resolve(json.response.docs[0].svg_code);
        }
      });
    });
  },
  renderMathJax: function() {
    var context = this.context;
    return new Ember.RSVP.Promise( function(resolve) {
      if ( context.volltext ) {
        MathJax.Hub.Queue(['Typeset', MathJax.Hub], () => { // jshint ignore:line
          resolve(true);
        });
      } else {
        resolve(true);
      }
    });
  },
  clearVariantConnectors: function() {
    Ember.$('.content_svg-overlay').remove(); // TODO: Find a more elegant way to re-render SVG
  },
  positionVariants: function() {
    var $ = Ember.$;
    var $laneTranscript = $('.transcript');
    var $references = $laneTranscript.find('.reference.-afootnote, .reference.-cfootnote');

    this.clearVariantConnectors();
    if ( $references.length === 0 ) {
      return;
    }

    var $laneVariants = $('.variants');
    var $variants = $laneVariants.find('.variant').hide();
    var prevVariantBottom = 0;
    var marginBetweenVariants = parseInt( $laneVariants.css('padding') );

    // Using plain JS for SVG since jQuery struggles with namespaces
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('class', 'content_svg-overlay');
    svg.setAttribute('width', $('.content').width());
    svg.setAttribute('height', $('.content').height());
    document.getElementsByClassName('content')[0].appendChild(svg);

    $references.each( function() {
      var $this = $(this);
      var variantID = $this.data('id');
      var $variant = $variants.filter('#' + variantID).show();
      if ( $variant.length === 0 ) {
        return; // variant not available
      }
      var left = $this.position().left;
      var top = $this.position().top;
      var bottom = $this.position().top + $this.outerHeight();
      var variantTop = (top < prevVariantBottom ? prevVariantBottom : top + 10); // TODO: Calucalte this value
      prevVariantBottom = variantTop + $variant.outerHeight() + marginBetweenVariants;
      $variant.css( {top: variantTop} );

      // Draw a curved line from reference to variant
      var path = document.createElementNS(svgNS, 'path');
      path.setAttribute('stroke', '#aaaaaa');
      path.setAttribute('fill', 'none');
      path.setAttribute('style', 'stroke-width: 1px');
      var pathD = `M ${left + 3}, ${bottom - .5}
                   L ${$laneTranscript.width()}, ${bottom - .5}
                   C ${$laneTranscript.width() + 21}, ${bottom - .5},
                     ${$laneTranscript.width() + 21}, ${variantTop + $variant.outerHeight() / 2 - .5},
                     ${$variant.offset().left}, ${variantTop + $variant.outerHeight() / 2 - .5}`;
      path.setAttribute('d', pathD);
      svg.appendChild(path);

      // Add click handler to highlight reference/variant pair
      $this.add($variant).off('click').click( () => {
        $this.add($variant).toggleClass('-highlight');
        return false;
      });

      // NOTE: Cannot use toggleClass because element can be moved under the
      // mouse pointer which does not trigger mouseEnter
      $this.add($variant).off('hover').hover( () => {
        $this.add($variant).addClass('-hover');
      }, () => {
        $this.add($variant).removeClass('-hover');
      });
    });
  }
});

/* global MathJax */
MathJax.Hub.Config({
  extensions: ['tex2jax.js'],
  jax: ['input/TeX', 'output/HTML-CSS'],
  tex2jax: {
    inlineMath: [ ['$', '$'], ['\\(', '\\)'] ],
    displayMath: [ ['$$', '$$'], ['\\[', '\\]'] ],
    processEscapes: true
  },
  'HTML-CSS': {
    availableFonts: ['TeX']
  }
});
<commit_msg>Fix positioning of variants in Firefox<commit_after>// Allow starting numerals with decimal point:
/* jshint -W008 */
import Ember from 'ember';
import config from '../config/environment';

export default Ember.Route.extend({
  actions: {
    beforeResize: function() {
      this.clearVariantConnectors();
    },
    afterResize: function() {
      this.positionVariants();
    }
  },
  model: function(params) {
    return Ember.$.ajax({
      url: config.solrURL,
      data: {
        wt: 'json',
        q: `id:${params.letter_id} or (doc_id:${params.letter_id} and type:variante)`,
        rows: 9999
      },
      dataType: 'jsonp',
      jsonp: 'json.wrf'
    }).then( function(json) {
      var letter = {};
      if ( json.response.docs.length > 0 ) {
        // TODO: Is letter always the first doc in response?
        letter = json.response.docs[0];
        letter.volltext = letter.volltext;
        letter.variants = json.response.docs.slice(1);
        // Determine variant type from ID
        // TODO: Would be nice to use for ( ... of ... ) here, but breaks tests
        letter.variants.forEach( function(variant) {
          var typeHint = variant.id.substr(0, 4);
          switch ( typeHint ) {
            case 'vara':
              variant.type = 'addition';
              break;
            case 'varc':
              variant.type = 'variant';
              break;
          }
        });
      } else {
        letter.id = params.letter_id;
      }

      // NOTE: query-params can only use this string if it is correctly URL-encoded
      letter.viewQuery = params.view;
      try {
        letter.view = Ember.$.parseJSON(params.view);
      } catch (e) {
        letter.view = null;
      }

      return letter;
    });
  },
  renderTemplate: function() {
    this.render({ outlet: 'letter' });
    this.controller.set('rendered', false);
  },
  setupController: function (controller, model) {
    this._super(controller, model);
    controller.set('rendered', true);
  },
  afterModel: function() {
    Ember.run.next( () => {
      this.activateLinks();

      // Convert image references to SVG images
      Ember.$('.transcript').find('.reference.-image').each( (index, ref) => {
        var imageID = Ember.$(ref).data('id');
        this.loadSVG(imageID).then( function(svg) {
          Ember.$(ref).html(svg);
        });
      });

      // Render MathJax, then position variants
      this.renderMathJax().then( () => {
        // TODO: For some reason, resize is always triggered once
        // this.positionVariants();
        Ember.$('.content').resize( () => {
          Ember.run.debounce(this, this.clearVariantConnectors, 250, true);
          Ember.run.debounce(this, this.positionVariants, 250);
        });
        this.controller.set('rendered', true);
      });
    });
  },
  // Turn static links into ember transition links
  activateLinks: function() {
    var route = this;
    // TODO: Get <a> elements directly
    Ember.$('.metadata').find('a').click( function(e) {
      e.preventDefault();
      var letterID = Ember.$(this).attr('href');
      route.transitionTo('letter', letterID);
    });
  },
  loadSVG: function(id) {
    return new Ember.RSVP.Promise( function(resolve) {
      Ember.$.ajax({
        url: config.solrURL,
        data: {
          wt: 'json',
          q: `id:${id}`
        },
        dataType: 'jsonp',
        jsonp: 'json.wrf'
      }).then( function(json) {
        if ( json.response.docs.length > 0 && json.response.docs[0].hasOwnProperty('svg_code')) {
          resolve(json.response.docs[0].svg_code);
        }
      });
    });
  },
  renderMathJax: function() {
    var context = this.context;
    return new Ember.RSVP.Promise( function(resolve) {
      if ( context.volltext ) {
        MathJax.Hub.Queue(['Typeset', MathJax.Hub], () => { // jshint ignore:line
          resolve(true);
        });
      } else {
        resolve(true);
      }
    });
  },
  clearVariantConnectors: function() {
    Ember.$('.content_svg-overlay').remove(); // TODO: Find a more elegant way to re-render SVG
  },
  positionVariants: function() {
    var $ = Ember.$;
    var $laneTranscript = $('.transcript');
    var $references = $laneTranscript.find('.reference.-afootnote, .reference.-cfootnote');

    this.clearVariantConnectors();
    if ( $references.length === 0 ) {
      return;
    }

    var $laneVariants = $('.variants');
    var $variants = $laneVariants.find('.variant').hide();
    var prevVariantBottom = 0;
    // NOTE: Shorthand css properties like `padding` are not supported in Firefox
    var marginBetweenVariants = parseInt( $laneVariants.css('lineHeight') ) / 2;

    // Using plain JS for SVG since jQuery struggles with namespaces
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('class', 'content_svg-overlay');
    svg.setAttribute('width', $('.content').width());
    svg.setAttribute('height', $('.content').height());
    document.getElementsByClassName('content')[0].appendChild(svg);

    $references.each( function() {
      var $this = $(this);
      var variantID = $this.data('id');
      var $variant = $variants.filter('#' + variantID).show();
      if ( $variant.length === 0 ) {
        return; // variant not available
      }
      var left = $this.position().left;
      var top = $this.position().top;
      var bottom = $this.position().top + $this.outerHeight();

      var variantTop = (top < prevVariantBottom ? prevVariantBottom : top);
      prevVariantBottom = variantTop + $variant.outerHeight() + marginBetweenVariants;
      $variant.css( {top: variantTop} );

      // Draw a curved line from reference to variant
      var path = document.createElementNS(svgNS, 'path');
      path.setAttribute('stroke', '#aaaaaa');
      path.setAttribute('fill', 'none');
      path.setAttribute('style', 'stroke-width: 1px');
      var pathD = `M ${left + 3}, ${bottom - .5}
                   L ${$laneTranscript.width()}, ${bottom - .5}
                   C ${$laneTranscript.width() + 21}, ${bottom - .5},
                     ${$laneTranscript.width() + 21}, ${variantTop + $variant.outerHeight() / 2 - .5},
                     ${$variant.offset().left}, ${variantTop + $variant.outerHeight() / 2 - .5}`;
      path.setAttribute('d', pathD);
      svg.appendChild(path);

      // Add click handler to highlight reference/variant pair
      $this.add($variant).off('click').click( () => {
        $this.add($variant).toggleClass('-highlight');
        return false;
      });

      // NOTE: Cannot use toggleClass because element can be moved under the
      // mouse pointer which does not trigger mouseEnter
      $this.add($variant).off('hover').hover( () => {
        $this.add($variant).addClass('-hover');
      }, () => {
        $this.add($variant).removeClass('-hover');
      });
    });
  }
});

/* global MathJax */
MathJax.Hub.Config({
  extensions: ['tex2jax.js'],
  jax: ['input/TeX', 'output/HTML-CSS'],
  tex2jax: {
    inlineMath: [ ['$', '$'], ['\\(', '\\)'] ],
    displayMath: [ ['$$', '$$'], ['\\[', '\\]'] ],
    processEscapes: true
  },
  'HTML-CSS': {
    availableFonts: ['TeX']
  }
});
<|endoftext|>


<commit_before>
function Route(sourceAddress, destinationAddress, deployRate = 1) {
  this.sourceAddress = sourceAddress;
  this.destinationAddress = destinationAddress;
  this.deployRate = deployRate;

  this.sendCount = 0;
  this.receivedCount = 0;
  this.receivedStepCount = 0;
  this.transitCount = 0;
  this.efficiency = NaN;

  this.reset = function reset() {
    this.sendCount = 0;
    this.receivedCount = 0;
    this.receivedStepCount = 0;
    this.transitCount = 0;
    this.efficiency = NaN;
  }
}

function createSim(graph) {
  var self = {};

  // Number of steps the simulation has run
  self.simStep = 0;

  // Duration of the last simulation run
  self.simDuration = 0;

  // Routes to deploy packet on
  self.routes = {};

  // Keep track of setTimeout id
  self.timerId = null;

  // Simulation state
  self.running = false;

  function shuffleArray(a) {
    for (let i = a.length; i; i--) {
      let j = Math.floor(Math.random() * i);
      [a[i - 1], a[j]] = [a[j], a[i - 1]];
    }
  }

  self.reset = function reset() {
    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();

    for (var i = 0; i < intLinks.length; i++) {
      intLinks[i].o.reset();
    }

    for (var i = 0; i < intNodes.length; i++) {
      intNodes[i].o.reset();
    }

    self.simStep = 0;
    self.simDuration = 0;

    self.clearRouteCounter();

    graph.redraw();
  }

  function num(v, suffix = '') {
    if (isNaN(v)) return '-';
    if (v === 100) return "100%";
    return (v.toFixed(1) + suffix);
  }

  function updateSimStatistics() {
    var packets_unicast = 0;
    var packets_broadcast = 0;

    for (var id in self.routes) {
      self.routes[id].transitCount = 0;
    }

    function countPackets(node, packets) {
      for (var j = 0; j < packets.length; j += 1) {
        var packet = packets[j];
        if ('deployedAtStep' in packet) {
          var id = packet.sourceAddress + '=>' + packet.destinationAddress;
          if (id in self.routes && packet.destinationAddress !== node.mac) {
            self.routes[id].transitCount += 1;
          }
        } else {
          var isBroadcast = (packet.receiverAddress === BROADCAST_MAC);
          packets_unicast += !isBroadcast;
          packets_broadcast += isBroadcast;
        }
      }
    }

    var intNodes = graph.getIntNodes();
    for (var i = 0; i < intNodes.length; i += 1) {
      var node = intNodes[i].o;
      countPackets(node, node.incoming);
      countPackets(node, node.outgoing);
    }

    var routesSend = 0;
    var routesReceived = 0;
    var routesLost = 0;
    var routesTransit = 0;
    var routesCount = 0;
    var routesEfficiencySum = 0;
    var routesEfficiencyCount = 0;

    for (var id in self.routes) {
      var route = self.routes[id];
      routesCount += 1;
      routesSend += route.sendCount;
      routesReceived += route.receivedCount;
      routesTransit += route.transitCount;

      if (!isNaN(route.efficiency)) {
        routesEfficiencySum += route.efficiency;
        routesEfficiencyCount += 1;
      }
    }

    // Convert to medium percent
    var routingEfficiencyPercent = 100 * routesEfficiencySum / routesEfficiencyCount;

    function withPercent(val, all) {
      if (isNaN(all) || isNaN(val)) {
        return '-';
      }
      var ret = '' + val;
      if (all !== 0) {
        ret += ' (' + (100 * val / all).toFixed(1) + '%)';
      }
      return ret;
    };

    $$('sim_steps_total').nodeValue = self.simStep;
    $$('sim_duration').nodeValue = self.simDuration + ' ms';

    $$('packets_broadcast').nodeValue = withPercent(packets_broadcast, packets_unicast + packets_broadcast);
    $$('packets_unicast').nodeValue = withPercent(packets_unicast, packets_unicast + packets_broadcast);
    $$('packets_per_node').nodeValue = intNodes.length ? ((packets_unicast + packets_broadcast) / intNodes.length).toFixed(2) : '-';

    $$('routes_count').nodeValue = routesCount;
    $$('routes_packets_send').nodeValue = routesSend;
    $$('routes_packets_received').nodeValue = withPercent(routesReceived, routesSend);
    $$('routes_packets_transit').nodeValue = withPercent(routesTransit, routesSend);
    $$('routes_packets_lost').nodeValue = withPercent(routesSend - routesReceived - routesTransit, routesSend);
    $$('routing_efficiency').nodeValue = num(routingEfficiencyPercent, '%');

    updateRoutesTable();
  }

  function updateRoutesTable() {
    var tbody = $('sim_routes');

    // Remove all elements
    clearChildren(tbody);

    for (key in self.routes) {
      var route = self.routes[key];
      var tr = append(tbody, 'tr');
      var source_td = append(tr, 'td', route.sourceAddress.slice(-5));
      var target_td = append(tr, 'td', route.destinationAddress.slice(-5));
      append(tr, 'td', route.deployRate);
      append(tr, 'td', route.sendCount);
      append(tr, 'td', num(100 * route.receivedCount / route.sendCount, '%'));
      append(tr, 'td', num(100 * route.transitCount / route.sendCount, '%'));
      append(tr, 'td', num(100 * (route.sendCount - route.receivedCount - route.transitCount) / route.sendCount, '%'));
      append(tr, 'td', num(100 * route.efficiency, '%'));

      // Hover text
      source_td.title = route.sourceAddress
      target_td.title = route.destinationAddress;
    }

    var display = (tbody.children.length === 0);
    displayElement($('sim_no_routes'), display);
  }

  self.delRoutes = function delRoutes() {
    function delRoute(sourceNode, targetNode) {
      var id = sourceNode.mac + '=>' + targetNode.mac;
      delete routes[id];
    }

    var intNodes = graph.getSelectedIntNodes();
    if (intNodes.length == 0) {
      alert('Select one source and at least one target node.');
      return;
    }

    var sourceNode = intNodes[0].o;
    for (var i = 1; i < intNodes.length; i += 1) {
      var targetNode = intNodes[i].o;
      delRoute(sourceNode, targetNode);
    }

    updateSimStatistics();
  }

  self.addRoutes = function addRoutes() {
    function addRoute(sourceAddress, destinationAddress) {
      var id = sourceAddress + '=>' + destinationAddress;
      if (!(id in self.routes)) {
        self.routes[id] = new Route(sourceAddress, destinationAddress, 1);
      }
    }

    var intNodes = graph.getSelectedIntNodes();
    if (intNodes.length == 0) {
      alert('Select one source and at least one target node.');
      return;
    }

    var sourceAddress = intNodes[0].o.mac;
    for (var i = 1; i < intNodes.length; i += 1) {
      var destinationAddress = intNodes[i].o.mac;
      addRoute(sourceAddress, destinationAddress);
    }

    updateSimStatistics();
  }

  function deployPackets_() {
    var nodes = graph.getIntNodes();
    var nodeMap = {};

    nodes.forEach(function(e) {
      nodeMap[e.o.mac] = e.o;
    });

    for (var id in self.routes) {
      var route = self.routes[id];
      if (randomBoolean(route.deployRate)) {
        var src = route.sourceAddress;
        var dst = route.destinationAddress;
        if (src in nodeMap && dst in nodeMap) {
          var packet = new Packet(src, src, src, dst);
          // For route efficiency calculation
          packet.deployedAtStep = self.simStep;
          nodeMap[src].incoming.push(packet);
          route.sendCount += 1;
        } else {
          console.log('Route does not exists: ' + src  + ' => ' + dst);
        }
      }
    }
  }

  self.deployPackets = function deployPackets() {
    if (isEmpty(self.routes)) {
      alert('No routes set on which to deploy packets.');
      return;
    }

    deployPackets_();
    updateSimStatistics();

    graph.redraw();
  }

  function updateRoutesEfficiency() {
    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();
    var dijkstra = createDijkstra(intNodes, intLinks);

    for (var id in self.routes) {
      var route = self.routes[id];
      var sourceIntNode = intNodes.find(function(e) { return e.o.mac === route.sourceAddress; });
      var targetIntNode = intNodes.find(function(e) { return e.o.mac === route.destinationAddress; });
      var shortestDistance = dijkstra.getShortestDistance(sourceIntNode, targetIntNode);
      /*
      * Efficiency as rate of optimal step count in relation to the shortest path of reveived packets.
      */
      route.efficiency = (shortestDistance * route.receivedCount / route.receivedStepCount);
    }
  }

  function packetOnRouteReceived(packet) {
    var id = packet.sourceAddress + '=>' + packet.destinationAddress;
    if (id in self.routes) {
      var route = self.routes[id];
      route.receivedCount += 1;
      route.receivedStepCount += (self.simStep - packet.deployedAtStep);
    }
  }

  self.clearRouteCounter = function clearRouteCounter() {
    for (var id in self.routes) {
      self.routes[id].reset();
    }

    updateSimStatistics();
  }

  self.start = function start(steps, delay, deployPacketsEnabled) {
    function trigger(steps, delay, deployPacketsEnabled) {
      if (steps > 0) {
        self.run(1, deployPacketsEnabled);
        self.timerId = setTimeout(trigger, delay, steps - 1, delay, deployPacketsEnabled);
      } else {
        self.timerId = null;
      }
    }

    if (self.timerId) {
      clearTimeout(self.timerId);
      self.timerId = null;
      return;
    }

    if (!this.running) {
      if (delay > 0) {
        trigger(steps, delay, deployPacketsEnabled);
      } else {
        self.run(steps, deployPacketsEnabled);
      }
    } else {
      alert('Simulation is still running.');
    }
  }

  self.run = function run(steps, deployPacketsEnabled) {
    this.running = true;

    // All links are bidirectional
    function getOtherIntNode(intLink, mac) {
      return (mac === intLink.target.o.mac) ? intLink.source : intLink.target;
    }

    function clonePacket(packet) {
      return JSON.parse(JSON.stringify(packet));
    }

    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();

    // Map of internal node index to array of d3 link objects
    var connections = {};

    for (var i = 0; i < intNodes.length; i += 1) {
      var n = intNodes[i];
      connections[n.index] = [];
    }

    for (var i = 0; i < intLinks.length; i += 1) {
      var l = intLinks[i];
      connections[l.source.index].push(l);
      connections[l.target.index].push(l);
    }

    var simStartTime = (new Date()).getTime();

    // Cumulated packet count for each link
    var packetCount = {};

    // Simulation steps
    for (var step = 0; step < steps; step += 1) {
      self.simStep += 1;

      // Initialize packet count
      for (var i = 0; i < intLinks.length; i++) {
        var intLink = intLinks[i];
        packetCount[intLink.index] = 0;
      }

      // Randomize order
      shuffleArray(intNodes);

      // Step nodes
      for (var i = 0; i < intNodes.length; i++) {
        var node = intNodes[i].o;
        node.step();
        node.incoming = [];
      }

      // Propagate packets
      for (var i = 0; i < intNodes.length; i++) {
        var intNode = intNodes[i];
        var intLinks = connections[intNode.index];

        // Randomize order
        shuffleArray(intLinks);

        for (var p = 0; p < intNode.o.outgoing.length; p++) {
          var packet = intNode.o.outgoing[p];
          var isBroadcast = (packet.receiverAddress === BROADCAST_MAC);

          for (var j = 0; j < intLinks.length; j++) {
            var intLink = intLinks[j];
            var otherIntNode = getOtherIntNode(intLink, intNode.o.mac);

            if (isBroadcast || (packet.receiverAddress === otherIntNode.o.mac)) {
              if (isBroadcast) {
                // Necessary for broadcast
                packet = clonePacket(packet);
              }

              // Update count per node and channel to
              // simulate a shared transmission medium
              if (intLink.o.channel > 0) {
                intLinks.forEach(function(l) {
                  if (l.o.channel === intLink.o.channel) {
                    packetCount[l.index] += 1;
                  }
                });
              } else {
                packetCount[intLink.index] += 1;
              }

              if (intLink.o.transmit(packet, packetCount[intLink.index])) {
                // Packet transmitted
                otherIntNode.o.incoming.push(packet);
                if ('deployedAtStep' in packet) {
                  if (packet.destinationAddress === otherIntNode.o.mac) {
                    packetOnRouteReceived(packet);
                  }
                }
              }

              if (!isBroadcast) {
                break;
              }
            }
          }
        }

        // All packets should have been handled
        intNode.o.outgoing = [];
      }

      if (deployPacketsEnabled) {
        deployPackets_();
      }
    }

    self.simDuration = (new Date()).getTime() - simStartTime;

    updateRoutesEfficiency();
    updateSimStatistics();

    graph.redraw();

    this.running = false;
  }

  return self;
}
<commit_msg>fix selected nodes check for adding routes<commit_after>
function Route(sourceAddress, destinationAddress, deployRate = 1) {
  this.sourceAddress = sourceAddress;
  this.destinationAddress = destinationAddress;
  this.deployRate = deployRate;

  this.sendCount = 0;
  this.receivedCount = 0;
  this.receivedStepCount = 0;
  this.transitCount = 0;
  this.efficiency = NaN;

  this.reset = function reset() {
    this.sendCount = 0;
    this.receivedCount = 0;
    this.receivedStepCount = 0;
    this.transitCount = 0;
    this.efficiency = NaN;
  }
}

function createSim(graph) {
  var self = {};

  // Number of steps the simulation has run
  self.simStep = 0;

  // Duration of the last simulation run
  self.simDuration = 0;

  // Routes to deploy packet on
  self.routes = {};

  // Keep track of setTimeout id
  self.timerId = null;

  // Simulation state
  self.running = false;

  function shuffleArray(a) {
    for (let i = a.length; i; i--) {
      let j = Math.floor(Math.random() * i);
      [a[i - 1], a[j]] = [a[j], a[i - 1]];
    }
  }

  self.reset = function reset() {
    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();

    for (var i = 0; i < intLinks.length; i++) {
      intLinks[i].o.reset();
    }

    for (var i = 0; i < intNodes.length; i++) {
      intNodes[i].o.reset();
    }

    self.simStep = 0;
    self.simDuration = 0;

    self.clearRouteCounter();

    graph.redraw();
  }

  function num(v, suffix = '') {
    if (isNaN(v)) return '-';
    if (v === 100) return "100%";
    return (v.toFixed(1) + suffix);
  }

  function updateSimStatistics() {
    var packets_unicast = 0;
    var packets_broadcast = 0;

    for (var id in self.routes) {
      self.routes[id].transitCount = 0;
    }

    function countPackets(node, packets) {
      for (var j = 0; j < packets.length; j += 1) {
        var packet = packets[j];
        if ('deployedAtStep' in packet) {
          var id = packet.sourceAddress + '=>' + packet.destinationAddress;
          if (id in self.routes && packet.destinationAddress !== node.mac) {
            self.routes[id].transitCount += 1;
          }
        } else {
          var isBroadcast = (packet.receiverAddress === BROADCAST_MAC);
          packets_unicast += !isBroadcast;
          packets_broadcast += isBroadcast;
        }
      }
    }

    var intNodes = graph.getIntNodes();
    for (var i = 0; i < intNodes.length; i += 1) {
      var node = intNodes[i].o;
      countPackets(node, node.incoming);
      countPackets(node, node.outgoing);
    }

    var routesSend = 0;
    var routesReceived = 0;
    var routesLost = 0;
    var routesTransit = 0;
    var routesCount = 0;
    var routesEfficiencySum = 0;
    var routesEfficiencyCount = 0;

    for (var id in self.routes) {
      var route = self.routes[id];
      routesCount += 1;
      routesSend += route.sendCount;
      routesReceived += route.receivedCount;
      routesTransit += route.transitCount;

      if (!isNaN(route.efficiency)) {
        routesEfficiencySum += route.efficiency;
        routesEfficiencyCount += 1;
      }
    }

    // Convert to medium percent
    var routingEfficiencyPercent = 100 * routesEfficiencySum / routesEfficiencyCount;

    function withPercent(val, all) {
      if (isNaN(all) || isNaN(val)) {
        return '-';
      }
      var ret = '' + val;
      if (all !== 0) {
        ret += ' (' + (100 * val / all).toFixed(1) + '%)';
      }
      return ret;
    };

    $$('sim_steps_total').nodeValue = self.simStep;
    $$('sim_duration').nodeValue = self.simDuration + ' ms';

    $$('packets_broadcast').nodeValue = withPercent(packets_broadcast, packets_unicast + packets_broadcast);
    $$('packets_unicast').nodeValue = withPercent(packets_unicast, packets_unicast + packets_broadcast);
    $$('packets_per_node').nodeValue = intNodes.length ? ((packets_unicast + packets_broadcast) / intNodes.length).toFixed(2) : '-';

    $$('routes_count').nodeValue = routesCount;
    $$('routes_packets_send').nodeValue = routesSend;
    $$('routes_packets_received').nodeValue = withPercent(routesReceived, routesSend);
    $$('routes_packets_transit').nodeValue = withPercent(routesTransit, routesSend);
    $$('routes_packets_lost').nodeValue = withPercent(routesSend - routesReceived - routesTransit, routesSend);
    $$('routing_efficiency').nodeValue = num(routingEfficiencyPercent, '%');

    updateRoutesTable();
  }

  function updateRoutesTable() {
    var tbody = $('sim_routes');

    // Remove all elements
    clearChildren(tbody);

    for (key in self.routes) {
      var route = self.routes[key];
      var tr = append(tbody, 'tr');
      var source_td = append(tr, 'td', route.sourceAddress.slice(-5));
      var target_td = append(tr, 'td', route.destinationAddress.slice(-5));
      append(tr, 'td', route.deployRate);
      append(tr, 'td', route.sendCount);
      append(tr, 'td', num(100 * route.receivedCount / route.sendCount, '%'));
      append(tr, 'td', num(100 * route.transitCount / route.sendCount, '%'));
      append(tr, 'td', num(100 * (route.sendCount - route.receivedCount - route.transitCount) / route.sendCount, '%'));
      append(tr, 'td', num(100 * route.efficiency, '%'));

      // Hover text
      source_td.title = route.sourceAddress
      target_td.title = route.destinationAddress;
    }

    var display = (tbody.children.length === 0);
    displayElement($('sim_no_routes'), display);
  }

  self.delRoutes = function delRoutes() {
    function delRoute(sourceNode, targetNode) {
      var id = sourceNode.mac + '=>' + targetNode.mac;
      delete routes[id];
    }

    var intNodes = graph.getSelectedIntNodes();
    if (intNodes.length == 0) {
      alert('Select one source and at least one target node.');
      return;
    }

    var sourceNode = intNodes[0].o;
    for (var i = 1; i < intNodes.length; i += 1) {
      var targetNode = intNodes[i].o;
      delRoute(sourceNode, targetNode);
    }

    updateSimStatistics();
  }

  self.addRoutes = function addRoutes() {
    function addRoute(sourceAddress, destinationAddress) {
      var id = sourceAddress + '=>' + destinationAddress;
      if (!(id in self.routes)) {
        self.routes[id] = new Route(sourceAddress, destinationAddress, 1);
      }
    }

    var intNodes = graph.getSelectedIntNodes();
    if (intNodes.length < 2) {
      alert('Select one source and at least one target node.');
      return;
    }

    var sourceAddress = intNodes[0].o.mac;
    for (var i = 1; i < intNodes.length; i += 1) {
      var destinationAddress = intNodes[i].o.mac;
      addRoute(sourceAddress, destinationAddress);
    }

    updateSimStatistics();
  }

  function deployPackets_() {
    var nodes = graph.getIntNodes();
    var nodeMap = {};

    nodes.forEach(function(e) {
      nodeMap[e.o.mac] = e.o;
    });

    for (var id in self.routes) {
      var route = self.routes[id];
      if (randomBoolean(route.deployRate)) {
        var src = route.sourceAddress;
        var dst = route.destinationAddress;
        if (src in nodeMap && dst in nodeMap) {
          var packet = new Packet(src, src, src, dst);
          // For route efficiency calculation
          packet.deployedAtStep = self.simStep;
          nodeMap[src].incoming.push(packet);
          route.sendCount += 1;
        } else {
          console.log('Route does not exists: ' + src  + ' => ' + dst);
        }
      }
    }
  }

  self.deployPackets = function deployPackets() {
    if (isEmpty(self.routes)) {
      alert('No routes set on which to deploy packets.');
      return;
    }

    deployPackets_();
    updateSimStatistics();

    graph.redraw();
  }

  function updateRoutesEfficiency() {
    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();
    var dijkstra = createDijkstra(intNodes, intLinks);

    for (var id in self.routes) {
      var route = self.routes[id];
      var sourceIntNode = intNodes.find(function(e) { return e.o.mac === route.sourceAddress; });
      var targetIntNode = intNodes.find(function(e) { return e.o.mac === route.destinationAddress; });
      var shortestDistance = dijkstra.getShortestDistance(sourceIntNode, targetIntNode);
      /*
      * Efficiency as rate of optimal step count in relation to the shortest path of reveived packets.
      */
      route.efficiency = (shortestDistance * route.receivedCount / route.receivedStepCount);
    }
  }

  function packetOnRouteReceived(packet) {
    var id = packet.sourceAddress + '=>' + packet.destinationAddress;
    if (id in self.routes) {
      var route = self.routes[id];
      route.receivedCount += 1;
      route.receivedStepCount += (self.simStep - packet.deployedAtStep);
    }
  }

  self.clearRouteCounter = function clearRouteCounter() {
    for (var id in self.routes) {
      self.routes[id].reset();
    }

    updateSimStatistics();
  }

  self.start = function start(steps, delay, deployPacketsEnabled) {
    function trigger(steps, delay, deployPacketsEnabled) {
      if (steps > 0) {
        self.run(1, deployPacketsEnabled);
        self.timerId = setTimeout(trigger, delay, steps - 1, delay, deployPacketsEnabled);
      } else {
        self.timerId = null;
      }
    }

    if (self.timerId) {
      clearTimeout(self.timerId);
      self.timerId = null;
      return;
    }

    if (!this.running) {
      if (delay > 0) {
        trigger(steps, delay, deployPacketsEnabled);
      } else {
        self.run(steps, deployPacketsEnabled);
      }
    } else {
      alert('Simulation is still running.');
    }
  }

  self.run = function run(steps, deployPacketsEnabled) {
    this.running = true;

    // All links are bidirectional
    function getOtherIntNode(intLink, mac) {
      return (mac === intLink.target.o.mac) ? intLink.source : intLink.target;
    }

    function clonePacket(packet) {
      return JSON.parse(JSON.stringify(packet));
    }

    var intNodes = graph.getIntNodes();
    var intLinks = graph.getIntLinks();

    // Map of internal node index to array of d3 link objects
    var connections = {};

    for (var i = 0; i < intNodes.length; i += 1) {
      var n = intNodes[i];
      connections[n.index] = [];
    }

    for (var i = 0; i < intLinks.length; i += 1) {
      var l = intLinks[i];
      connections[l.source.index].push(l);
      connections[l.target.index].push(l);
    }

    var simStartTime = (new Date()).getTime();

    // Cumulated packet count for each link
    var packetCount = {};

    // Simulation steps
    for (var step = 0; step < steps; step += 1) {
      self.simStep += 1;

      // Initialize packet count
      for (var i = 0; i < intLinks.length; i++) {
        var intLink = intLinks[i];
        packetCount[intLink.index] = 0;
      }

      // Randomize order
      shuffleArray(intNodes);

      // Step nodes
      for (var i = 0; i < intNodes.length; i++) {
        var node = intNodes[i].o;
        node.step();
        node.incoming = [];
      }

      // Propagate packets
      for (var i = 0; i < intNodes.length; i++) {
        var intNode = intNodes[i];
        var intLinks = connections[intNode.index];

        // Randomize order
        shuffleArray(intLinks);

        for (var p = 0; p < intNode.o.outgoing.length; p++) {
          var packet = intNode.o.outgoing[p];
          var isBroadcast = (packet.receiverAddress === BROADCAST_MAC);

          for (var j = 0; j < intLinks.length; j++) {
            var intLink = intLinks[j];
            var otherIntNode = getOtherIntNode(intLink, intNode.o.mac);

            if (isBroadcast || (packet.receiverAddress === otherIntNode.o.mac)) {
              if (isBroadcast) {
                // Necessary for broadcast
                packet = clonePacket(packet);
              }

              // Update count per node and channel to
              // simulate a shared transmission medium
              if (intLink.o.channel > 0) {
                intLinks.forEach(function(l) {
                  if (l.o.channel === intLink.o.channel) {
                    packetCount[l.index] += 1;
                  }
                });
              } else {
                packetCount[intLink.index] += 1;
              }

              if (intLink.o.transmit(packet, packetCount[intLink.index])) {
                // Packet transmitted
                otherIntNode.o.incoming.push(packet);
                if ('deployedAtStep' in packet) {
                  if (packet.destinationAddress === otherIntNode.o.mac) {
                    packetOnRouteReceived(packet);
                  }
                }
              }

              if (!isBroadcast) {
                break;
              }
            }
          }
        }

        // All packets should have been handled
        intNode.o.outgoing = [];
      }

      if (deployPacketsEnabled) {
        deployPackets_();
      }
    }

    self.simDuration = (new Date()).getTime() - simStartTime;

    updateRoutesEfficiency();
    updateSimStatistics();

    graph.redraw();

    this.running = false;
  }

  return self;
}
<|endoftext|>


<commit_before>import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';

import { Users } from '../../../models';
import { Notifications } from '../../../notifications';
import { hasPermission } from '../../../authorization';
import { RateLimiter } from '../lib';

// mirror of object in /imports/startup/client/listenActiveUsers.js - keep updated
const STATUS_MAP = {
	offline: 0,
	online: 1,
	away: 2,
	busy: 3,
};

export const _setStatusText = function(userId, statusText) {
	statusText = s.trim(statusText);
	if (statusText.length > 120) {
		statusText = statusText.substr(0, 120);
	}

	if (!userId) {
		return false;
	}

	const user = Users.findOneById(userId);

	// User already has desired statusText, return
	if (user.statusText === statusText) {
		return user;
	}

	// Set new statusText
	Users.updateStatusText(user._id, statusText);
	user.statusText = statusText;

	Notifications.notifyLogged('user-status', [
		user._id,
		user.username,
		STATUS_MAP[user.status],
		statusText,
	]);

	return true;
};

export const setStatusText = RateLimiter.limitFunction(_setStatusText, 1, 60000, {
	0() {
		// Administrators have permission to change others status, so don't limit those
		return !Meteor.userId() || !hasPermission(Meteor.userId(), 'edit-other-user-info');
	},
});
<commit_msg>[FIX] Custom User Status throttled by rate limiter (#15001)<commit_after>import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';

import { Users } from '../../../models';
import { Notifications } from '../../../notifications';
import { hasPermission } from '../../../authorization';
import { RateLimiter } from '../lib';

// mirror of object in /imports/startup/client/listenActiveUsers.js - keep updated
const STATUS_MAP = {
	offline: 0,
	online: 1,
	away: 2,
	busy: 3,
};

export const _setStatusText = function(userId, statusText) {
	statusText = s.trim(statusText);
	if (statusText.length > 120) {
		statusText = statusText.substr(0, 120);
	}

	if (!userId) {
		return false;
	}

	const user = Users.findOneById(userId);

	// User already has desired statusText, return
	if (user.statusText === statusText) {
		return user;
	}

	// Set new statusText
	Users.updateStatusText(user._id, statusText);
	user.statusText = statusText;

	Notifications.notifyLogged('user-status', [
		user._id,
		user.username,
		STATUS_MAP[user.status],
		statusText,
	]);

	return true;
};

export const setStatusText = RateLimiter.limitFunction(_setStatusText, 5, 60000, {
	0() {
		// Administrators have permission to change others status, so don't limit those
		return !Meteor.userId() || !hasPermission(Meteor.userId(), 'edit-other-user-info');
	},
});
<|endoftext|>


<commit_before>'use strict';

(function($, window) {
  var ACTION_ASSET_DOWNLOAD_SHOW = '[data-action="asset-download-show"]';
  var ACTION_ASSET_ZOOMABLE = '.asset-image--zoomable';
  var ACTION_BIG_IMAGE_TOGGLE = '[data-action="asset-image-size-toggle"]:not(.dimmed)';
  var ACTION_BIG_IMAGE_DISABLED = '[data-action="asset-image-size-toggle"].dimmed';
  var CONTENT_ASSET_DOWNLOAD = '[data-content="asset-download"]';
  var CONTENT_ASSET_NO_ZOOM = '.no-zoom-message';
  var CONTENT_BIG_IMG_CLASS = 'big-image';
  var CONTENT_SLIDER = '.slider';
  var OVERLAY_ACTIVE_CLASS = 'overlay__container--active';
  var OVERLAY_ANIM_IN_CLASS = 'overlay__container--anim-in';

  var AssetPage = {
    init: function() {
      $(ACTION_ASSET_DOWNLOAD_SHOW)
        .on('click', this.actionAssetDownloadShow.bind(this, true));
      $(CONTENT_ASSET_DOWNLOAD)
        .on('click', this.actionAssetDownloadShow.bind(this, false));
      $(ACTION_BIG_IMAGE_DISABLED)
        .on('click', this.actionAssetNoZoom.bind(this, true));
      $(CONTENT_ASSET_NO_ZOOM)
        .on('click', this.actionAssetNoZoom.bind(this, false));
      $(ACTION_ASSET_ZOOMABLE)
        .on('click', this.toggleBigImage.bind(this));
      $(ACTION_BIG_IMAGE_TOGGLE)
        .on('click', this.toggleBigImage.bind(this));
      $(ACTION_ASSET_ZOOMABLE).each(function(){
        $(this).attr('src', $(this).data('src'));
      });

      if ($(CONTENT_SLIDER).size() > 0) {
        $(CONTENT_SLIDER).slick({
          lazyLoad: 'progressive',
          infinite: true,
          speed: 300,
          slidesToShow: 6,
          slidesToScroll: 6,
          prevArrow: '.related-assets__prev-arrow',
          nextArrow: '.related-assets__next-arrow',

          responsive: [{
            breakpoint: 768,
            settings: {
              slidesToShow: 4,
              slidesToScroll: 4,
            }
          }, {
            breakpoint: 480,
            settings: {
              slidesToShow: 3,
              slidesToScroll: 3
            }
          }]
        });
      }
    },

    actionAssetDownloadShow: function(show) {
      var $el = $(CONTENT_ASSET_DOWNLOAD);
      if (show === true) {
        $el.addClass(OVERLAY_ACTIVE_CLASS);
        $el.addClass(OVERLAY_ANIM_IN_CLASS);
      } else if (show === false) {
        $el.removeClass(OVERLAY_ANIM_IN_CLASS);
        setTimeout(function() {
          $el.removeClass(OVERLAY_ACTIVE_CLASS);
        }, 300);
      }
    },

    actionAssetNoZoom: function(show) {
      var $el = $(CONTENT_ASSET_NO_ZOOM);
      if (show === true) {
        $el.addClass(OVERLAY_ACTIVE_CLASS);
        $el.addClass(OVERLAY_ANIM_IN_CLASS);
      } else if (show === false) {
        $el.removeClass(OVERLAY_ANIM_IN_CLASS);
        setTimeout(function() {
          $el.removeClass(OVERLAY_ACTIVE_CLASS);
        }, 300);
      }
    },

    toggleBigImage: function() {
      var $use = $(ACTION_BIG_IMAGE_TOGGLE).find('use');
      $(ACTION_ASSET_ZOOMABLE).closest('.container-fluid')
        .toggleClass(CONTENT_BIG_IMG_CLASS);
      if ($use.attr('xlink:href') === '#icon-zoom-in') {
        $use.attr('xlink:href', '#icon-zoom-out');
      } else {
        $use.attr('xlink:href', '#icon-zoom-in');
      }
    }
  };

  window.AssetPage = AssetPage;

})(jQuery, window);
<commit_msg>add zoom class to asset top instead<commit_after>'use strict';

(function($, window) {
  var ACTION_ASSET_DOWNLOAD_SHOW = '[data-action="asset-download-show"]';
  var ACTION_ASSET_ZOOMABLE = '.asset-image--zoomable';
  var ACTION_BIG_IMAGE_TOGGLE = '[data-action="asset-image-size-toggle"]:not(.dimmed)';
  var ACTION_BIG_IMAGE_DISABLED = '[data-action="asset-image-size-toggle"].dimmed';
  var CONTENT_ASSET_TOP = '.asset-top';
  var CONTENT_ASSET_DOWNLOAD = '[data-content="asset-download"]';
  var CONTENT_ASSET_NO_ZOOM = '.no-zoom-message';
  var CONTENT_BIG_IMG_CLASS = 'big-image';
  var CONTENT_SLIDER = '.slider';
  var OVERLAY_ACTIVE_CLASS = 'overlay__container--active';
  var OVERLAY_ANIM_IN_CLASS = 'overlay__container--anim-in';

  var AssetPage = {
    init: function() {
      $(ACTION_ASSET_DOWNLOAD_SHOW)
        .on('click', this.actionAssetDownloadShow.bind(this, true));
      $(CONTENT_ASSET_DOWNLOAD)
        .on('click', this.actionAssetDownloadShow.bind(this, false));
      $(ACTION_BIG_IMAGE_DISABLED)
        .on('click', this.actionAssetNoZoom.bind(this, true));
      $(CONTENT_ASSET_NO_ZOOM)
        .on('click', this.actionAssetNoZoom.bind(this, false));
      $(ACTION_ASSET_ZOOMABLE)
        .on('click', this.toggleBigImage.bind(this));
      $(ACTION_BIG_IMAGE_TOGGLE)
        .on('click', this.toggleBigImage.bind(this));
      $(ACTION_ASSET_ZOOMABLE).each(function(){
        $(this).attr('src', $(this).data('src'));
      });

      if ($(CONTENT_SLIDER).size() > 0) {
        $(CONTENT_SLIDER).slick({
          lazyLoad: 'progressive',
          infinite: true,
          speed: 300,
          slidesToShow: 6,
          slidesToScroll: 6,
          prevArrow: '.related-assets__prev-arrow',
          nextArrow: '.related-assets__next-arrow',

          responsive: [{
            breakpoint: 768,
            settings: {
              slidesToShow: 4,
              slidesToScroll: 4,
            }
          }, {
            breakpoint: 480,
            settings: {
              slidesToShow: 3,
              slidesToScroll: 3
            }
          }]
        });
      }
    },

    actionAssetDownloadShow: function(show) {
      var $el = $(CONTENT_ASSET_DOWNLOAD);
      if (show === true) {
        $el.addClass(OVERLAY_ACTIVE_CLASS);
        $el.addClass(OVERLAY_ANIM_IN_CLASS);
      } else if (show === false) {
        $el.removeClass(OVERLAY_ANIM_IN_CLASS);
        setTimeout(function() {
          $el.removeClass(OVERLAY_ACTIVE_CLASS);
        }, 300);
      }
    },

    actionAssetNoZoom: function(show) {
      var $el = $(CONTENT_ASSET_NO_ZOOM);
      if (show === true) {
        $el.addClass(OVERLAY_ACTIVE_CLASS);
        $el.addClass(OVERLAY_ANIM_IN_CLASS);
      } else if (show === false) {
        $el.removeClass(OVERLAY_ANIM_IN_CLASS);
        setTimeout(function() {
          $el.removeClass(OVERLAY_ACTIVE_CLASS);
        }, 300);
      }
    },

    toggleBigImage: function() {
      var $use = $(ACTION_BIG_IMAGE_TOGGLE).find('use');
      $(CONTENT_ASSET_TOP).toggleClass(CONTENT_BIG_IMG_CLASS);
      if ($use.attr('xlink:href') === '#icon-zoom-in') {
        $use.attr('xlink:href', '#icon-zoom-out');
      } else {
        $use.attr('xlink:href', '#icon-zoom-in');
      }
    }
  };

  window.AssetPage = AssetPage;

})(jQuery, window);
<|endoftext|>


<commit_before>'use strict';

/**
 * Test user data handling
 */
// function for generating a test user by http://randomuser.me/
function getNewUser() {
    $.ajax({dataType:'json', url: 'http://api.randomuser.me/', timeout:5000, success:onRssSuccess, error:onRssError, async: false});
}

// handle successful requests
function onRssSuccess(results) {
    var user = results.results[0].user;
    var seed = results.results[0].seed;
    // set user data
    $('#firstname').val(user.name.first);
    $('#lastname').val(user.name.last);
    // we 'generate' a username here
    $('#nickname').val(user.name.first.substring(0, 3) + user.name.last.substr(0, 3) + user.location.zip.substring(0, 3));
    $('#password').val(user.password);

    // set user picture
    $('#face').remove();
    $('#facespace').prepend('');

    // set user location
    $('#street').val(user.location.street);
    $('#city').val(user.location.city);
    $('#state').val(user.location.state);
    $('#zip').val(user.location.zip);

    console.log(user.picture);
}

// handle unsuccessful requests
function onRssError(results) {
    console.log('error');
}

/**
 * Get email handling
 */
function getEmail() {
    $.ajax({dataType:'json', url: 'https://www.guerrillamail.com/ajax.php?f=get_email_address', timeout:5000, success:onEmailRssSuccess, error:onEmailRssError, async: false});
}

function onEmailRssSuccess(result) {
    console.log(result.email_addr);
    $('#email').val(result.email_addr);
}

function onEmailRssError(result) {
    console.log('email cannot be retrieved due to an error');
}

/**
 * Forget email handling
 */
function forgetEmail() {
    $.ajax({dataType:'json', url: 'https://www.guerrillamail.com/ajax.php?f=forget_me', timeout:5000, async: false});
}

/**
 * Just do all calls, when button is clicked
 */
function doCalls() {
    getNewUser();
    forgetEmail();
    getEmail();
}

// Add event listeners once the DOM has fully loaded by listening for the
// `DOMContentLoaded` event on the document, and adding your listeners to
// specific elements when it triggers.
document.addEventListener('DOMContentLoaded', function () {
    document.querySelector('button').addEventListener('click', doCalls);
});<commit_msg>added function for selecting the text of an input field when clicking on it<commit_after>'use strict';

/**
 * Test user data handling
 */
// function for generating a test user by http://randomuser.me/
function getNewUser() {
    $.ajax({dataType:'json', url: 'http://api.randomuser.me/', timeout:5000, success:onRssSuccess, error:onRssError, async: false});
}

// handle successful requests
function onRssSuccess(results) {
    var user = results.results[0].user;
    var seed = results.results[0].seed;
    // set user data
    $('#firstname').val(user.name.first);
    $('#lastname').val(user.name.last);
    // we 'generate' a username here
    $('#nickname').val(user.name.first.substring(0, 3) + user.name.last.substr(0, 3) + user.location.zip.substring(0, 3));
    $('#password').val(user.password);

    // set user picture
    $('#face').remove();
    $('#facespace').prepend('');

    // set user location
    $('#street').val(user.location.street);
    $('#city').val(user.location.city);
    $('#state').val(user.location.state);
    $('#zip').val(user.location.zip);

    console.log(user.picture);
}

// handle unsuccessful requests
function onRssError(results) {
    console.log('error');
}

/**
 * Get email handling
 */
function getEmail() {
    $.ajax({dataType:'json', url: 'https://www.guerrillamail.com/ajax.php?f=get_email_address', timeout:5000, success:onEmailRssSuccess, error:onEmailRssError, async: false});
}

function onEmailRssSuccess(result) {
    console.log(result.email_addr);
    $('#email').val(result.email_addr);
}

function onEmailRssError(result) {
    console.log('email cannot be retrieved due to an error');
}

/**
 * Forget email handling
 */
function forgetEmail() {
    $.ajax({dataType:'json', url: 'https://www.guerrillamail.com/ajax.php?f=forget_me', timeout:5000, async: false});
}

/**
 * Just do all calls, when button is clicked
 */
function doCalls() {
    getNewUser();
    forgetEmail();
    getEmail();
}

function selectElement(target) {
    console.log('works');
    target.select();
}

// Add event listeners once the DOM has fully loaded by listening for the
// `DOMContentLoaded` event on the document, and adding your listeners to
// specific elements when it triggers.
document.addEventListener('DOMContentLoaded', function () {
    document.querySelector('button').addEventListener('click', doCalls);
    //document.querySelector('#firstname').addEventListener('click', test);
    document.addEventListener('click', function(e) {

        var liste = ['firstname', 'lastname', 'email', 'nickname', 'password', 'street', 'city', 'state', 'zip'];
        if (liste.indexOf(e.target.id) != -1) {
            selectElement(e.target);
        }

    }, false);
});<|endoftext|>


<commit_before>/**
 * Main ui constructor
 *
 * @contructor
 *
 */
MartIrcUi = function() {
    if (! (this instanceof arguments.callee)) {
        return new arguments.callee(arguments);
    }

    var self = this;

    self.ircConnection = null;

    self.init();
    self.bindEvents();
};

/**
 * MartIrcUi init
 *
 */
MartIrcUi.prototype.init = function() {
    var self = this;
};

MartIrcUi.prototype.bindEvents = function() {
    var self = this;

    $('#connectButton').click(function() {
				  self.connect();
			      });

    $('#prompt form').submit(function(event){
				 event.preventDefault();

				 self.parseIncomingMessage();
			     });

    $('#chat .current-title img').live('click', function(event){
					   self.removeChat();
				       });

    $('#channels a.channel').live('click', function(event){
					  self.focusOnPublicChat($(this));
				      });

    $('#channels a.user, #users .list.active a').live('click', function(event){
							      self.focusOnPrivateChat($(this));
							  });

    $('#channels a.server').live('click', function(event){
					self.focusOnServer($(this));
				     });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.connect = function() {
    var self = this;

    if(self.ircConnection && self.ircConnection.connected()){
	self.ircConnection.disconnect();

	self.ircConnection = null;
    }

    self.ircConnection = new IrcConnection({
					       nodeServerHost : $('#nodeServerHost').val(),
					       nodeServerPort : parseInt($('#nodeServerPort').val()),
					       ircServerHost : $('#ircServerHost').val(),
					       ircServerPort : parseInt($('#ircServerPort').val()),
					       nickname : $('#nickname').val()
					   });

    $(self.ircConnection).bind('irc.server',function(event, data) {
				   console.log(data.raw);

				   $(self).trigger('irc.server', data);

				   self.displayServerMessage(data.raw);
			       });

};

MartIrcUi.prototype.displayServerMessage = function(rawMsg) {
    var self = this;

    //console.log('Notice: ' + message);

    var msg = $('').addClass('msg');
    msg.append($('').addClass('server-msg').text('Server : '));
    msg.append($('').addClass('txt').text(rawMsg));

    $("#chat .server").append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.scanMessage = function(rawMsg) {
    var self = this;

    var regex = /\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i;

    return rawMsg.replace(regex," $& ");
};

MartIrcUi.prototype.parseIncomingMessage = function() {
    var self = this;

    var extractCommand = new RegExp("^:(\\w) ([\\S]+)", "");

    var rawMsg = $('#prompt form input').val();

    $('#prompt form input').val('');

    var matches = rawMsg.match(extractCommand);

    if(!matches) {
	self.sendMessage(rawMsg);
    }

    switch(matches[1]){
    case 'c':
	self.ircConnection.join(matches[2]);
	self.createPublicChat(matches[2]);
	break;
    }
};

/*
 * Sending raw messages only for the moment
 */
MartIrcUi.prototype.sendMessage = function(rawMsg) {
    var self = this;

    var msg = $('').addClass('msg');

    if($('#chat .active').hasClass('server')) {
	msg.append($('').addClass("command").text('Command : '));
	msg.append($('').addClass('txt').text(rawMsg));
	self.ircConnection.sendMessage(rawMsg);
    } else {
	msg.append($('').addClass("current-user nick").text($('#nickname').val()+' : '));
	msg.append($('').addClass('txt').append(self.scanMessage(rawMsg)));
	self.ircConnection.privmsg($('#channels .active').text(), rawMsg);
    }

    $('#chat .active').append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.createPublicChat = function(name) {
    var self = this;

    var id = 'channel-'+new Date().getTime();

    $('#channels').append($('').attr('id', id).addClass('channel').text(name));
    $('#chat').append($('
').addClass(id));
    $("#users").append($('
').addClass('list '+id));

    self.focusOnPublicChat($('#channels a#'+id));
};

MartIrcUi.prototype.focusOnPrompt = function() {
    var self = this;

    $("#chat .active").attr({ scrollTop: $("#chat .active").attr("scrollHeight") });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.focusOnServer = function(channel) {
    var self = this;

    self.changeActiveChat(channel.attr('id'), 'Server');

    self.displayUsersTab(false);
    self.displayCloseIcon(false);

    var chatToEnable = $('#chat .server').addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPrivateChat = function(channel) {
    var self = this;
    var id;

    if(channel.attr('id')){
	id = channel.attr('id');
    } else {
	id = channel.attr('class');
    }

    self.changeActiveChat(id, 'Private : '+channel.text());

    self.displayUsersTab(false);
    self.displayCloseIcon(true);

    if(!$('#channels a#'+id).get(0)){
	var user = $('').attr('id', id).attr('class', 'user').text(channel.text());
	$('#channels').append(user);

	var userChat = $('
').attr('class', id);
	$('#chat').append(userChat);
    }

    var chatTitle = 'Private : '+channel.text();

    var chatToEnable = $('#chat .'+id).addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPublicChat = function(channel) {
    var self = this;
    var id = channel.attr('id');

    self.changeActiveChat(id, 'Public : '+channel.text());

    self.displayUsersTab(true);
    self.displayCloseIcon(true);

    var chatTitle = 'Public : '+channel.text();

    var chatAndUsersToEnable = $('#chat .'+id+', #users .list.'+id).addClass('active');
    chatAndUsersToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.changeActiveChat = function(id, chatTitle) {
    var self = this;

    var channelToDisable = $('#channels .active');
    var chatAndUsersToDisable = $('#chat .active, #users .list.active');

    chatAndUsersToDisable.hide();
    channelToDisable.removeClass('active');
    chatAndUsersToDisable.removeClass('active');

    $("#chat .current-title span").text(chatTitle);

    $('#'+id).addClass('active');
};

MartIrcUi.prototype.removeChat = function() {
    var self = this;

    var id = $('#channels .active').attr('id');

    $('#channels  #'+id+', #chat .'+id).remove();

    if($('#channels .active').hasClass('channel')){
	$('#users .'+id).remove();
    }

    var lastChannel = $('#channels a').last();

    if(lastChannel.attr('class') == 'channel') {
	self.focusOnPublicChat(lastChannel);
    } else if(lastChannel.attr('class') == 'user') {
	self.focusOnPrivateChat(lastChannel);
    } else {
	self.focusOnServer();
    }
};

MartIrcUi.prototype.displayUsersTab = function(display) {
    var self = this;

    if(display){
	$('#chat, #prompt').removeClass('span-19');
	$('#chat, #prompt').addClass('span-16');
	$('#prompt').removeClass('append-1');
	$('#prompt').addClass('append-4');
	$('#prompt .text').addClass('span-14');
	$('#prompt .text').removeClass('span-17');
	$('#users').removeClass('last');
	$('#chat').addClass('last');
	$('#users').show();
    } else {
	$('#chat, #prompt').removeClass('span-16');
	$('#chat, #prompt').addClass('span-19');
	$('#prompt').removeClass('append-4');
	$('#prompt').addClass('append-1');
	$('#prompt .text').removeClass('span-14');
	$('#prompt .text').addClass('span-17');
	$('#users').addClass('last');
	$('#chat').removeClass('last');
	$('#users').hide();
    }
};

MartIrcUi.prototype.displayCloseIcon = function(display) {
    var self = this;

    if(display){
	$('#chat .current-title img').css('visibility', 'visible');
    } else {
	$('#chat .current-title img').css('visibility', 'hidden');
    }
};
<commit_msg>Argument is not mandatory for vi-like tool<commit_after>/**
 * Main ui constructor
 *
 * @contructor
 *
 */
MartIrcUi = function() {
    if (! (this instanceof arguments.callee)) {
        return new arguments.callee(arguments);
    }

    var self = this;

    self.ircConnection = null;

    self.init();
    self.bindEvents();
};

/**
 * MartIrcUi init
 *
 */
MartIrcUi.prototype.init = function() {
    var self = this;
};

MartIrcUi.prototype.bindEvents = function() {
    var self = this;

    $('#connectButton').click(function() {
				  self.connect();
			      });

    $('#prompt form').submit(function(event){
				 event.preventDefault();

				 self.parseIncomingMessage();
			     });

    $('#chat .current-title img').live('click', function(event){
					   self.removeChat();
				       });

    $('#channels a.channel').live('click', function(event){
					  self.focusOnPublicChat($(this));
				      });

    $('#channels a.user, #users .list.active a').live('click', function(event){
							      self.focusOnPrivateChat($(this));
							  });

    $('#channels a.server').live('click', function(event){
					self.focusOnServer($(this));
				     });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.connect = function() {
    var self = this;

    if(self.ircConnection && self.ircConnection.connected()){
	self.ircConnection.disconnect();

	self.ircConnection = null;
    }

    self.ircConnection = new IrcConnection({
					       nodeServerHost : $('#nodeServerHost').val(),
					       nodeServerPort : parseInt($('#nodeServerPort').val()),
					       ircServerHost : $('#ircServerHost').val(),
					       ircServerPort : parseInt($('#ircServerPort').val()),
					       nickname : $('#nickname').val()
					   });

    $(self.ircConnection).bind('irc.server',function(event, data) {
				   console.log(data.raw);

				   $(self).trigger('irc.server', data);

				   self.displayServerMessage(data.raw);
			       });

};

MartIrcUi.prototype.displayServerMessage = function(rawMsg) {
    var self = this;

    //console.log('Notice: ' + message);

    var msg = $('').addClass('msg');
    msg.append($('').addClass('server-msg').text('Server : '));
    msg.append($('').addClass('txt').text(rawMsg));

    $("#chat .server").append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.scanMessage = function(rawMsg) {
    var self = this;

    var regex = /\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i;

    return rawMsg.replace(regex," $& ");
};

MartIrcUi.prototype.parseIncomingMessage = function() {
    var self = this;

    var extractCommand = new RegExp("^:(\\w)(?: ([\\S]+))*", "");

    var rawMsg = $('#prompt form input').val();

    $('#prompt form input').val('');

    var matches = rawMsg.match(extractCommand);

    if(!matches) {
	self.sendMessage(rawMsg);
    }

    switch(matches[1]){
    case 'c':
	self.ircConnection.join(matches[2]);
	self.createPublicChat(matches[2]);
	break;
    }
};

/*
 * Sending raw messages only for the moment
 */
MartIrcUi.prototype.sendMessage = function(rawMsg) {
    var self = this;

    var msg = $('').addClass('msg');

    if($('#chat .active').hasClass('server')) {
	msg.append($('').addClass("command").text('Command : '));
	msg.append($('').addClass('txt').text(rawMsg));
	self.ircConnection.sendMessage(rawMsg);
    } else {
	msg.append($('').addClass("current-user nick").text($('#nickname').val()+' : '));
	msg.append($('').addClass('txt').append(self.scanMessage(rawMsg)));
	self.ircConnection.privmsg($('#channels .active').text(), rawMsg);
    }

    $('#chat .active').append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.createPublicChat = function(name) {
    var self = this;

    var id = 'channel-'+new Date().getTime();

    $('#channels').append($('').attr('id', id).addClass('channel').text(name));
    $('#chat').append($('
').addClass(id));
    $("#users").append($('
').addClass('list '+id));

    self.focusOnPublicChat($('#channels a#'+id));
};

MartIrcUi.prototype.focusOnPrompt = function() {
    var self = this;

    $("#chat .active").attr({ scrollTop: $("#chat .active").attr("scrollHeight") });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.focusOnServer = function(channel) {
    var self = this;

    self.changeActiveChat(channel.attr('id'), 'Server');

    self.displayUsersTab(false);
    self.displayCloseIcon(false);

    var chatToEnable = $('#chat .server').addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPrivateChat = function(channel) {
    var self = this;
    var id;

    if(channel.attr('id')){
	id = channel.attr('id');
    } else {
	id = channel.attr('class');
    }

    self.changeActiveChat(id, 'Private : '+channel.text());

    self.displayUsersTab(false);
    self.displayCloseIcon(true);

    if(!$('#channels a#'+id).get(0)){
	var user = $('').attr('id', id).attr('class', 'user').text(channel.text());
	$('#channels').append(user);

	var userChat = $('
').attr('class', id);
	$('#chat').append(userChat);
    }

    var chatTitle = 'Private : '+channel.text();

    var chatToEnable = $('#chat .'+id).addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPublicChat = function(channel) {
    var self = this;
    var id = channel.attr('id');

    self.changeActiveChat(id, 'Public : '+channel.text());

    self.displayUsersTab(true);
    self.displayCloseIcon(true);

    var chatTitle = 'Public : '+channel.text();

    var chatAndUsersToEnable = $('#chat .'+id+', #users .list.'+id).addClass('active');
    chatAndUsersToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.changeActiveChat = function(id, chatTitle) {
    var self = this;

    var channelToDisable = $('#channels .active');
    var chatAndUsersToDisable = $('#chat .active, #users .list.active');

    chatAndUsersToDisable.hide();
    channelToDisable.removeClass('active');
    chatAndUsersToDisable.removeClass('active');

    $("#chat .current-title span").text(chatTitle);

    $('#'+id).addClass('active');
};

MartIrcUi.prototype.removeChat = function() {
    var self = this;

    var id = $('#channels .active').attr('id');

    $('#channels  #'+id+', #chat .'+id).remove();

    if($('#channels .active').hasClass('channel')){
	$('#users .'+id).remove();
    }

    var lastChannel = $('#channels a').last();

    if(lastChannel.attr('class') == 'channel') {
	self.focusOnPublicChat(lastChannel);
    } else if(lastChannel.attr('class') == 'user') {
	self.focusOnPrivateChat(lastChannel);
    } else {
	self.focusOnServer();
    }
};

MartIrcUi.prototype.displayUsersTab = function(display) {
    var self = this;

    if(display){
	$('#chat, #prompt').removeClass('span-19');
	$('#chat, #prompt').addClass('span-16');
	$('#prompt').removeClass('append-1');
	$('#prompt').addClass('append-4');
	$('#prompt .text').addClass('span-14');
	$('#prompt .text').removeClass('span-17');
	$('#users').removeClass('last');
	$('#chat').addClass('last');
	$('#users').show();
    } else {
	$('#chat, #prompt').removeClass('span-16');
	$('#chat, #prompt').addClass('span-19');
	$('#prompt').removeClass('append-4');
	$('#prompt').addClass('append-1');
	$('#prompt .text').removeClass('span-14');
	$('#prompt .text').addClass('span-17');
	$('#users').addClass('last');
	$('#chat').removeClass('last');
	$('#users').hide();
    }
};

MartIrcUi.prototype.displayCloseIcon = function(display) {
    var self = this;

    if(display){
	$('#chat .current-title img').css('visibility', 'visible');
    } else {
	$('#chat .current-title img').css('visibility', 'hidden');
    }
};
<|endoftext|>