<commit_before>const canvas = document.getElementById("gamecanvas");
const context = canvas.getContext("2d");

var keys = [];
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

function sound(src) {
    this.sound = document.createElement("audio");
    this.sound.src = src;
    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function(){
        this.sound.play();
    }
    this.stop = function(){
        this.sound.pause();
    }
}

class Game {
    constructor(canvas) {
        this.canvas = canvas;

        this.sound = {};
        this.initializeSounds();

        this.startAttractMode();

        this.accumulator = 0;
        this.step = 1/360;
        let lastTime = null;
        this._frameCallback = (timestamp) => {
            if (lastTime !== null) {
                this.accumulator += (timestamp - lastTime) / 1000;
                while (this.accumulator >= this.step) {
                    this.simulate(this.step);
                    this.accumulator -= this.step;
                }
                this.render();
            }
            lastTime = timestamp;
            requestAnimationFrame(this._frameCallback);
        };
        requestAnimationFrame(this._frameCallback);
    }

    startAttractMode() {
        this.attractMode = true;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 1;
        this.level = Math.floor(Math.random() * 3) + 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    startGame() {
        this.attractMode = false;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 3;
        this.level = 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    initializeSounds() {
        this.sound["PlayerHit"] = new sound("sounds/playerhit.wav");
        this.sound["BlockHit"] = new sound("sounds/blockhit.mp3");
        this.sound["WallHit"] = new sound("sounds/wallhit.wav");
        this.sound["LifeLost"] = new sound("sounds/lifelost.mp3");
    }

    simulate(deltaTime) {
        if (keys[37] && !this.attractMode) {
            this.player.moveLeft();
        }
        if (keys[39] && !this.attractMode) {
            this.player.moveRight();
        }
        if (keys[13] && this.attractMode) {
            this.startGame();
            this.ball = new Ball();
            this.player = new Player();
        }
        if (keys[27] && !this.attractMode) {
            this.startAttractMode();
        }

        this.player.update(deltaTime);

        if (this.ball.pos.y-this.ball.height/2 > this.canvas.height) {
            // player missed the ball
            this.sound["LifeLost"].play();
            this.ball = new Ball();
            this.player = new Player();
            this.multiplier = 1;
            if (--this.lives == 0) this.startAttractMode(); // fix me
        } else if (this.ball.pos.y-this.ball.height/2 <= 0) {
            // ball touched ceiling
            this.sound["WallHit"].play();
            this.ball.velocity.y = -this.ball.velocity.y;
        } else if (this.ball.pos.x-this.ball.width/2 <= 0 || this.ball.pos.x+this.ball.width/2 >= this.canvas.width) {
            // ball touched left or right wall
            this.sound["WallHit"].play();
            this.ball.velocity.x = -this.ball.velocity.x;
        }
        this.ball.pos.x += this.ball.velocity.x * deltaTime;
        this.ball.pos.y += this.ball.velocity.y * deltaTime;

        // detect ball collision with player
        if (this.ball.collisionDetection(this.player)) {
            this.sound["PlayerHit"].play();
            this.ball.velocity.x = ((this.ball.pos.x+this.ball.width/2) - (this.player.pos.x+this.player.width/2)) * 6;
            this.ball.velocity.y = -this.ball.velocity.y;
            this.multiplier = 1;
        }

        // detect ball collision with blocks
        this.blocks.forEach((block)=> {
            if (this.ball.collisionDetection(block)) {
                this.sound["BlockHit"].play();
                this.score += this.multiplier++;

                var health = block.damage();
                if (health <= 0) {
                    var i = this.blocks.indexOf(block);
                    this.blocks.splice(i, 1);
                }

                var side = this.ball.collisionSide(block);
                if (side == "top/bottom") {
                    this.ball.velocity.y = -this.ball.velocity.y;
                } else {
                    this.ball.velocity.x = -this.ball.velocity.x;
                }
            }
        });

        // check if level cleared
        if (this.blocks.length == 0) {
            if (this.attractMode) {
                // restart attract mode
                this.startAttractMode();
            } else {
                // move to next level
                this.blocks = generateLevel(++this.level);
                this.ball = new Ball();
                this.player = new Player();
            }
        }

        // AI
        if (this.attractMode) {
            if (this.ball.pos.y > this.canvas.height*0.3 && this.ball.pos.y < this.canvas.height*0.9) {
                if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) < 50) {
                    this.player.moveRight();
                } else if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) > -50) {
                    this.player.moveLeft();
                }
            }
        }
    }

    render() {
        // draw background
        context.fillStyle = "#272822";
        context.fillRect(0, 0, canvas.width, canvas.height);

        // draw objects
        this.ball.draw();
        this.player.draw();
        this.blocks.forEach(function(block) {
            block.draw();
        });

        // draw text
        context.fillStyle = "rgba(255, 255, 255, 0.75)";
        context.font = "20px Georgia";
        context.textAlign = "left";
        context.fillText("Score: " + this.score, 10, 20);
        context.textAlign = "center";
        context.fillText("Level: " + this.level, canvas.width/2, 20);
        context.textAlign = "right";
        context.fillText("Lives: " + this.lives, canvas.width-10, 20);
        context.globalAlpha = 1;

        if (this.attractMode) {
            context.fillStyle = "white";
            context.textAlign = "center";
            context.fillText("Press <enter> to start playing", canvas.width / 2, canvas.height / 2);
        }
    }
}

class Rectangle {
    constructor(x, y, width, height, color="#FFF") {
        this.pos = { x: x, y: y};
        this.width = width;
        this.height = height;
        this.color = color;
    }

    get left() {
        return this.pos.x;
    }

    get right() {
        return this.pos.x + this.width;
    }

    get top() {
        return this.pos.y;
    }

    get bottom() {
        return this.pos.y + this.height;
    }

    collisionDetection(object) {
        if (this.left < object.right &&
            this.right > object.left &&
            this.top < object.bottom &&
            this.bottom > object.top) {
            return true;
        }
        return false;
    }

    collisionSide(object) {
        // top/bottom or left/right
        if (this.right >= object.left && this.left <= object.right) {
            return "top/bottom";
        } else if (this.top >= object.bottom && this.bottom <= object.top) {
            return "left/right";
        }
        return "";
    }

    draw() {
        context.fillStyle = this.color;
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    }
}

class Player extends Rectangle {
    constructor() {
        const width = 120;
        const height = 16;
        super(canvas.width / 2 - width/2, canvas.height - 32, width, height, "#F92672");
        this.velocity = 0;
        this.speed = 50;
        this.friction = 0.9;
    }

    moveLeft() {
        this.velocity -= this.speed;
    }

    moveRight() {
        this.velocity += this.speed;
    }

    update(deltaTime) {
        this.pos.x += this.velocity * deltaTime;
        this.velocity *= this.friction;

        if (this.pos.x+this.width/2 < 0) {
            this.pos.x = -this.width/2;
            this.velocity = 0;
        } else if (this.pos.x+this.width/2 > canvas.width) {
            this.pos.x = canvas.width-this.width/2;
            this.velocity = 0;
        }
    }
}

class Ball extends Rectangle {
    constructor() {
        const size = 12;
        super(canvas.width/2, canvas.height-64, size, size, "#F8F8F2");
        this.speed = -300;
        this.velocity = {x: (Math.random() + 0.5) * Math.pow(-1, Math.floor(Math.random() * 2)) * 60,
                         y: this.speed};
    }
}

class Block extends Rectangle {
    constructor(x, y, width, height, color="#FFE792", health=1) {
        super(x, y, width, height, color);
        this.health = health;
    }

    damage(d=1) {
        this.health -= d;
        return this.health;
    }
}

function generateLevel(level) {
    const blocks = [];
    const colors = ["#F92672", "#66D9EF", "#A6E22E", "#FD971F", "#AE81FF", "#FFE792", "#FFE792"];
    if (level == 1) {
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    } else if (level == 2) {
        for (row = 0; row < 3; row++) {
            for (col = 1; col < 7; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }

        for (row = 0; row < 4; row++) {
            for (col = 0; col < 8; col++) {
                if (col == 2 || col == 5) continue;
                blocks.push(new Block(2+col*60, 160+row*20, 58, 16, colors[row]));
            }
        }

        for (col = 0; col < 8; col++) {
            blocks.push(new Block(2+col*60, 160+row*20, 58, 16, "grey", 2));
        }
    } else if (level == 3) {
        blocks.push(new Block(60, 60, 16, 196, "grey", 2));
        blocks.push(new Block(canvas.width-76, 60, 16, 196, "grey", 2));

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 60+row*20, 50, 16, colors[row]));
            }
        }
        for (row = 0; row < 4; row++) {
            blocks.push(new Block(80, 120+row*20, 50, 16, colors[2]));
            blocks.push(new Block(canvas.width-130, 120+row*20, 50, 16, colors[2]));
        }

        for (col = 0; col < 2; col++) {
            blocks.push(new Block(134+col*108, 120, 104, 76, colors[5]));
        }

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 200+row*20, 50, 16, colors[2-row]));
            }
        }

        for (col = 0; col < 6; col++) {
            blocks.push(new Block(80+col*54, 200+row*20, 50, 16, "grey", 2));
        }
    } else {
        // simple random level
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                if (Math.random() >= 0.5) continue;
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    }
    return blocks;
}

var game = new Game(canvas);
<commit_msg>Changed on-screen text for attract mode<commit_after>const canvas = document.getElementById("gamecanvas");
const context = canvas.getContext("2d");

var keys = [];
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

function sound(src) {
    this.sound = document.createElement("audio");
    this.sound.src = src;
    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function(){
        this.sound.play();
    }
    this.stop = function(){
        this.sound.pause();
    }
}

class Game {
    constructor(canvas) {
        this.canvas = canvas;

        this.sound = {};
        this.initializeSounds();

        this.startAttractMode();

        this.accumulator = 0;
        this.step = 1/360;
        let lastTime = null;
        this._frameCallback = (timestamp) => {
            if (lastTime !== null) {
                this.accumulator += (timestamp - lastTime) / 1000;
                while (this.accumulator >= this.step) {
                    this.simulate(this.step);
                    this.accumulator -= this.step;
                }
                this.render();
            }
            lastTime = timestamp;
            requestAnimationFrame(this._frameCallback);
        };
        requestAnimationFrame(this._frameCallback);
    }

    startAttractMode() {
        this.attractMode = true;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 1;
        this.level = Math.floor(Math.random() * 3) + 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    startGame() {
        this.attractMode = false;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 3;
        this.level = 1;

        this.ball = new Ball();
        this.player = new Player();
        this.blocks = generateLevel(this.level);
    }

    initializeSounds() {
        this.sound["PlayerHit"] = new sound("sounds/playerhit.wav");
        this.sound["BlockHit"] = new sound("sounds/blockhit.mp3");
        this.sound["WallHit"] = new sound("sounds/wallhit.wav");
        this.sound["LifeLost"] = new sound("sounds/lifelost.mp3");
    }

    simulate(deltaTime) {
        if (keys[37] && !this.attractMode) {
            this.player.moveLeft();
        }
        if (keys[39] && !this.attractMode) {
            this.player.moveRight();
        }
        if (keys[13] && this.attractMode) {
            this.startGame();
            this.ball = new Ball();
            this.player = new Player();
        }
        if (keys[27] && !this.attractMode) {
            this.startAttractMode();
        }

        this.player.update(deltaTime);

        if (this.ball.pos.y-this.ball.height/2 > this.canvas.height) {
            // player missed the ball
            this.sound["LifeLost"].play();
            this.ball = new Ball();
            this.player = new Player();
            this.multiplier = 1;
            if (--this.lives == 0) this.startAttractMode(); // fix me
        } else if (this.ball.pos.y-this.ball.height/2 <= 0) {
            // ball touched ceiling
            this.sound["WallHit"].play();
            this.ball.velocity.y = -this.ball.velocity.y;
        } else if (this.ball.pos.x-this.ball.width/2 <= 0 || this.ball.pos.x+this.ball.width/2 >= this.canvas.width) {
            // ball touched left or right wall
            this.sound["WallHit"].play();
            this.ball.velocity.x = -this.ball.velocity.x;
        }
        this.ball.pos.x += this.ball.velocity.x * deltaTime;
        this.ball.pos.y += this.ball.velocity.y * deltaTime;

        // detect ball collision with player
        if (this.ball.collisionDetection(this.player)) {
            this.sound["PlayerHit"].play();
            this.ball.velocity.x = ((this.ball.pos.x+this.ball.width/2) - (this.player.pos.x+this.player.width/2)) * 6;
            this.ball.velocity.y = -this.ball.velocity.y;
            this.multiplier = 1;
        }

        // detect ball collision with blocks
        this.blocks.forEach((block)=> {
            if (this.ball.collisionDetection(block)) {
                this.sound["BlockHit"].play();
                this.score += this.multiplier++;

                var health = block.damage();
                if (health <= 0) {
                    var i = this.blocks.indexOf(block);
                    this.blocks.splice(i, 1);
                }

                var side = this.ball.collisionSide(block);
                if (side == "top/bottom") {
                    this.ball.velocity.y = -this.ball.velocity.y;
                } else {
                    this.ball.velocity.x = -this.ball.velocity.x;
                }
            }
        });

        // check if level cleared
        if (this.blocks.length == 0) {
            if (this.attractMode) {
                // restart attract mode
                this.startAttractMode();
            } else {
                // move to next level
                this.blocks = generateLevel(++this.level);
                this.ball = new Ball();
                this.player = new Player();
            }
        }

        // AI
        if (this.attractMode) {
            if (this.ball.pos.y > this.canvas.height*0.3 && this.ball.pos.y < this.canvas.height*0.9) {
                if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) < 50) {
                    this.player.moveRight();
                } else if ((this.player.pos.x + this.player.width/2) - (this.ball.pos.x + this.ball.width/2) > -50) {
                    this.player.moveLeft();
                }
            }
        }
    }

    render() {
        // draw background
        context.fillStyle = "#272822";
        context.fillRect(0, 0, canvas.width, canvas.height);

        // draw objects
        this.ball.draw();
        this.player.draw();
        this.blocks.forEach(function(block) {
            block.draw();
        });

        // draw text
        if (this.attractMode) {
            context.fillStyle = "rgba(0, 0, 0, 0.75)";
            context.fillRect(canvas.width/2-140, canvas.height*3/4-20, 280, 28);
            context.fillStyle = "white";
            context.font = "20px Georgia";
            context.textAlign = "center";
            context.fillText("Press <enter> to start playing", canvas.width / 2, canvas.height * 3/4);
        } else {
            context.fillStyle = "rgba(255, 255, 255, 0.75)";
            context.font = "20px Georgia";
            context.textAlign = "left";
            context.fillText("Score: " + this.score, 10, 20);
            context.textAlign = "center";
            context.fillText("Level: " + this.level, canvas.width/2, 20);
            context.textAlign = "right";
            context.fillText("Lives: " + this.lives, canvas.width-10, 20);
            context.globalAlpha = 1;
        }
    }
}

class Rectangle {
    constructor(x, y, width, height, color="#FFF") {
        this.pos = { x: x, y: y};
        this.width = width;
        this.height = height;
        this.color = color;
    }

    get left() {
        return this.pos.x;
    }

    get right() {
        return this.pos.x + this.width;
    }

    get top() {
        return this.pos.y;
    }

    get bottom() {
        return this.pos.y + this.height;
    }

    collisionDetection(object) {
        if (this.left < object.right &&
            this.right > object.left &&
            this.top < object.bottom &&
            this.bottom > object.top) {
            return true;
        }
        return false;
    }

    collisionSide(object) {
        // top/bottom or left/right
        if (this.right >= object.left && this.left <= object.right) {
            return "top/bottom";
        } else if (this.top >= object.bottom && this.bottom <= object.top) {
            return "left/right";
        }
        return "";
    }

    draw() {
        context.fillStyle = this.color;
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    }
}

class Player extends Rectangle {
    constructor() {
        const width = 120;
        const height = 16;
        super(canvas.width / 2 - width/2, canvas.height - 32, width, height, "#F92672");
        this.velocity = 0;
        this.speed = 50;
        this.friction = 0.9;
    }

    moveLeft() {
        this.velocity -= this.speed;
    }

    moveRight() {
        this.velocity += this.speed;
    }

    update(deltaTime) {
        this.pos.x += this.velocity * deltaTime;
        this.velocity *= this.friction;

        if (this.pos.x+this.width/2 < 0) {
            this.pos.x = -this.width/2;
            this.velocity = 0;
        } else if (this.pos.x+this.width/2 > canvas.width) {
            this.pos.x = canvas.width-this.width/2;
            this.velocity = 0;
        }
    }
}

class Ball extends Rectangle {
    constructor() {
        const size = 12;
        super(canvas.width/2, canvas.height-64, size, size, "#F8F8F2");
        this.speed = -300;
        this.velocity = {x: (Math.random() + 0.5) * Math.pow(-1, Math.floor(Math.random() * 2)) * 60,
                         y: this.speed};
    }
}

class Block extends Rectangle {
    constructor(x, y, width, height, color="#FFE792", health=1) {
        super(x, y, width, height, color);
        this.health = health;
    }

    damage(d=1) {
        this.health -= d;
        return this.health;
    }
}

function generateLevel(level) {
    const blocks = [];
    const colors = ["#F92672", "#66D9EF", "#A6E22E", "#FD971F", "#AE81FF", "#FFE792", "#FFE792"];
    if (level == 1) {
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    } else if (level == 2) {
        for (row = 0; row < 3; row++) {
            for (col = 1; col < 7; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }

        for (row = 0; row < 4; row++) {
            for (col = 0; col < 8; col++) {
                if (col == 2 || col == 5) continue;
                blocks.push(new Block(2+col*60, 160+row*20, 58, 16, colors[row]));
            }
        }

        for (col = 0; col < 8; col++) {
            blocks.push(new Block(2+col*60, 160+row*20, 58, 16, "grey", 2));
        }
    } else if (level == 3) {
        blocks.push(new Block(60, 60, 16, 196, "grey", 2));
        blocks.push(new Block(canvas.width-76, 60, 16, 196, "grey", 2));

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 60+row*20, 50, 16, colors[row]));
            }
        }
        for (row = 0; row < 4; row++) {
            blocks.push(new Block(80, 120+row*20, 50, 16, colors[2]));
            blocks.push(new Block(canvas.width-130, 120+row*20, 50, 16, colors[2]));
        }

        for (col = 0; col < 2; col++) {
            blocks.push(new Block(134+col*108, 120, 104, 76, colors[5]));
        }

        for (row = 0; row < 3; row++) {
            for (col = 0; col < 6; col++) {
                blocks.push(new Block(80+col*54, 200+row*20, 50, 16, colors[2-row]));
            }
        }

        for (col = 0; col < 6; col++) {
            blocks.push(new Block(80+col*54, 200+row*20, 50, 16, "grey", 2));
        }
    } else {
        // simple random level
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                if (Math.random() >= 0.5) continue;
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    }
    return blocks;
}

var game = new Game(canvas);
<|endoftext|>


<commit_before>var Lexer  = require( "../../lib/lexer/lexer" );
var should = require( "should"                );

describe ("Lexer", function () {
  var lexer;
  beforeEach(function () {
    lexer = Lexer.clone();
    lexer.rules  = [];
    lexer.column = 0;
    lexer.line   = 0;
  });

  describe (".rule", function () {
    it ("creates a new token", function () {
      var action = function () {};
      var rule = lexer.rule("number", /\d+/, action);
      rule. name.   should. eql ("number");
      rule. regex.  should. eql ("^(\\d+)");
      rule. action. should. eql (action);
    });

    it ("stores the token in the rules list", function () {
      lexer.rule("number", /foo/);
      lexer.rules.length.should.eql(1);
      lexer.rules[0].name.should.eql("number");
    });
  });

  describe ("advance", function () {

    it ("returns a token object when a match is found", function () {
      lexer.rule("number", /\d+/);
      lexer.source = "123"
      var token = lexer.advance();

      token. type.  should. eql ( "number" );
      token. value. should. eql ( "123"    );
    });

    it ("updates the column count after a match", function () {
      lexer.source = "123";
      lexer.rule("number", /\d+/);
      lexer.advance();

      lexer.column.should.eql(3);
    });

    it("should choose the longest match when there are multiple choices", function () {
      lexer.source = "||";
      lexer.rule("operator", /\|/);
      lexer.rule("operator", /\|\|/);
      var token = lexer.advance();

      token.type.should.eql("operator");
    });

    it ("should run the value through the action if one is provided", function () {
      lexer.source = "23";
      lexer.rule("number", /\d+/, function (num) { return parseInt(num, 10); });

      lexer.advance().value.should.eql(23);
    });

    it ("should return the value instead of a token if the action returns an array", function () {
      lexer.source = "23";
      lexer.rule("number", /\d+/, function (num) { return [this.create("num", parseInt(num, 10))]; });

      lexer.advance()[0].value.should.eql(23);
    });

    it ("should return the value if the action returns a token", function () {
      lexer.source = "23";
      lexer.rule("number", /\d+/, function (num) { return this.create("num", parseInt(num)); });

      lexer.advance().type.should.eql("num");
    });

    it ("should keep track of token position", function () {
      lexer.rule("name", /[a-zA-Z]+/);
      lexer.rule("(nl)", /\n/, function () { return "(nl)"; });

      lexer.source = "foo\n";
      var foo = lexer.advance();
      var nl  = lexer.advance();

      foo.start.should.eql(0)
      foo.end.should.eql(2);
      foo.line.should.eql(0);

      nl.start.should.eql(3);
      nl.end.should.eql(3);
      nl.line.should.eql(0);
    });

    describe ("peek", function () {
      it ("should return the next token if called without an argument", function () {
        lexer.rule("number", /\d+/)
        lexer.skip(/\s+/);
        var tokens = lexer.lex('123 456');

        tokens.peek().value.should.eql("123");
      });

      it ("should return the token at the index if called with an index", function () {
        lexer.rule("number", /\d+/)
        lexer.skip(/\s+/);
        var tokens = lexer.lex('123 456');

        tokens.peek(1).value.should.eql("456");
      });
    });

    it ("should keep track of the token line", function () {
      lexer.rule("name", /[a-zA-Z]+/);
      lexer.rule("(nl)", /\n/, function () { return "(nl)"; });

      lexer.source = "foo\nbar";
      var foo = lexer.advance();
      var nl  = lexer.advance();
      var bar = lexer.advance();

      bar.start.should.eql(0)
      bar.end.should.eql(2);
      bar.line.should.eql(1);
    });
  });

  describe (".lex", function () {
    it ("should should return an empty array token if called without any input", function () {
      lexer.lex().length.should.eql(0);
    });

    it ("should should return an empty array if called with an empty string", function () {
      lexer.lex("").length.should.eql(0);
    });

    it ("should return an array of tokens if called with a valid string", function () {
      lexer.rule ( "id"  , /[a-zA-Z]+/           );
      lexer.rule ( "num" , /[0-9]+/   , parseInt );
      lexer.rule ( "op"  , /\+/                  );

      lexer.lex("foo+23").
        map(function (tok) { return [tok.type, tok.value] }).
        should.eql([["id", "foo"], ["op", "+"], ["num", 23]])
    });

    it ("should append each individual token if advance returns an array", function () {
      lexer.advance = function () {
        this.source = "";
        this.tokens = [1];
        return [2, 3];
      };
      lexer.lex("foo").join(", ").should.eql("1, 2, 3");
    });

    it ("should create an error token if advance returns undefined", function () {
      var err = "";
      lexer.advance = function () {
        return undefined;
      };
      lexer.error = function (char) { this.source = ""; err = char; };
      lexer.lex("foo")
      err.should.eql("f");
    });
  });

  describe ("clone", function () {

    it ("sets up a prototypal inheritance", function () {
      lexer.rule ("id", /[a-zA-Z]+/ )
      var l2 = lexer.clone();

      l2.lex('foo').map(function (tok) { return [tok.type, tok.value] })[0].should.eql(["id", "foo"]);
    });

    it ("supports overriding of rules", function () {
      lexer.rule ("id", /[a-zA-Z]+/ )
      var l2 = lexer.clone(function () { this.rule('id', /[a-zA-Z\$]+/) });

      l2.lex('foo$').map(function (tok) { return [tok.type, tok.value] })[0].should.eql(["id", "foo$"]);
    })
  });
  describe ("Error Handling", function () {

    describe ("error", function () {

      it ("appends an error token to the tokens collection", function () {
        lexer.error("e");
        lexer.tokens[0]._type.should.eql("ErrorToken");
        lexer.tokens[0].value.should.eql("e");
        lexer.tokens[0].start.should.eql(-1);
        lexer.tokens[0].end.should.eql(0);
        lexer.tokens[0].line.should.eql(0);
      });

      it ("appends to the previous token in tokens if they are positioned together", function () {
        lexer.error("f");
        lexer.error("o");
        lexer.error("o");

        lexer.tokens.length.should.eql(1);
        lexer.tokens[0].value.should.eql("foo");
      });

      it ("appends a new error token to tokens if they are positioned apart", function () {
        lexer.error("f");
        lexer.column += 11;
        lexer.error("o");

        lexer.tokens.length.should.eql(2);
        lexer.tokens[0].value.should.eql("f");
        lexer.tokens[1].value.should.eql("o");
      });

      it ("appends a new error token to tokens if they are on separate lines", function () {
        lexer.error("f");
        lexer.line  += 1;
        lexer.column = 0;
        lexer.error("o");

        lexer.tokens.length.should.eql(2);
        lexer.tokens[0].value.should.eql("f");
        lexer.tokens[1].value.should.eql("o");
      });
    });
  });

  describe ("init", function () {

    it ("sets column to 0", function () {
      lexer.column.should.eql(0);
    });

    it ("sets line to 0", function () {
      lexer.line.should.eql(0);
    });
  });
});<commit_msg>ensure lexers are extendable<commit_after>var Lexer  = require( "../../lib/lexer/lexer" );
var should = require( "should"                );

describe ("Lexer", function () {
  var lexer;
  beforeEach(function () {
    lexer = Lexer.clone();
    lexer.rules  = [];
    lexer.column = 0;
    lexer.line   = 0;
  });

  describe (".rule", function () {
    it ("creates a new token", function () {
      var action = function () {};
      var rule = lexer.rule("number", /\d+/, action);
      rule. name.   should. eql ("number");
      rule. regex.  should. eql ("^(\\d+)");
      rule. action. should. eql (action);
    });

    it ("stores the token in the rules list", function () {
      lexer.rule("number", /foo/);
      lexer.rules.length.should.eql(1);
      lexer.rules[0].name.should.eql("number");
    });
  });

  describe ("advance", function () {

    it ("returns a token object when a match is found", function () {
      lexer.rule("number", /\d+/);
      lexer.source = "123"
      var token = lexer.advance();

      token. type.  should. eql ( "number" );
      token. value. should. eql ( "123"    );
    });

    it ("updates the column count after a match", function () {
      lexer.source = "123";
      lexer.rule("number", /\d+/);
      lexer.advance();

      lexer.column.should.eql(3);
    });

    it("should choose the longest match when there are multiple choices", function () {
      lexer.source = "||";
      lexer.rule("operator", /\|/);
      lexer.rule("operator", /\|\|/);
      var token = lexer.advance();

      token.type.should.eql("operator");
    });

    it ("should run the value through the action if one is provided", function () {
      lexer.source = "23";
      lexer.rule("number", /\d+/, function (num) { return parseInt(num, 10); });

      lexer.advance().value.should.eql(23);
    });

    it ("should return the value instead of a token if the action returns an array", function () {
      lexer.source = "23";
      lexer.rule("number", /\d+/, function (num) { return [this.create("num", parseInt(num, 10))]; });

      lexer.advance()[0].value.should.eql(23);
    });

    it ("should return the value if the action returns a token", function () {
      lexer.source = "23";
      lexer.rule("number", /\d+/, function (num) { return this.create("num", parseInt(num)); });

      lexer.advance().type.should.eql("num");
    });

    it ("should keep track of token position", function () {
      lexer.rule("name", /[a-zA-Z]+/);
      lexer.rule("(nl)", /\n/, function () { return "(nl)"; });

      lexer.source = "foo\n";
      var foo = lexer.advance();
      var nl  = lexer.advance();

      foo.start.should.eql(0)
      foo.end.should.eql(2);
      foo.line.should.eql(0);

      nl.start.should.eql(3);
      nl.end.should.eql(3);
      nl.line.should.eql(0);
    });

    describe ("peek", function () {
      it ("should return the next token if called without an argument", function () {
        lexer.rule("number", /\d+/)
        lexer.skip(/\s+/);
        var tokens = lexer.lex('123 456');

        tokens.peek().value.should.eql("123");
      });

      it ("should return the token at the index if called with an index", function () {
        lexer.rule("number", /\d+/)
        lexer.skip(/\s+/);
        var tokens = lexer.lex('123 456');

        tokens.peek(1).value.should.eql("456");
      });
    });

    it ("should keep track of the token line", function () {
      lexer.rule("name", /[a-zA-Z]+/);
      lexer.rule("(nl)", /\n/, function () { return "(nl)"; });

      lexer.source = "foo\nbar";
      var foo = lexer.advance();
      var nl  = lexer.advance();
      var bar = lexer.advance();

      bar.start.should.eql(0)
      bar.end.should.eql(2);
      bar.line.should.eql(1);
    });
  });

  describe (".lex", function () {
    it ("should should return an empty array token if called without any input", function () {
      lexer.lex().length.should.eql(0);
    });

    it ("should should return an empty array if called with an empty string", function () {
      lexer.lex("").length.should.eql(0);
    });

    it ("should return an array of tokens if called with a valid string", function () {
      lexer.rule ( "id"  , /[a-zA-Z]+/           );
      lexer.rule ( "num" , /[0-9]+/   , parseInt );
      lexer.rule ( "op"  , /\+/                  );

      lexer.lex("foo+23").
        map(function (tok) { return [tok.type, tok.value] }).
        should.eql([["id", "foo"], ["op", "+"], ["num", 23]])
    });

    it ("should append each individual token if advance returns an array", function () {
      lexer.advance = function () {
        this.source = "";
        this.tokens = [1];
        return [2, 3];
      };
      lexer.lex("foo").join(", ").should.eql("1, 2, 3");
    });

    it ("should create an error token if advance returns undefined", function () {
      var err = "";
      lexer.advance = function () {
        return undefined;
      };
      lexer.error = function (char) { this.source = ""; err = char; };
      lexer.lex("foo")
      err.should.eql("f");
    });
  });

  describe ("clone", function () {

    it ("sets up a prototypal inheritance", function () {
      lexer.rule ("id", /[a-zA-Z]+/ )
      var l2 = lexer.clone();

      l2.lex('foo').map(function (tok) { return [tok.type, tok.value] })[0].should.eql(["id", "foo"]);
    });

    it ("supports overriding of rules", function () {
      lexer.rule ("id", /[a-zA-Z]+/ )
      var l2 = lexer.clone(function () { this.rule('id', /[a-zA-Z\$]+/) });

      l2.lex('foo$').map(function (tok) { return [tok.type, tok.value] })[0].should.eql(["id", "foo$"]);
    })
  });

  describe ("extend", function () {

    it ("copies all rules from another lexer", function () {
      lexer.rule ("id", /[a-zA-Z]+/ )
      lexer.skip (/\s+/)
      var l2 = Lexer.clone(function () { this.extend(lexer); });

      l2.lex('foo bar').map(function (tok) { return [tok.type, tok.value] }).
          should.eql([["id", "foo"], ["id", "bar"]]);
    });
  });

  describe ("Error Handling", function () {

    describe ("error", function () {

      it ("appends an error token to the tokens collection", function () {
        lexer.error("e");
        lexer.tokens[0]._type.should.eql("ErrorToken");
        lexer.tokens[0].value.should.eql("e");
        lexer.tokens[0].start.should.eql(-1);
        lexer.tokens[0].end.should.eql(0);
        lexer.tokens[0].line.should.eql(0);
      });

      it ("appends to the previous token in tokens if they are positioned together", function () {
        lexer.error("f");
        lexer.error("o");
        lexer.error("o");

        lexer.tokens.length.should.eql(1);
        lexer.tokens[0].value.should.eql("foo");
      });

      it ("appends a new error token to tokens if they are positioned apart", function () {
        lexer.error("f");
        lexer.column += 11;
        lexer.error("o");

        lexer.tokens.length.should.eql(2);
        lexer.tokens[0].value.should.eql("f");
        lexer.tokens[1].value.should.eql("o");
      });

      it ("appends a new error token to tokens if they are on separate lines", function () {
        lexer.error("f");
        lexer.line  += 1;
        lexer.column = 0;
        lexer.error("o");

        lexer.tokens.length.should.eql(2);
        lexer.tokens[0].value.should.eql("f");
        lexer.tokens[1].value.should.eql("o");
      });
    });
  });

  describe ("init", function () {

    it ("sets column to 0", function () {
      lexer.column.should.eql(0);
    });

    it ("sets line to 0", function () {
      lexer.line.should.eql(0);
    });
  });
});<|endoftext|>


<commit_before>// client side code
// just include this js file in your html and enjoy the cats, man ;)
function catContainerPosition(){
	$("#catContainer").attr('style',
		"background:#FFF;position:absolute;left:0px;bottom:0px;overflow:hidden;height:330px;width:306px;text-align:center;border:1px black solid;padding:6px;"
	);
	$("#catContainer label").attr('style',
		"color:#000;font-size:30px;font-family:'Helvetica Neue',Helvetica,Arial;font-weight:100;"
	);
}
$("body").append("
BroadCat
");
$(document).ready(catContainerPosition());
$(window).resize(catContainerPosition());
$(window).scroll(catContainerPosition());
var count = 0;
var CATS;
var ready = false;
function parseResponse( msg ) {
  CATS = msg;
  ready = true;
};
setInterval(function(){
	if(ready){
		$("#catContainer img").attr("src",CATS.data[count].images.standard_resolution.url);
		count = (count+1)%CATS.data.length;
	}
},2000);S.data.length;
	}
},2000);<commit_msg>bug fix :)<commit_after>// client side code
// just include this js file in your html and enjoy the cats, man ;)
function catContainerPosition(){
	$("#catContainer").attr('style',
		"background:#FFF;position:absolute;left:0px;bottom:0px;overflow:hidden;height:330px;width:306px;text-align:center;border:1px black solid;padding:6px;"
	);
	$("#catContainer label").attr('style',
		"color:#000;font-size:30px;font-family:'Helvetica Neue',Helvetica,Arial;font-weight:100;"
	);
	$("#catContainer img").attr('style',
		"height:300px;width:300px;"
	);
}
$("body").append("
BroadCat
");
$(document).ready(catContainerPosition());
$(window).resize(catContainerPosition());
$(window).scroll(catContainerPosition());
var count = 0;
var CATS;
var ready = false;
function parseResponse( msg ) {
  CATS = msg;
  ready = true;
};
setInterval(function(){
	if(ready){
		$("#catContainer img").attr("src",CATS.data[count].images.standard_resolution.url);
		count = (count+1)%CATS.data.length;
	}
},2000);<|endoftext|>


<commit_before>/* global global */
var UnexpectedMarkdown = require('unexpected-markdown');
var basename = require('path').basename;
var debug = require('debug')('metalsmith-unexpected-markdown');
var dirname = require('path').dirname;
var resolve = require('path').resolve;
var extname = require('path').extname;
var fs = require('fs');
var async = require('async');
var extend = require('extend');

module.exports = function plugin(pluginOptions) {
    pluginOptions = pluginOptions || {};

    return function (files, metalsmith, next) {
        var sourcePath = metalsmith.source();

        async.series([
            function (cb) {
                var markdownFiles = Object.keys(files).filter(function (file) {
                    return /\.md|\.markdown/.test(extname(file));
                }).sort();

                async.eachSeries(markdownFiles, function (file, cb) {
                    debug('checking file: %s', file);
                    var theme = files[file].theme;
                    var data = files[file];
                    var content = data.contents.toString();
                    var options = extend({}, { theme: theme }, pluginOptions);

                    var markdown = new UnexpectedMarkdown(content);
                    var tasks = [];
                    if (options.updateExamples) {
                        tasks.push(function (cb) {
                            markdown.withUpdatedExamples(options).then(function (updatedMarkdown) {
                                markdown = updatedMarkdown;
                                cb();
                            }).catch(cb);
                        });
                        tasks.push(function (cb) {
                            debug('updating examples in file: %s', file);
                            var absoluteFilePath = resolve(sourcePath, file);
                            async.waterfall([
                                function (cb) {
                                    // read file again to avoid removing metadata from the file
                                    fs.readFile(absoluteFilePath, cb);
                                },
                                function (data, cb) {
                                    new UnexpectedMarkdown(data.toString()).withUpdatedExamples(options).then(function (markdownForFile) {
                                        cb(null, markdownForFile);
                                    }).catch(cb);
                                },
                                function (markdown, cb) {
                                    fs.writeFile(absoluteFilePath, markdown.toString(), 'utf8', cb);
                                }
                            ], cb);
                        });
                    }

                    tasks.push(function (cb) {
                        async.waterfall([
                            function (cb) {
                                debug('generating html for: %s', file);
                                markdown.toHtml(options).then(function (html) {
                                    cb(null, html);
                                }).catch(cb);
                            },
                            function (html, cb) {
                                data.contents = Buffer.from(html);
                                delete files[file];
                                debug('converting file: %s', file);
                                var dir = dirname(file);
                                var htmlFile = basename(file, extname(file)) + '.html';
                                if ('.' !== dir) { htmlFile = dir + '/' + htmlFile; }
                                files[htmlFile] = data;
                                cb();
                            }
                        ], cb);
                    });

                    async.series(tasks, cb);
                }, cb);
            }
        ], next);
    };
};
<commit_msg>Stop evaluating the code snippets twice when updating examples<commit_after>/* global global */
var UnexpectedMarkdown = require('unexpected-markdown');
var basename = require('path').basename;
var debug = require('debug')('metalsmith-unexpected-markdown');
var dirname = require('path').dirname;
var resolve = require('path').resolve;
var extname = require('path').extname;
var fs = require('fs');
var async = require('async');
var extend = require('extend');

module.exports = function plugin(pluginOptions) {
    pluginOptions = pluginOptions || {};

    return function (files, metalsmith, next) {
        var sourcePath = metalsmith.source();

        async.series([
            function (cb) {
                var markdownFiles = Object.keys(files).filter(function (file) {
                    return /\.md|\.markdown/.test(extname(file));
                }).sort();

                async.eachSeries(markdownFiles, function (file, cb) {
                    debug('checking file: %s', file);
                    var theme = files[file].theme;
                    var data = files[file];
                    var options = extend({}, { theme: theme }, pluginOptions);

                    var tasks = [];
                    if (options.updateExamples) {
                        tasks.push(function (cb) {
                            debug('updating examples in file: %s', file);
                            var absoluteFilePath = resolve(sourcePath, file);
                            async.waterfall([
                                function (cb) {
                                    // read file again to avoid removing metadata from the file
                                    fs.readFile(absoluteFilePath, cb);
                                },
                                function (data, cb) {
                                    new UnexpectedMarkdown(data.toString()).withUpdatedExamples(options).then(function (markdownForFile) {
                                        cb(null, markdownForFile);
                                    }).catch(cb);
                                },
                                function (markdown, cb) {
                                    fs.writeFile(absoluteFilePath, markdown.toString(), 'utf8', cb);
                                }
                            ], cb);
                        });
                    }

                    tasks.push(function (cb) {
                        async.waterfall([
                            function (cb) {
                                debug('generating html for: %s', file);

                                var content = data.contents.toString();
                                new UnexpectedMarkdown(content).toHtml(options).then(function (html) {
                                    cb(null, html);
                                }).catch(cb);
                            },
                            function (html, cb) {
                                data.contents = Buffer.from(html);
                                delete files[file];
                                debug('converting file: %s', file);
                                var dir = dirname(file);
                                var htmlFile = basename(file, extname(file)) + '.html';
                                if ('.' !== dir) { htmlFile = dir + '/' + htmlFile; }
                                files[htmlFile] = data;
                                cb();
                            }
                        ], cb);
                    });

                    async.series(tasks, cb);
                }, cb);
            }
        ], next);
    };
};
<|endoftext|>


<commit_before><commit_msg>bytewiser l4<commit_after>var split = require('split');
var fs = require('fs');

fs.createReadStream(process.argv[2])
    .pipe(split())
    .on("data", function (data) {
        console.log(new Buffer(data));
    });<|endoftext|>


<commit_before>var jsonfile = './browscap.json';

exports.setJson = function (filename) {
  jsonfile = filename;
};

exports.getBrowser = function (userAgent) {
  var browsers, patterns, re, found, matches, browsersindex;

  patterns = require(jsonfile).patterns;
  browsers = require(jsonfile).browsers;

  // Test user agent against each browser regex
  for (var pattern in patterns) {
    if (!patterns.hasOwnProperty(pattern)) {
      continue;
    }

    re = new RegExp(pattern.replace(/@/g, ''), 'i');

    if (re.test(userAgent)) {
      patternData = patterns[pattern];
      found = false;
      matches = userAgent.match(re);
      matches.shift();

      if (matches.length === 1) {
        browsersindex = patternData;
        found = true;
      } else {
        var matchString = '@' + matches.join('|');

        if (patternData[matchString]) {
          browsersindex = patternData[matchString];
          found = true;
        }
      }

      if (found && browsers[browsersindex]) {
        var browser = {
          browser_name: userAgent,
          browser_name_regex: pattern.toLowerCase().trim()
        };
        var browserData = JSON.parse(browsers[browsersindex]);

        for (var property in browserData) {
          if (!browserData.hasOwnProperty(property)) {
            continue;
          }

          browser[property] = browserData[property];
        }

        var browserParentData = browserData;

        while (browserParentData['Parent']) {
          browserParentData = JSON.parse(browsers[browserParentData['Parent']]);

          for (var propertyParent in browserParentData) {
            if (!browserParentData.hasOwnProperty(propertyParent)) {
              continue;
            }

            if (browser.hasOwnProperty(propertyParent)) {
              continue;
            }

            browser[propertyParent] = browserParentData[propertyParent];
          }
        }

        if (browser['Parent']) {
          var userAgents = require(jsonfile).userAgents;
          browser['Parent'] = userAgents[browser['Parent']];
        }

        return browser;
      }
    }
  }

  // return default
  return {
    Comment:"Default Browser",
    Browser:"Default Browser",
    Version:"0.0",
    MajorVer:"0",
    MinorVer:"0",
    Platform:"unknown",
    Platform_Version:"unknown",
    Alpha:false,
    Beta:false,
    Win16:false,
    Win32:false,
    Win64:false,
    Frames:false,
    IFrames:false,
    Tables:false,
    Cookies:false,
    BackgroundSounds:false,
    JavaScript:false,
    VBScript:false,
    JavaApplets:false,
    ActiveXControls:false,
    isMobileDevice:false,
    isTablet:false,
    isSyndicationReader:false,
    Crawler:false,
    CssVersion:"0",
    AolVersion:"0"
  };
};
<commit_msg>update browscap.js to use actual browscap.json<commit_after>var jsonfile = './browscap.json';

exports.setJson = function (filename) {
  jsonfile = filename;
};

exports.getBrowser = function (userAgent) {
  var patterns, re;

  patterns = require(jsonfile);

  // Test user agent against each browser regex
  for (var pattern in patterns) {
    if (!patterns.hasOwnProperty(pattern)) {
      continue;
    }

    if ('GJK_Browscap_Version' === pattern || 'comments' === pattern) {
      continue;
    }

    re = new RegExp(pattern.replace(/@/g, '').replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), 'i');

    if (re.test(userAgent)) {
      var browser = {
        browser_name: userAgent,
        browser_name_regex: pattern.toLowerCase().trim()
      };
      var browserData = JSON.parse(patterns[pattern]);

      for (var property in browserData) {
        if (!browserData.hasOwnProperty(property)) {
          continue;
        }

        browser[property] = browserData[property];
      }

      var browserParentData = browserData;

      while (browserParentData['Parent']) {
        browserParentData = JSON.parse(patterns[browserParentData['Parent']]);

        for (var propertyParent in browserParentData) {
          if (!browserParentData.hasOwnProperty(propertyParent)) {
            continue;
          }

          if (browser.hasOwnProperty(propertyParent)) {
            continue;
          }

          browser[propertyParent] = browserParentData[propertyParent];
        }
      }

      if (browser['Parent']) {
        browser['Parent'] = patterns[browser['Parent']];
      }

      return browser;
    }
  }

  // return default
  return {
    Comment:"Default Browser",
    Browser:"Default Browser",
    Version:"0.0",
    MajorVer:"0",
    MinorVer:"0",
    Platform:"unknown",
    Platform_Version:"unknown",
    Alpha:false,
    Beta:false,
    Win16:false,
    Win32:false,
    Win64:false,
    Frames:false,
    IFrames:false,
    Tables:false,
    Cookies:false,
    BackgroundSounds:false,
    JavaScript:false,
    VBScript:false,
    JavaApplets:false,
    ActiveXControls:false,
    isMobileDevice:false,
    isTablet:false,
    isSyndicationReader:false,
    Crawler:false,
    CssVersion:"0",
    AolVersion:"0"
  };
};
<|endoftext|>


<commit_before>var config = require('config');

module.exports  = function(request,response,next) {
  var contentType = request.headers["Content-Type"];
  var query = "";
  request.sparqlQuery = {};

  if (request.body && request.body.query) {
          if (request.body.query.length > config.get('app.maxQueryLength')) {
            response.status(413)
            .send("Query text over " + config.get('app.maxQueryLength') + " bytes is not allowed.\n")
          } else {
                request.sparqlQuery = request.body;
                next();
          } //end of else
  } else if (request.query.query) {
          query = request.query.query;
          if (query.length > config.get('app.maxQueryLength')) {
            response.status(413)
            .send("Query text over " + config.get('app.maxQueryLength') + " bytes is not allowed.\n")
          } else {
                request.sparqlQuery = request.query;
                next();
          } //end of else
  }
  else {
    var message = "You must pass your SPARQL query either as a JSON object, with 'Content-Type: application/json' header:\n\n"
    + "Example: {\"query\": \"select * where {?s ?p ?o} limit 10\", \"endpoint\":\"http://somedomain.net/sparql\"}\n\n"
    + "or as URL encoded parameters:\n\n"
    + "Example: " + siteRootUrl + request.path + "?query=" + encodeURIComponent("?select * where {?s ?p ?o} limit 10")
    + "&endpoint=" + encodeURIComponent("http://somedomain.net/sparql") + "\n\n"
    + "In any case, if no endpoint URL is provided, the default endpoint will be used.";
    response.status(400)
    .send(message)
  }
}
<commit_msg>Added debug info<commit_after>var config = require('config');
var debug = require('debug')('routes');

module.exports  = function(request,response,next) {
  var query = "";
  request.sparqlQuery = {};

  if (request.body && request.body.query) {
    debug("Request JSON body: " + JSON.stringify(request.body));
          if (request.body.query.length > config.get('app.maxQueryLength')) {
            response.status(413)
            .send("Query text over " + config.get('app.maxQueryLength') + " bytes is not allowed.\n")
          } else {
                request.sparqlQuery = request.body;
                next();
          } //end of else
  } else if (request.query.query) {
          query = request.query.query;
          if (query.length > config.get('app.maxQueryLength')) {
            response.status(413)
            .send("Query text over " + config.get('app.maxQueryLength') + " bytes is not allowed.\n")
          } else {
                request.sparqlQuery = request.query;
                next();
          } //end of else
  }
  else {
    var message = "You must pass your SPARQL query either as a JSON object, with 'Content-Type: application/json' header:\n\n"
    + "Example: {\"query\": \"select * where {?s ?p ?o} limit 10\", \"endpoint\":\"http://somedomain.net/sparql\"}\n\n"
    + "or as URL encoded parameters:\n\n"
    + "Example: " + siteRootUrl + request.path + "?query=" + encodeURIComponent("?select * where {?s ?p ?o} limit 10")
    + "&endpoint=" + encodeURIComponent("http://somedomain.net/sparql") + "\n\n"
    + "In any case, if no endpoint URL is provided, the default endpoint will be used.";
    response.status(400)
    .send(message)
  }
}
<|endoftext|>


<commit_before>const utils = require('../../utils/utils.js');

class ConsoleListener {
    constructor(embark, options) {
        this.logger = embark.logger;
        this.ipc = options.ipc;
        this.addressToContract = [];
        this.contractsConfig = embark.config.contractsConfig;
        this.listenForLogRequests();
    }

    _updateContractList(){
        Object.keys(this.contractsConfig.contracts).forEach(contractName => {
            let contract = this.contractsConfig.contracts[contractName];
            let address = contract.deployedAddress.toLowerCase();

            if(!this.addressToContract[address]){
                let funcSignatures = {};
                contract.abiDefinition
                    .filter(func => func.type == "function")
                    .map(func => {
                                return {
                                    name: func.name +
                                            '(' +
                                            (func.inputs ? func.inputs.map(input => input.type).join(',') : '') +
                                            ')',
                                    abi: func,
                                    functionName: func.name
                                };
                        })
                    .forEach(func => {
                        funcSignatures[utils.sha3(func.name).substring(0, 10)] = func;
                    });

                this.addressToContract[address] = {
                    name: contractName,
                    functions: funcSignatures
                };
            }
        });
    }

    listenForLogRequests(){
        if(this.ipc.ipcRole === 'server'){
            this.ipc.on('log', (request) => {
                if(request.type == 'contract-log'){

                    let {address, data, transactionHash, blockNumber, gasUsed, status} = request;
                    if(!this.addressToContract[address]){
                        this._updateContractList();
                    }

                    let name = this.addressToContract[address].name;
                    let func = this.addressToContract[address].functions[data.substring(0, 10)];
                    let functionName = func.functionName;

                    let decodedParameters = utils.decodeParams(func.abi.inputs, data.substring(10));
                    let paramString = "";
                    if(func.abi.inputs){
                        func.abi.inputs.forEach((input) => {
                            let quote = input.type.indexOf("int") == -1 ? '"' : '';
                            paramString +=   quote + decodedParameters[input.name] + quote + ", ";
                        });
                        paramString = paramString.substring(0, paramString.length - 2);
                    }

                    gasUsed = utils.hexToNumber(gasUsed);
                    blockNumber = utils.hexToNumber(blockNumber);

                    this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`);
                } else {
                    this.logger.debug(request);
                }
            });
        }
    }
}

module.exports = ConsoleListener;
<commit_msg>Displays json as a string in the console<commit_after>const utils = require('../../utils/utils.js');

class ConsoleListener {
    constructor(embark, options) {
        this.logger = embark.logger;
        this.ipc = options.ipc;
        this.addressToContract = [];
        this.contractsConfig = embark.config.contractsConfig;
        this.listenForLogRequests();
    }

    _updateContractList(){
        Object.keys(this.contractsConfig.contracts).forEach(contractName => {
            let contract = this.contractsConfig.contracts[contractName];
            let address = contract.deployedAddress.toLowerCase();

            if(!this.addressToContract[address]){
                let funcSignatures = {};
                contract.abiDefinition
                    .filter(func => func.type == "function")
                    .map(func => {
                                return {
                                    name: func.name +
                                            '(' +
                                            (func.inputs ? func.inputs.map(input => input.type).join(',') : '') +
                                            ')',
                                    abi: func,
                                    functionName: func.name
                                };
                        })
                    .forEach(func => {
                        funcSignatures[utils.sha3(func.name).substring(0, 10)] = func;
                    });

                this.addressToContract[address] = {
                    name: contractName,
                    functions: funcSignatures
                };
            }
        });
    }

    listenForLogRequests(){
        if(this.ipc.ipcRole === 'server'){
            this.ipc.on('log', (request) => {
                if(request.type == 'contract-log'){

                    let {address, data, transactionHash, blockNumber, gasUsed, status} = request;
                    if(!this.addressToContract[address]){
                        this._updateContractList();
                    }

                    let name = this.addressToContract[address].name;
                    let func = this.addressToContract[address].functions[data.substring(0, 10)];
                    let functionName = func.functionName;

                    let decodedParameters = utils.decodeParams(func.abi.inputs, data.substring(10));
                    let paramString = "";
                    if(func.abi.inputs){
                        func.abi.inputs.forEach((input) => {
                            let quote = input.type.indexOf("int") == -1 ? '"' : '';
                            paramString +=   quote + decodedParameters[input.name] + quote + ", ";
                        });
                        paramString = paramString.substring(0, paramString.length - 2);
                    }

                    gasUsed = utils.hexToNumber(gasUsed);
                    blockNumber = utils.hexToNumber(blockNumber);

                    this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`);
                } else {
                    this.logger.debug(JSON.stringify(request));
                }
            });
        }
    }
}

module.exports = ConsoleListener;
<|endoftext|>


<commit_before>/* jshint mocha: true */
// TODO: wtf, jshint doesn't know about `KeyboardEvent` object?
/* global KeyboardEvent */
"use strict";

const debug = require('debug')('test-events');

const helper = require('./helper');
const assert = require('./assert/dom');

const WidgetEvent = require('../lib/widget-event');

const test_html = `

`;

function createMouseEvent(type, button, options) {
	options = options || {};
	options.button = button;
	return new MouseEvent(type, options);
}

function triggerMouseEvent(element, type, button, options) {
	let evt = createMouseEvent(type, button, options);
	return element.dispatch(evt);
}

function createKeyEvent(type, code, options) {
	options = options || {};
	options.code = code;
	return new KeyboardEvent(type, options);
}

function triggerKeyEvent(element, type, key, options) {
	let evt = createKeyEvent(type, key, options);
	return element.dispatch(evt);
}

describe('Widget Events', () => {
	let body;
	let target;

	beforeEach(() => {
		// clean up test html body
		document.body.innerHTML = test_html;

		// prepare target elements for each test
		body = document.body;
		target = helper.query('#target');
	});

	describe('WidgetEvent', () => {

		describe('constructor', () => {
			it('should throw Error with missing element', () => {
				assert(() => {
					let dummy = new WidgetEvent();
				}).throws(Error, 'Should throw Error for missing element.');
			});

			it('should throw Error when passing string as element', () => {
				assert(() => {
					let dummy = new WidgetEvent('Hello');
				}).throws(Error, 'Should throw Error for missing element.');
			});

			it('should throw Error when passing object as element', () => {
				assert(() => {
					let dummy = new WidgetEvent({});
				}).throws(Error, 'Should throw Error for missing element.');
			});
		});

		describe('formatSelector', () => {
			it('should throw Error with non-string selector', () => {
				assert(() => {
					WidgetEvent.parseSelector({});
				}).throws(Error);
			});

			it('should parse selector parts', () => {
				let parts;
				function assertParts(parts, which, alt, ctrl, shift, meta) {
					assert(parts.which).equal(which);
					assert(parts.alt).strictEqual(alt);
					assert(parts.ctrl).strictEqual(ctrl);
					assert(parts.shift).strictEqual(shift);
					assert(parts.meta).strictEqual(meta);
				}

				parts = WidgetEvent.parseSelector('Space');
				assertParts(parts, 'space', false, false, false, false);

				parts = WidgetEvent.parseSelector('Ctrl+Space');
				assertParts(parts, 'space', false, true, false, false);

				parts = WidgetEvent.parseSelector('Alt+Ctrl+Space');
				assertParts(parts, 'space', true, true, false, false);

				parts = WidgetEvent.parseSelector('Space+Alt+Shift+Ctrl');
				assertParts(parts, 'space', true, true, true, false);

				parts = WidgetEvent.parseSelector('Space+Shift');
				assertParts(parts, 'space', false, false, true, false);

				parts = WidgetEvent.parseSelector('Shift+KeyD+Ctrl');
				assertParts(parts, 'keyd', false, true, true, false);

				parts = WidgetEvent.parseSelector('Shift+Alt+enter+Ctrl+Meta');
				assertParts(parts, 'enter', true, true, true, true);

				parts = WidgetEvent.parseSelector(' Shift + Alt + enter + Ctrl + Meta  ');
				assertParts(parts, 'enter', true, true, true, true);

				parts = WidgetEvent.parseSelector('Space+KeyD+Enter');
				assertParts(parts, 'enter', false, false, false, false);
			});
		});

		describe('normalizeSelector', () => {
			it('should normalize without modifiers', () => {
				assert(WidgetEvent.normalizeSelector('Space')).equal('space');
				assert(WidgetEvent.normalizeSelector('KeyD')).equal('keyd');
				assert(WidgetEvent.normalizeSelector(' enter ')).equal('enter');
			});

			it('should normalize with modifiers', () => {
				assert(WidgetEvent.normalizeSelector('Alt+Space')).equal('alt+space');
				assert(WidgetEvent.normalizeSelector('Shift + Space')).equal('shift+space');
			});

			it('should normalize the order', () => {
				assert(WidgetEvent.normalizeSelector('Space+Ctrl')).equal('ctrl+space');
				assert(WidgetEvent.normalizeSelector('Meta+Space+Shift')).equal('shift+meta+space');
				assert(WidgetEvent.normalizeSelector('Alt+Space+Meta+Ctrl+Shift')).equal('alt+ctrl+shift+meta+space');
			});

			it('should remove duplicates', () => {
				assert(WidgetEvent.normalizeSelector('Space+Space+Ctrl+Ctrl')).equal('ctrl+space');
			});

			it('should only take last which', () => {
				assert(WidgetEvent.normalizeSelector('Space+Enter')).equal('enter');
			});
		});

		describe('parseEventSelector', () => {
			function assertEvent(actual, type, name, selector, event) {
				assert(actual.type).equal(type);
				assert(actual.name).equal(name);
				assert(actual.selector).equal(selector);
				assert(actual.event).equal(event);
			}

			it('should parse type', () => {
				let actual = WidgetEvent.parseEventSelector('mouse');
				assertEvent(actual, 'mouse');
			});

			it('should parse type and name', () => {
				let actual = WidgetEvent.parseEventSelector('mouse:click');
				assertEvent(actual, 'mouse', 'click', undefined, 'click');
			});

			it('should parse type, name and selector', () => {
				let actual = WidgetEvent.parseEventSelector('key:press:Ctrl+Space');
				assertEvent(actual, 'key', 'press', 'ctrl+space', 'keypress');
			});

			it('should map event to dom event', () => {
				let actual = WidgetEvent.parseEventSelector('key:press:enter');
				assertEvent(actual, 'key', 'press', 'enter', 'keypress');
			});

			it('should have undefined `event` for non dom event', () => {
				let actual = WidgetEvent.parseEventSelector('hello');
				assertEvent(actual, 'hello');
				actual = WidgetEvent.parseEventSelector('hello:world');
				assertEvent(actual, 'hello', 'world');
			});
		});

		describe('eventMap', () => {

		});

		describe('getEventTypes', () => {
			it('should return list of all event types', () => {
				let expected = [
					'mouse',
					'key',
				];
				assert(WidgetEvent.getEventTypes()).deepEqual(expected);
			});
		});

		describe('getEventNames', () => {
			it('should return list of all event names in type', () => {
				let expected = [
					'key:press',
					'key:down',
					'key:up',
				];
				assert(WidgetEvent.getEventNames('key')).deepEqual(expected);
			});
		});

		describe('getDOMEventName', () => {
			it('should return mapped DOM event', () => {
				let expected = 'keypress';
				assert(WidgetEvent.getDOMEventName('key', 'press')).equal(expected);
			});

			it('should return null if not found', () => {
				assert(WidgetEvent.getDOMEventName('hello', 'world')).isNull();
				assert(WidgetEvent.getDOMEventName('key', 'hello')).isNull();
			});
		});
	});

});
<commit_msg>UNIT: Remove unused test case<commit_after>/* jshint mocha: true */
// TODO: wtf, jshint doesn't know about `KeyboardEvent` object?
/* global KeyboardEvent */
"use strict";

const debug = require('debug')('test-events');

const helper = require('./helper');
const assert = require('./assert/dom');

const WidgetEvent = require('../lib/widget-event');

const test_html = `

`;

function createMouseEvent(type, button, options) {
	options = options || {};
	options.button = button;
	return new MouseEvent(type, options);
}

function triggerMouseEvent(element, type, button, options) {
	let evt = createMouseEvent(type, button, options);
	return element.dispatch(evt);
}

function createKeyEvent(type, code, options) {
	options = options || {};
	options.code = code;
	return new KeyboardEvent(type, options);
}

function triggerKeyEvent(element, type, key, options) {
	let evt = createKeyEvent(type, key, options);
	return element.dispatch(evt);
}

describe('Widget Events', () => {
	let body;
	let target;

	beforeEach(() => {
		// clean up test html body
		document.body.innerHTML = test_html;

		// prepare target elements for each test
		body = document.body;
		target = helper.query('#target');
	});

	describe('WidgetEvent', () => {

		describe('constructor', () => {
			it('should throw Error with missing element', () => {
				assert(() => {
					let dummy = new WidgetEvent();
				}).throws(Error, 'Should throw Error for missing element.');
			});

			it('should throw Error when passing string as element', () => {
				assert(() => {
					let dummy = new WidgetEvent('Hello');
				}).throws(Error, 'Should throw Error for missing element.');
			});

			it('should throw Error when passing object as element', () => {
				assert(() => {
					let dummy = new WidgetEvent({});
				}).throws(Error, 'Should throw Error for missing element.');
			});
		});

		describe('formatSelector', () => {
			it('should throw Error with non-string selector', () => {
				assert(() => {
					WidgetEvent.parseSelector({});
				}).throws(Error);
			});

			it('should parse selector parts', () => {
				let parts;
				function assertParts(parts, which, alt, ctrl, shift, meta) {
					assert(parts.which).equal(which);
					assert(parts.alt).strictEqual(alt);
					assert(parts.ctrl).strictEqual(ctrl);
					assert(parts.shift).strictEqual(shift);
					assert(parts.meta).strictEqual(meta);
				}

				parts = WidgetEvent.parseSelector('Space');
				assertParts(parts, 'space', false, false, false, false);

				parts = WidgetEvent.parseSelector('Ctrl+Space');
				assertParts(parts, 'space', false, true, false, false);

				parts = WidgetEvent.parseSelector('Alt+Ctrl+Space');
				assertParts(parts, 'space', true, true, false, false);

				parts = WidgetEvent.parseSelector('Space+Alt+Shift+Ctrl');
				assertParts(parts, 'space', true, true, true, false);

				parts = WidgetEvent.parseSelector('Space+Shift');
				assertParts(parts, 'space', false, false, true, false);

				parts = WidgetEvent.parseSelector('Shift+KeyD+Ctrl');
				assertParts(parts, 'keyd', false, true, true, false);

				parts = WidgetEvent.parseSelector('Shift+Alt+enter+Ctrl+Meta');
				assertParts(parts, 'enter', true, true, true, true);

				parts = WidgetEvent.parseSelector(' Shift + Alt + enter + Ctrl + Meta  ');
				assertParts(parts, 'enter', true, true, true, true);

				parts = WidgetEvent.parseSelector('Space+KeyD+Enter');
				assertParts(parts, 'enter', false, false, false, false);
			});
		});

		describe('normalizeSelector', () => {
			it('should normalize without modifiers', () => {
				assert(WidgetEvent.normalizeSelector('Space')).equal('space');
				assert(WidgetEvent.normalizeSelector('KeyD')).equal('keyd');
				assert(WidgetEvent.normalizeSelector(' enter ')).equal('enter');
			});

			it('should normalize with modifiers', () => {
				assert(WidgetEvent.normalizeSelector('Alt+Space')).equal('alt+space');
				assert(WidgetEvent.normalizeSelector('Shift + Space')).equal('shift+space');
			});

			it('should normalize the order', () => {
				assert(WidgetEvent.normalizeSelector('Space+Ctrl')).equal('ctrl+space');
				assert(WidgetEvent.normalizeSelector('Meta+Space+Shift')).equal('shift+meta+space');
				assert(WidgetEvent.normalizeSelector('Alt+Space+Meta+Ctrl+Shift')).equal('alt+ctrl+shift+meta+space');
			});

			it('should remove duplicates', () => {
				assert(WidgetEvent.normalizeSelector('Space+Space+Ctrl+Ctrl')).equal('ctrl+space');
			});

			it('should only take last which', () => {
				assert(WidgetEvent.normalizeSelector('Space+Enter')).equal('enter');
			});
		});

		describe('parseEventSelector', () => {
			function assertEvent(actual, type, name, selector, event) {
				assert(actual.type).equal(type);
				assert(actual.name).equal(name);
				assert(actual.selector).equal(selector);
				assert(actual.event).equal(event);
			}

			it('should parse type', () => {
				let actual = WidgetEvent.parseEventSelector('mouse');
				assertEvent(actual, 'mouse');
			});

			it('should parse type and name', () => {
				let actual = WidgetEvent.parseEventSelector('mouse:click');
				assertEvent(actual, 'mouse', 'click', undefined, 'click');
			});

			it('should parse type, name and selector', () => {
				let actual = WidgetEvent.parseEventSelector('key:press:Ctrl+Space');
				assertEvent(actual, 'key', 'press', 'ctrl+space', 'keypress');
			});

			it('should map event to dom event', () => {
				let actual = WidgetEvent.parseEventSelector('key:press:enter');
				assertEvent(actual, 'key', 'press', 'enter', 'keypress');
			});

			it('should have undefined `event` for non dom event', () => {
				let actual = WidgetEvent.parseEventSelector('hello');
				assertEvent(actual, 'hello');
				actual = WidgetEvent.parseEventSelector('hello:world');
				assertEvent(actual, 'hello', 'world');
			});
		});

		describe('getEventTypes', () => {
			it('should return list of all event types', () => {
				let expected = [
					'mouse',
					'key',
				];
				assert(WidgetEvent.getEventTypes()).deepEqual(expected);
			});
		});

		describe('getEventNames', () => {
			it('should return list of all event names in type', () => {
				let expected = [
					'key:press',
					'key:down',
					'key:up',
				];
				assert(WidgetEvent.getEventNames('key')).deepEqual(expected);
			});
		});

		describe('getDOMEventName', () => {
			it('should return mapped DOM event', () => {
				let expected = 'keypress';
				assert(WidgetEvent.getDOMEventName('key', 'press')).equal(expected);
			});

			it('should return null if not found', () => {
				assert(WidgetEvent.getDOMEventName('hello', 'world')).isNull();
				assert(WidgetEvent.getDOMEventName('key', 'hello')).isNull();
			});
		});
	});

});
<|endoftext|>


<commit_before>// The MESSAGE event runs anytime a message is received
// Note that due to the binding of client to every event, every event
// goes `client, other, args` when this function is run.

module.exports = (client, message) => {
  // It's good practice to ignore other bots. This also makes your bot ignore itself
  // and not get into a spam loop (we call that "botception").
  if (message.author.bot) return;

  // Grab the settings for this server from the PersistentCollection
  const settings = client.settings.get(message.guild.id);

  // For ease of use in commands and functions, we'll attach the settings
  // to the message object, so `message.settings` is accessible.
  message.settings = settings;

  // Also good practice to ignore any message that does not start with our prefix,
  // which is set in the configuration file.
  if (message.content.indexOf(settings.prefix) !== 0) return;

  // Here we separate our "command" name, and our "arguments" for the command.
  // e.g. if we have the message "+say Is this the real life?" , we'll get the following:
  // command = say
  // args = ["Is", "this", "the", "real", "life?"]
  const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
  const command = args.shift().toLowerCase();

  // Get the user or member's permission level from the elevation
  const level = client.permlevel(message);

  // Check whether the command, or alias, exist in the collections defined
  // in app.js.
  const cmd = client.commands.get(command) || client.commands.get(client.aliases.get(command));
  // using this const varName = thing OR otherthign; is a pretty efficient
  // and clean way to grab one of 2 values!

  // If the command exists, **AND** the user has permission, run it.
  if (cmd && level >= cmd.conf.permLevel) {
    client.log("log", `${message.guild.name}/#${message.channel.name}:
      ${message.author.username} (${message.author.id}) ran command ${cmd.help.name}`, "CMD");
    cmd.run(client, message, args, level);
  }
  // Best Practice: **do not** reply with a message if the command does
  // not exist, or permissions lack.
};
<commit_msg>Removed crash when receiving DMs (with configs)<commit_after>// The MESSAGE event runs anytime a message is received
// Note that due to the binding of client to every event, every event
// goes `client, other, args` when this function is run.

module.exports = (client, message) => {
  // It's good practice to ignore other bots. This also makes your bot ignore itself
  // and not get into a spam loop (we call that "botception").
  if (message.author.bot) return;

  // Grab the settings for this server from the PersistentCollection
  // If there is no guild, get default conf (DMs)
  const settings = !!message.guild
    ? client.settings.get(message.guild.id)
    : client.config.defaultSettings;

  // For ease of use in commands and functions, we'll attach the settings
  // to the message object, so `message.settings` is accessible.
  message.settings = settings;

  // Also good practice to ignore any message that does not start with our prefix,
  // which is set in the configuration file.
  if (message.content.indexOf(settings.prefix) !== 0) return;

  // Here we separate our "command" name, and our "arguments" for the command.
  // e.g. if we have the message "+say Is this the real life?" , we'll get the following:
  // command = say
  // args = ["Is", "this", "the", "real", "life?"]
  const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
  const command = args.shift().toLowerCase();

  // Get the user or member's permission level from the elevation
  const level = client.permlevel(message);

  // Check whether the command, or alias, exist in the collections defined
  // in app.js.
  const cmd = client.commands.get(command) || client.commands.get(client.aliases.get(command));
  // using this const varName = thing OR otherthign; is a pretty efficient
  // and clean way to grab one of 2 values!

  // If the command exists, **AND** the user has permission, run it.
  if (cmd && level >= cmd.conf.permLevel) {
    client.log("log", `${message.author.username} (${message.author.id}) ran command ${cmd.help.name}`, "CMD");
    cmd.run(client, message, args, level);
  }
  // Best Practice: **do not** reply with a message if the command does
  // not exist, or permissions lack.
};
<|endoftext|>