<commit_before>'use strict';
var express = require('express')
  , app = express()
  , server = require('http').createServer(app)
  , socket = require('socket.io')
exports.name = 'express-socket.io'
exports.description = 'express HTTP Server with Socket.IO support'
exports.server = server
exports.start = function(apx,fn){
  //conditionally setup socket.io
  if(!apx.config.exists('socket-io.enabled') || true === apx.config.get('socket-io.enabled')){
    var io = socket.listen(server)
      , logLevel = apx.config.exists('socket-io.logLevel') ? apx.config.get('socket-io.logLevel') : null
    //set default log level for socket.io
    io.set('log level',(null !== logLevel ? logLevel : 3))
    //setup redis store for socket.io for multiple processes
    if('production' === process.env.NODE_ENV){
      apx.log.info('using redis for socket.io store in production')
      var redis = require('redis')
        , RedisStore = require('socket.io/lib/stores/redis')
      io.set('store',new RedisStore({
        redisPub: redis.createClient(),
        redisSub: redis.createClient(),
        redisClient: redis.createClient()
      }))
      io.set('log level',(null !== logLevel ? logLevel : 0))
    }
    //setup socket routing
    if(apx.config.exists('socket-io.routes')){
      io.sockets.on('connection',function(socket){
        apx.config.get('socket-io.routes').forEach(function(route){
          var methods = route.methods
          if(undefined === route.methods)
            methods = ['']
          else if('string' === typeof route.methods)
            methods = [route.methods]
          methods.forEach(function(method){
            var verb = Object.keys(route)[0]
              , path = method ? verb + ':' + method : verb
            socket.on(path,function(data,fn){
              apx.runAction(
                route[verb],
                data,
                method || 'run',
                function(response){
                  fn(response.json || {data: response.rendered})
                }
              )
            })
          })
        })
      })
    }
  }
  //setup express
  //express middleware
  if(
    (!apx.config.exists('express.logger') && 'production' !== process.env.NODE_ENV) ||
    apx.config.get('express.logger')
  ){
    app.use(express.logger('dev'))
  }
  app.use(express.json())
  app.use(express.urlencoded())
  //setup http routing
  if(apx.config.exists('express.routes')){
    apx.config.get('express.routes').forEach(function(route){
      var methods = route.methods
      if(undefined === route.methods)
        methods = ['']
      else if('string' === typeof route.methods)
        methods = [route.methods]
      methods.forEach(function(method){
        var verb = Object.keys(route)[0]
          , path = method ? route[verb].path + '/' + method : route[verb].path
        app[verb](path,function(req,res){
          apx.runAction(
            route[verb].file,
            req.data,
            method || 'run',
            function(response){
              res.send(response.rendered)
            }
          )
        })
      })
    })
  }
  server.listen(apx.config.get('express.port') || 3000,apx.config.get('express.host'),fn)
}
exports.stop = function(apx,fn){
  server.close(fn)
}<commit_msg>small fix with rendering of express and socket io from new apx format<commit_after>'use strict';
var express = require('express')
  , app = express()
  , server = require('http').createServer(app)
  , socket = require('socket.io')
exports.name = 'express-socket.io'
exports.description = 'express HTTP Server with Socket.IO support'
exports.server = server
exports.start = function(apx,fn){
  //conditionally setup socket.io
  if(!apx.config.exists('socket-io.enabled') || true === apx.config.get('socket-io.enabled')){
    var io = socket.listen(server)
      , logLevel = apx.config.exists('socket-io.logLevel') ? apx.config.get('socket-io.logLevel') : null
    //set default log level for socket.io
    io.set('log level',(null !== logLevel ? logLevel : 3))
    //setup redis store for socket.io for multiple processes
    if('production' === process.env.NODE_ENV){
      apx.log.info('using redis for socket.io store in production')
      var redis = require('redis')
        , RedisStore = require('socket.io/lib/stores/redis')
      io.set('store',new RedisStore({
        redisPub: redis.createClient(),
        redisSub: redis.createClient(),
        redisClient: redis.createClient()
      }))
      io.set('log level',(null !== logLevel ? logLevel : 0))
    }
    //setup socket routing
    if(apx.config.exists('socket-io.routes')){
      io.sockets.on('connection',function(socket){
        apx.config.get('socket-io.routes').forEach(function(route){
          var methods = route.methods
          if(undefined === route.methods)
            methods = ['']
          else if('string' === typeof route.methods)
            methods = [route.methods]
          methods.forEach(function(method){
            var verb = Object.keys(route)[0]
              , path = method ? verb + ':' + method : verb
            socket.on(path,function(data,fn){
              apx.runAction(
                route[verb],
                data,
                method || 'run',
                function(err,response){
                  if(err){
                    response.error(err)
                  }
                  fn(response.json || {body: response.rendered})
                }
              )
            })
          })
        })
      })
    }
  }
  //setup express
  //express middleware
  if(
    (!apx.config.exists('express.logger') && 'production' !== process.env.NODE_ENV) ||
    apx.config.get('express.logger')
  ){
    app.use(express.logger('dev'))
  }
  app.use(express.json())
  app.use(express.urlencoded())
  //setup http routing
  if(apx.config.exists('express.routes')){
    apx.config.get('express.routes').forEach(function(route){
      var methods = route.methods
      if(undefined === route.methods)
        methods = ['']
      else if('string' === typeof route.methods)
        methods = [route.methods]
      methods.forEach(function(method){
        var verb = Object.keys(route)[0]
          , path = method ? route[verb].path + '/' + method : route[verb].path
        app[verb](path,function(req,res){
          apx.runAction(
            route[verb].file,
            req.data,
            method || 'run',
            function(err,response){
              if(err){
                response.error(err)
              }
              res.send(response.rendered)
            }
          )
        })
      })
    })
  }
  server.listen(apx.config.get('express.port') || 3000,apx.config.get('express.host'),fn)
}
exports.stop = function(apx,fn){
  server.close(fn)
}<|endoftext|>


<commit_before>class Negotiation {
  constructor(amount, date, value) {
    this._amount = amount;
    this._date = new Date(date.getTime());
    this._value = value;
    Object.freeze(this);
  }

  get amount() {
    return this._amount;
  }

  get date() {
    return new Date(this._date.getTime());
  }

  get value() {
    return this._value;
  }

  get volume() {
    return this._amount * this._value;
  }
}
<commit_msg>fix negotiation ,order parameters<commit_after>class Negotiation {
  constructor(date, amount, value) {
    this._date = new Date(date.getTime());
    this._amount = amount;
    this._value = value;
    Object.freeze(this);
  }

  get amount() {
    return this._amount;
  }

  get date() {
    return new Date(this._date.getTime());
  }

  get value() {
    return this._value;
  }

  get volume() {
    return this._amount * this._value;
  }
}
<|endoftext|>


<commit_before>angular.module('app')
    .directive('scatterPlot', function() {
        return {
            link: function(scope, element, attr) {
                var compiler_runs_data = [];
                var useLogBubbleSize = true;
                showUserThePerformanceTestDetails = function(json) {
                    var jsonForServer = {
                        "backend": {
                            "name": "Octave",
                            "version": "3.4.3",
                        },
                        "benchmark": {
                            "name": "escoufier",
                            "version": "1.0",
                            "iteration": 3,
                            "scale": 22,
                        }
                    };
                    jsonForServer.backend.version = json.backendVersion;
                    jsonForServer.backend.name = json.backendName;

                    jsonForServer.benchmark.name = json.benchmarkName;
                    jsonForServer.benchmark.version = json.benchmarkVersion;
                    jsonForServer.benchmark.iteration = json.iteration;
                    jsonForServer.benchmark.scale = json.scale;

                    scope.$apply(function () {
                        scope.$emit("openExperimentRunner", jsonForServer);
                    })
                };

                var drawScatterPlot = function() {

                    console.log(compiler_runs_data);

                    var clearPreviousPlots = true;
                    if (clearPreviousPlots) {
                        element.html("");
                    }
                    var w = element.width(),
                        h = 300,
                        pad = 20,
                        left_pad = 100;

                    var svg = d3.select(element[0])
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

                    /* Get the max values from the JSON to determine the axis lengths */
                    var max_value_of_x = Math.max.apply(Math,
                        compiler_runs_data.map(function(d) {
                            return d.scale;
                        }));
                    var max_value_of_y = Math.max.apply(Math,
                        compiler_runs_data.map(function(d) {
                            return d.runtime;
                        }));

                    var x = d3.scale.linear().domain([0, max_value_of_x]).range([left_pad, w - pad]),
                        y = d3.scale.linear().domain([max_value_of_y, 0]).range([pad, h - pad * 2]);

                    /* basic axis */
                    var xAxis = d3.svg.axis().scale(x).orient("bottom"),
                        yAxis = d3.svg.axis().scale(y).orient("left");

                    svg.append("g")
                        .attr("class", "axis")
                        .attr("transform", "translate(0, " + (h - pad) + ")")
                        .call(xAxis);

                    svg.append("g")
                        .attr("class", "axis")
                        .attr("transform", "translate(" + (left_pad - pad) + ", 0)")
                        .call(yAxis);

                    /* Show Loading until the data loads */
                    svg.append("text")
                        .attr("class", "loading")
                        .text("Loading ...")
                        .attr("x", function() {
                            return w / 2;
                        })
                        .attr("y", function() {
                            return h / 2 - 5;
                        });

                    var max_r = d3.max(compiler_runs_data.map(
                        function(d) {
                            return d[2];
                        })),
                        r = d3.scale.linear()
                            .domain([0, d3.max(compiler_runs_data, function(d) {
                                return d[2];
                            })])
                            .range([0, 12]);

                    var getXFromJson = function(object) {
                        return x(object.scale);
                    };

                    var getYFromJson = function(object) {
                        return y(object.runtime);
                    };

                    var bubbleWeight = 1;
                    var getBubbleSizeFromJson = function(object) {
                        if (useLogBubbleSize) {
                            bubbleWeight = 10;
                        } else {
                            bubbleWeight = 1;
                        }
                        var radius = object.runtime / object.iteration * bubbleWeight
                        console.log("Run time: " + object.runtime);
                        console.log("Dataset size: " + object.iteration);
                        console.log("\tRadius: " + radius);
                        if (useLogBubbleSize) {
                            radius = Math.log(radius);
                        }

                        // if (radius > 50){
                        //  radius = object.runtime/object.scale;
                        // }
                        return radius;
                    };

                    /* Make a tooltip which can show the details */
                    var tooltip = d3.select("body")
                        .append("div")
                        .style("position", "absolute")
                        .style("z-index", "10")
                        .style("visibility", "hidden")
                        .html("");

                    var color = d3.scale.category20();

                    svg.selectAll(".loading").remove();
                    svg.selectAll("circle")
                        .data(compiler_runs_data)
                        .enter()
                        .append("circle")
                        .attr("class", "circle")
                        .attr("cx", getXFromJson)
                        .attr("cy", getYFromJson)
                        .attr("r", getBubbleSizeFromJson)
                        .style("fill", function(object, i) {
                            return color(i);
                        })
                        .style("opacity", function(object, i) {
                            return ".5";
                        })
                        .on("mouseover", function(object) {
                            return tooltip
                                .style("visibility", "visible")
                                .html("
Benchmark: " + object.benchmarkName + "
 Time: " + object.runtime + "
 Dataset Size: " + object.scale + "
");
                        })
                        .on("mousemove", function(object) {
                            return tooltip.style("top", (event.pageY - 10) + "px")
                                .style("left", (event.pageX + 10) + "px");
                        })
                        .on("mouseout", function(object) {
                            return tooltip
                                .style("visibility", "hidden");
                        })
                        .on("click", function(object) {
                            showUserThePerformanceTestDetails(object);
                        });
                };
                scope.$watchCollection(attr.useLogBubbleSize, function(newValue, oldValue){
                    if (useLogBubbleSize != newValue) {
                        useLogBubbleSize = newValue;
                        return drawScatterPlot();
                    }
                });

                scope.$watchCollection(attr.scatterPlot, function(newValue, oldValue){
                    if (compiler_runs_data != newValue) {
                        compiler_runs_data = newValue;
                        return drawScatterPlot();
                    }
                });

            }
        }
    });<commit_msg>Fixed scatterPlot directive<commit_after>angular.module('app')
    .directive('scatterPlot', function() {
        return {
            link: function(scope, element, attr) {
                var compiler_runs_data = [];
                var useLogBubbleSize = true;
                showUserThePerformanceTestDetails = function(json) {
                    var jsonForServer = {
                        "backend": {
                            "name": "Octave",
                            "version": "3.4.3",
                        },
                        "benchmark": {
                            "name": "escoufier",
                            "version": "1.0",
                            "iteration": 3,
                            "scale": 22,
                        }
                    };
                    jsonForServer.backend.version = json.backendVersion;
                    jsonForServer.backend.name = json.backendName;

                    jsonForServer.benchmark.name = json.benchmarkName;
                    jsonForServer.benchmark.version = json.benchmarkVersion;
                    jsonForServer.benchmark.iteration = json.iteration;
                    jsonForServer.benchmark.scale = json.scale;

                    scope.$apply(function () {
                        scope.$emit("openExperimentRunner", jsonForServer);
                    })
                };

                var drawScatterPlot = function() {

                    console.log(compiler_runs_data);

                    var clearPreviousPlots = true;
                    if (clearPreviousPlots) {
                        element.html("");
                    }
                    var w = element.width(),
                        h = 300,
                        pad = 20,
                        left_pad = 100;

                    var svg = d3.select(element[0])
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

                    /* Get the max values from the JSON to determine the axis lengths */
                    var max_value_of_x = Math.max.apply(Math,
                        compiler_runs_data.map(function(d) {
                            return d.scale;
                        }));
                    var max_value_of_y = Math.max.apply(Math,
                        compiler_runs_data.map(function(d) {
                            return d.runtime;
                        }));

                    var x = d3.scale.linear().domain([0, max_value_of_x]).range([left_pad, w - pad]),
                        y = d3.scale.linear().domain([max_value_of_y, 0]).range([pad, h - pad * 2]);

                    /* basic axis */
                    var xAxis = d3.svg.axis().scale(x).orient("bottom"),
                        yAxis = d3.svg.axis().scale(y).orient("left");

                    svg.append("g")
                        .attr("class", "axis")
                        .attr("transform", "translate(0, " + (h - pad) + ")")
                        .call(xAxis);

                    svg.append("g")
                        .attr("class", "axis")
                        .attr("transform", "translate(" + (left_pad - pad) + ", 0)")
                        .call(yAxis);

                    /* Show Loading until the data loads */
                    svg.append("text")
                        .attr("class", "loading")
                        .text("Loading ...")
                        .attr("x", function() {
                            return w / 2;
                        })
                        .attr("y", function() {
                            return h / 2 - 5;
                        });

                    var max_r = d3.max(compiler_runs_data.map(
                        function(d) {
                            return d[2];
                        })),
                        r = d3.scale.linear()
                            .domain([0, d3.max(compiler_runs_data, function(d) {
                                return d[2];
                            })])
                            .range([0, 12]);

                    var getXFromJson = function(object) {
                        return x(object.scale);
                    };

                    var getYFromJson = function(object) {
                        return y(object.runtime);
                    };

                    var bubbleWeight = 1;
                    var getBubbleSizeFromJson = function(object) {
                        if (useLogBubbleSize) {
                            bubbleWeight = 10;
                        } else {
                            bubbleWeight = 1;
                        }
                        var radius = object.runtime / object.iteration * bubbleWeight
                        console.log("Run time: " + object.runtime);
                        console.log("Dataset size: " + object.iteration);
                        console.log("\tRadius: " + radius);
                        if (useLogBubbleSize) {
                            radius = Math.log(radius);
                        }

                        // if (radius > 50){
                        //  radius = object.runtime/object.scale;
                        // }
                        return radius;
                    };

                    /* Make a tooltip which can show the details */
                    var tooltip = d3.select("body")
                        .append("div")
                        .style("position", "absolute")
                        .style("z-index", "10")
                        .style("visibility", "hidden")
                        .html("");

                    var color = d3.scale.category20();

                    svg.selectAll(".loading").remove();
                    svg.selectAll("circle")
                        .data(compiler_runs_data)
                        .enter()
                        .append("circle")
                        .attr("class", "circle")
                        .attr("cx", getXFromJson)
                        .attr("cy", getYFromJson)
                        .attr("r", getBubbleSizeFromJson)
                        .style("fill", function(object, i) {
                            return color(i);
                        })
                        .style("opacity", function(object, i) {
                            return ".5";
                        })
                        .on("mouseover", function(object) {
                            return tooltip
                                .style("visibility", "visible")
                                .html("
Benchmark: " + object.benchmarkName + "
 Time: " + object.runtime + "
 Dataset Size: " + object.scale + "
");
                        })
                        .on("mousemove", function(object) {
                            return tooltip.style("top", (event.pageY - 10) + "px")
                                .style("left", (event.pageX + 10) + "px");
                        })
                        .on("mouseout", function(object) {
                            return tooltip
                                .style("visibility", "hidden");
                        })
                        .on("click", function(object) {
                            showUserThePerformanceTestDetails(object);
                        });
                };
                scope.$watch(attr.useLogBubbleSize, function(newValue, oldValue){
                    useLogBubbleSize = newValue;
                    return drawScatterPlot();
                });

                scope.$watchCollection(attr.scatterPlot, function(newValue, oldValue){
                    compiler_runs_data = newValue;
                    return drawScatterPlot();
                });

            }
        }
    });<|endoftext|>


<commit_before>// 3rd party dependencies: jQuery v3.2.1, mui-0.9.22
// local dependencies: functions.js

const prodApi = 'https://alchemist.digital/flashcards/api/'; // PROD API
const devApi = '../test-api/'; // TEST API

var Api = (function(){

    function Api(url){
        this.url = url || devApi;
        this.user = this.url + 'users/';
        this.decks = this.url + 'decks/userid/';
        this.cards = this.url + 'cards/deckid/';
    }

    Api.prototype.getData = function(self, type, value, success, failure){

        var url;

        switch(type){
            case 'user':
                url = this.user + value;
                break;
            case 'decks':
                url = this.decks + value;
                break;
            case 'cards':
                url = this.cards + value;
            default:
                throw Error('[ERROR] value must be "user", "decks", or "cards"');
        }

        $.getJSON(url)
        .done(function(data){
            console.log('this: ', this);
            console.log('[DEBUG] getJSON success - data found: ', data);
            if(success){
                success(data);
            }
            return data;
        }.bind(self))
        .fail(function() {
            console.log('[DEBUG] getJSON failed');
            if(failure){
                failure();
            }
            throw Error('[ERROR] getData failed');
        });
    }

    return Api;
}());

var User = (function(){

    function User(username){
        this.username = username;
        this.id = 0;
        this.decks = [];

        this.getUserId(this.username);
    }

    User.prototype.getUserId = function(username){
        $.getJSON(api.user + username)
        .done(function(data){
            this.id = data[0].id;
            this.getDecks(this.id);
        }.bind(this))
        .fail(function() {
            throw Error('[ERROR] getJSON failed');
        });
    }

    User.prototype.getDecks = function(userId){
        $.getJSON(api.decks + userId)
        .done(function(data){
            for(var i = 0; i < data.length; i++){
                this.decks.push(new Deck(data[i]));
            }
            console.log('this test:', this);
            interface.userLogin(this);
        }.bind(this))
        .fail(function() {
            throw Error('[ERROR] getJSON failed');
        });
    }

    return User;
}());

var Deck = (function(){

    function Deck(obj){
        this.title = obj.title;
        this.id = obj.id || null;
        this.stack = obj.stack;
        this.cards = [];

        this.getCards(this.id);
    }

    Deck.prototype.getCards = function(deckId){
        $.getJSON(api.cards + deckId)
        .done(function(data){
            for(var i = 0; i < data.length; i++){
                this.cards.push(new Card(data[i]));
            }
        }.bind(this))
        .fail(function() {
            throw Error('[ERROR] getJSON failed');
        });
    }

    return Deck;
}());

var Card = (function(){

    function Card(obj){
        this.front = obj.front;
        this.back = obj.back;
        this.id = obj.id || null;
    }

    return Card;
}());

var Modal = (function(){

    var _options = {
        'keyboard': true,
        'static': false,
        'onclose': function() {
                console.log('modal closed');
            }
        };

    function Modal(){
        this.element = document.getElementById('loginModal');
        this.overlay = {};
    }

    Modal.prototype.open = function(){
        mui.overlay('on', _options, this.element);
    }

    Modal.prototype.close = function(){
        mui.overlay('off');
    }

    return Modal;
}());

var Interface = (function(){

    function Interface(){

        this.elements = {

            // modal
            modal: new Modal(),

            // controls
            dropdownMenu: document.getElementById('dropdown-menu'),

            // menu options
            menuCardView: document.getElementById('menu-card-view'),
            menuEditView: document.getElementById('menu-edit-view'),
            menuLoginModal: document.getElementById('menu-login-modal'),

            // views
            cardView: document.getElementById('cardView'),
            editorView: document.getElementById('editorView'),

            // flashcards
            flashcardContainer: document.getElementById('flashcard-container'),
            flashcard: document.getElementById('flashcard'),
            front: document.getElementById('front'),
            back: document.getElementById('back'),
            frontText: front.getElementsByTagName('p')[0],
            backText: back.getElementsByTagName('p')[0],

            // progress bar
            progressBar: document.getElementById('progress-bar'),
            correctProgress: document.getElementById('correct-progress'),
            incorrectProgress: document.getElementById('incorrect-progress'),
            skippedProgress: document.getElementById('skipped-progress'),

            // dropdown to select decks
            deckSelect: document.getElementById('deck-select'),

            // buttons
            correctButton: document.getElementById('correct'),
            incorrectButton: document.getElementById('incorrect'),
            skipButton: document.getElementById('skip')
        };

        this.current = {
            username: '',
            userId: 0,
            decks: [],
            deck: {},
            cards: [],
            card: {},
            totalCards: 0,
            correct: 0,
            incorrect: 0,
            skipped: 0
        };

    }

    Interface.prototype.setupEventListeners = function(){
    }

    Interface.prototype.userLogin = function(user){

        // user details
        this.current.username = user.username;
        this.current.userId = user.id;

        // deck details
        this.current.decks = user.decks;

        this.setupDeckSelection();
    }

    Interface.prototype.addOptions = function(options){
    // options = [{name: '', decks: [{id: 0, title: ''}]}]

        // remove existing dropdown elements
        this.elements.deckSelect.innerHTML = '';

        for(var i = 0; i < options.length; i++){

            // add option group for deck groups
            var optionGroup = document.createElement('optgroup');
            optionGroup.label = options[i].name;

            for(var j = 0; j < options[i].decks.length; j++){

                // add option for each deck
                var option = document.createElement('option');
                option.setAttribute('value', options[i].decks[j].id);
                option.text = options[i].decks[j].title;

                // append it to the select dropdown
                optionGroup.appendChild(option);
            }

            // append it to the select dropdown
            this.elements.deckSelect.appendChild(optionGroup);
        }
    }

    Interface.prototype.setupDeckSelection = function(){

        var decks = this.current.decks;
        var stackNames = [];
        var options = [];

        // iterate through each deck
        for(var i = 0; i < decks.length; i++){

            // add the group to the list if it's not there already
            if(stackNames.indexOf(decks[i].stack) === -1){
                stackNames.push(decks[i].stack);
            }
        }

        // iterate through each group on the group list
        for(var i = 0; i < stackNames.length; i++){

            var stacks = [];

            // and each deck
            for(var j = 0; j < decks.length; j++){

                var deck = {
                    id: 0,
                    title: ''
                };

                if(stackNames[i] === decks[j].stack){
                    deck.id = decks[j].id;
                    deck.title = decks[j].title;

                    stacks.push(deck);
                }
            }

            // add the name and titles to the options list
            options.push({
                name: stackNames[i],
                decks: stacks
            });
        }

        this.addOptions(options);

        // create an onchange event to switch selected deck
        this.elements.deckSelect.addEventListener('change', function(data){
            console.log('deck select data', data);
            console.log('deck select this', this);
        }.bind(this));
    }

    return Interface;
}());

// TEST
var api = new Api(devApi);
var interface = new Interface();<commit_msg>Started deck and card selection<commit_after>// 3rd party dependencies: jQuery v3.2.1, mui-0.9.22
// local dependencies: functions.js

const prodApi = 'https://alchemist.digital/flashcards/api/'; // PROD API
const devApi = '../test-api/'; // TEST API

var Api = (function(){

    function Api(url){
        this.url = url || devApi;
        this.user = this.url + 'users/';
        this.decks = this.url + 'decks/userid/';
        this.cards = this.url + 'cards/deckid/';
    }

    Api.prototype.getData = function(self, type, value, success, failure){

        var url;

        switch(type){
            case 'user':
                url = this.user + value;
                break;
            case 'decks':
                url = this.decks + value;
                break;
            case 'cards':
                url = this.cards + value;
            default:
                throw Error('[ERROR] value must be "user", "decks", or "cards"');
        }

        $.getJSON(url)
        .done(function(data){
            console.log('this: ', this);
            console.log('[DEBUG] getJSON success - data found: ', data);
            if(success){
                success(data);
            }
            return data;
        }.bind(self))
        .fail(function() {
            console.log('[DEBUG] getJSON failed');
            if(failure){
                failure();
            }
            throw Error('[ERROR] getData failed');
        });
    }

    return Api;
}());

var User = (function(){

    function User(username){
        this.username = username;
        this.id = 0;
        this.decks = [];

        this.getUserId(this.username);
    }

    User.prototype.getUserId = function(username){
        $.getJSON(api.user + username)
        .done(function(data){
            this.id = data[0].id;
            this.getDecks(this.id);
        }.bind(this))
        .fail(function() {
            throw Error('[ERROR] getJSON failed');
        });
    }

    User.prototype.getDecks = function(userId){
        $.getJSON(api.decks + userId)
        .done(function(data){
            for(var i = 0; i < data.length; i++){
                this.decks.push(new Deck(data[i]));
            }
            console.log('this test:', this);
            interface.userLogin(this);
        }.bind(this))
        .fail(function() {
            throw Error('[ERROR] getJSON failed');
        });
    }

    return User;
}());

var Deck = (function(){

    function Deck(obj){
        this.title = obj.title;
        this.id = obj.id || null;
        this.stack = obj.stack;
        this.cards = [];

        this.getCards(this.id);
    }

    Deck.prototype.getCards = function(deckId){
        $.getJSON(api.cards + deckId)
        .done(function(data){
            for(var i = 0; i < data.length; i++){
                this.cards.push(new Card(data[i]));
            }
        }.bind(this))
        .fail(function() {
            throw Error('[ERROR] getJSON failed');
        });
    }

    return Deck;
}());

var Card = (function(){

    function Card(obj){
        this.front = obj.front;
        this.back = obj.back;
        this.id = obj.id || null;
    }

    return Card;
}());

var Modal = (function(){

    var _options = {
        'keyboard': true,
        'static': false,
        'onclose': function() {
                console.log('modal closed');
            }
        };

    function Modal(){
        this.element = document.getElementById('loginModal');
        this.overlay = {};
    }

    Modal.prototype.open = function(){
        mui.overlay('on', _options, this.element);
    }

    Modal.prototype.close = function(){
        mui.overlay('off');
    }

    return Modal;
}());

var Interface = (function(){

    function Interface(){

        this.elements = {

            // modal
            modal: new Modal(),

            // controls
            dropdownMenu: document.getElementById('dropdown-menu'),

            // menu options
            menuCardView: document.getElementById('menu-card-view'),
            menuEditView: document.getElementById('menu-edit-view'),
            menuLoginModal: document.getElementById('menu-login-modal'),

            // views
            cardView: document.getElementById('cardView'),
            editorView: document.getElementById('editorView'),

            // flashcards
            flashcardContainer: document.getElementById('flashcard-container'),
            flashcard: document.getElementById('flashcard'),
            front: document.getElementById('front'),
            back: document.getElementById('back'),
            frontText: front.getElementsByTagName('p')[0],
            backText: back.getElementsByTagName('p')[0],

            // progress bar
            progressBar: document.getElementById('progress-bar'),
            correctProgress: document.getElementById('correct-progress'),
            incorrectProgress: document.getElementById('incorrect-progress'),
            skippedProgress: document.getElementById('skipped-progress'),

            // dropdown to select decks
            deckSelect: document.getElementById('deck-select'),

            // buttons
            correctButton: document.getElementById('correct'),
            incorrectButton: document.getElementById('incorrect'),
            skipButton: document.getElementById('skip')
        };

        this.current = {
            username: '',
            userId: 0,
            decks: [],
            deck: {},
            cards: [],
            card: {},
            totalCards: 0,
            correct: 0,
            incorrect: 0,
            skipped: 0
        };

    }

    Interface.prototype.setupEventListeners = function(){
    }

    Interface.prototype.userLogin = function(user){

        // user details
        this.current.username = user.username;
        this.current.userId = user.id;

        // deck details
        this.current.decks = user.decks;

        this.setupDeckSelection();
    }

    Interface.prototype.addOptions = function(options){
    // options = [{name: '', decks: [{id: 0, title: ''}]}]

        // remove existing dropdown elements
        this.elements.deckSelect.innerHTML = '';

        for(var i = 0; i < options.length; i++){

            // add option group for deck groups
            var optionGroup = document.createElement('optgroup');
            optionGroup.label = options[i].name;

            for(var j = 0; j < options[i].decks.length; j++){

                // add option for each deck
                var option = document.createElement('option');
                option.setAttribute('value', options[i].decks[j].id);
                option.text = options[i].decks[j].title;

                // append it to the select dropdown
                optionGroup.appendChild(option);
            }

            // append it to the select dropdown
            this.elements.deckSelect.appendChild(optionGroup);
        }
    }

    Interface.prototype.setupDeckSelection = function(){

        var decks = this.current.decks;
        var stackNames = [];
        var options = [];

        // iterate through each deck
        for(var i = 0; i < decks.length; i++){

            // add the group to the list if it's not there already
            if(stackNames.indexOf(decks[i].stack) === -1){
                stackNames.push(decks[i].stack);
            }
        }

        // iterate through each group on the group list
        for(var i = 0; i < stackNames.length; i++){

            var stacks = [];

            // and each deck
            for(var j = 0; j < decks.length; j++){

                var deck = {
                    id: 0,
                    title: ''
                };

                if(stackNames[i] === decks[j].stack){
                    deck.id = decks[j].id;
                    deck.title = decks[j].title;

                    stacks.push(deck);
                }
            }

            // add the name and titles to the options list
            options.push({
                name: stackNames[i],
                decks: stacks
            });
        }

        this.addOptions(options);

        // create an onchange event to switch selected deck
        this.elements.deckSelect.addEventListener('change', function(){

            var deckId = Number(interface.elements.deckSelect.value);
            this.selectDeck(deckId);

        }.bind(this));
    }

    Interface.prototype.selectDeck = function(deckId){

        // iterate through all current decks
        for(var i = 0; i < this.current.decks.length; i++){

            // if the selected deck matches
            if(this.current.decks[i].id === deckId){
                this.current.deck = this.current.decks[i];
                this.current.cards = this.current.deck.cards;
                this.current.card = this.current.cards[0];
                this.current.totalCards = this.current.cards.length;

                this.selectCard()
            }
        }
    }

    Interface.prototype.selectCard = function(){

        // pop a card off of the deck
        this.current.card = this.current.cards.pop();
        this.elements.frontText.innerText = this.current.card.front;
        this.elements.backText.innerText = this.current.card.back;
    }

    return Interface;
}());

// TEST
var api = new Api(devApi);
var interface = new Interface();<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { withFirebase } from '../Firebase';
import { withRouter } from 'react-router';
import { compose } from 'recompose';

class Timer extends Component {

  constructor(props) {
    super(props);
    this.state = {

    }
  }

  async componentDidMount() {
    const { id } = this.props.match.params;
    const game = this.props.firebase.game(id);

    game.get()
    .then(docSnapshot => {
      if(docSnapshot.exists) {
        this.unsubscribe = game.onSnapshot((snapshot) => {
          if(snapshot.data().gameStartTime !== null && snapshot.data().currentPlayerIndex === 0) {
            this.setState({
              currentPlayerIndex: snapshot.data().currentPlayerIndex + 1,
              startTime: snapshot.data().gameStartTime.seconds,
              timePerTurnInSeconds: parseInt(snapshot.data().timeLimit, 10) * 60,
            })
            this.setState({
              timeTurnWillEnd: (this.state.timePerTurnInSeconds + this.state.startTime),
            })
            this.setState({
              days: Math.floor((((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60)/ 24),
              hours: Math.floor(((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60) % 24,
              minutes: Math.floor((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) % 60,
              seconds: (this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) % 60
            })
          } else if(snapshot.data().gameStartTime !== null) {
            this.setState({
              startTime: Math.floor(new Date().getTime() / 1000),
              timePerTurnInSeconds: parseInt(snapshot.data().timeLimit, 10) * 60,
            })
            this.setState({
              timeTurnWillEnd: (this.state.timePerTurnInSeconds + this.state.startTime),
            })
            this.setState({
              days: Math.floor((((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60)/ 24),
              hours: Math.floor(((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60) % 24,
              minutes: Math.floor((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) % 60,
              seconds: (this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) % 60
            })
          }
        })
      }
    })

    this.myInterval = setInterval(async () => {
      const { days, hours, minutes, seconds } = this.state
      const gameRef = await this.props.firebase.game(id).get();

      if (seconds > 0) {
        this.setState({
          seconds: (this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) % 60
        })
      }
      if (seconds === 0) {
        if (minutes === 0 && hours === 0 && days === 0) {
          game.set({
            currentPlayerIndex: gameRef.data().currentPlayerIndex + 1,
          }, { merge: true })
          clearInterval(this.myInterval)
        } else {
          this.setState({
            days: Math.floor((((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60)/ 24),
            hours: Math.floor(((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60) % 24,
            minutes: Math.floor((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) % 60,
            seconds: (this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) % 60
          })
        }
      }
    }, 1000)
  }

  componentWillUnmount() {
    this.unsubscribe && this.unsubscribe()
  }

  render() {
    const { days, hours, minutes, seconds } = this.state;

    return(

          {
            (() => {
              if(minutes || seconds) {
                return (
                   (days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0)
                  ?
Times up!

                  :
Time Remaining: { days > 0 && `${ days }:`}
                  { hours > 0 && `${ hours }:`}
                  { minutes }:{ seconds < 10 ? `0${ seconds }` : seconds }

                )
              }
            })()
          }

    )
  }
}

export default compose(
  withFirebase,
  withRouter
)(Timer);
<commit_msg>added helper method for repetitive code<commit_after>import React, { Component } from 'react';
import { withFirebase } from '../Firebase';
import { withRouter } from 'react-router';
import { compose } from 'recompose';

class Timer extends Component {

  constructor(props) {
    super(props);
    this.state = {

    }
  }

  async componentDidMount() {
    const { id } = this.props.match.params;
    const game = this.props.firebase.game(id);

    game.get()
    .then(docSnapshot => {
      if(docSnapshot.exists) {
        this.unsubscribe = game.onSnapshot((snapshot) => {
          if(snapshot.data().gameStartTime !== null && snapshot.data().currentPlayerIndex === 0) {
            this.setState({
              currentPlayerIndex: snapshot.data().currentPlayerIndex + 1,
              startTime: snapshot.data().gameStartTime.seconds,
              timePerTurnInSeconds: parseInt(snapshot.data().timeLimit, 10) * 60,
            })
            this.setState({
              timeTurnWillEnd: (this.state.timePerTurnInSeconds + this.state.startTime),
            })
            this.setState({
              days: this.calculateTime('days'),
              hours: this.calculateTime('hours'),
              minutes: this.calculateTime('minutes'),
              seconds: this.calculateTime('seconds')
            })
          } else if(snapshot.data().gameStartTime !== null) {
            this.setState({
              startTime: Math.floor(new Date().getTime() / 1000),
              timePerTurnInSeconds: parseInt(snapshot.data().timeLimit, 10) * 60,
            })
            this.setState({
              timeTurnWillEnd: (this.state.timePerTurnInSeconds + this.state.startTime),
            })
            this.setState({
              days: this.calculateTime('days'),
              hours: this.calculateTime('hours'),
              minutes: this.calculateTime('minutes'),
              seconds: this.calculateTime('seconds')
            })
          }
        })
      }
    })

    this.myInterval = setInterval(async () => {
      const { days, hours, minutes, seconds } = this.state
      const gameRef = await this.props.firebase.game(id).get();

      if (seconds > 0) {
        this.setState({
          seconds: this.calculateTime('seconds')
        })
      }
      if (seconds === 0) {
        if (minutes === 0 && hours === 0 && days === 0) {
          game.set({
            currentPlayerIndex: gameRef.data().currentPlayerIndex + 1,
          }, { merge: true })
          clearInterval(this.myInterval)
        } else {
          this.setState({
            days: this.calculateTime('days'),
            hours: this.calculateTime('hours'),
            minutes: this.calculateTime('minutes'),
            seconds: this.calculateTime('seconds')
          })
        }
      }
    }, 1000)
  }

  calculateTime(unitOfTime) {
    switch(unitOfTime) {
      case 'days':
        return Math.floor((((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60)/ 24);
      case 'hours':
        return Math.floor(((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) / 60) % 24;
      case 'minutes':
        return Math.floor((this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) / 60) % 60;
      case 'seconds':
        return (this.state.timeTurnWillEnd - Math.floor(new Date().getTime() / 1000)) % 60;
      default:
        throw new Error('invalid case')
    }
  }

  componentWillUnmount() {
    this.unsubscribe && this.unsubscribe()
  }

  render() {
    const { days, hours, minutes, seconds } = this.state;

    return (

          {
            (() => {
              if(minutes || seconds) {
                return (
                   (days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0)
                  ?
Times up!

                  :
Time Remaining: { days > 0 && `${ days }:`}
                  { hours > 0 && `${ hours }:`}
                  { minutes }:{ seconds < 10 ? `0${ seconds }` : seconds }

                )
              }
            })()
          }

    )
  }
}

export default compose(
  withFirebase,
  withRouter
)(Timer);
<|endoftext|>


<commit_before>var GridFader = function(canvasId) {
	var canvas;
	var brush;

	var boxSize;

	var gridSize;
	var gridColor;

	var palette = new Array();

	var clock = 0;
	var clockCycle = 0;
	var clockSpeed = 500;

	this.Init = function() {
		boxSize = 50;

		gridSize = 5;
		gridColor = new ColorManagement.Color({ r: 255, g: 255, b: 255, a: .1 });

		palette.push(new ColorManagement.Color({ r: 228, g: 77, b: 38 }));	// HTML5 Orange
		palette.push(new ColorManagement.Color({ r: 2, g: 112, b: 187 }));	// CSS3 Blue
		palette.push(new ColorManagement.Color({ r: 214, g: 186, b: 51 }));	// JavaScript Yellow

		window.onload = Events.Init;
		window.onresize = Events.Resize;
	};

	var ColorManagement = {
		Color: function(obj) {
			var self = this;

			this.r = 0;
			this.g = 0;
			this.b = 0;
			this.a = 1;

			if(typeof obj !== 'undefined')
			{
				this.r = obj.r;
				this.g = obj.g;
				this.b = obj.b;
				this.a = typeof obj.a === 'undefined' ? this.a : obj.a;
			}

			this.Darken = function(amount) {
				darkerColor = new ColorManagement.Color();

				darkerColor.r = Math.floor(self.r - amount >= 0 ? self.r - amount : 0);
				darkerColor.g = Math.floor(self.g - amount >= 0 ? self.g - amount : 0);
				darkerColor.b = Math.floor(self.b - amount >= 0 ? self.b - amount : 0);

				darkerColor.a = self.a;

				return darkerColor;
			};

			this.toString = function() {
				return 'rgba(' + self.r + ', ' + self.g + ', ' + self.b + ', ' + self.a + ')';
			};
		},

		GetRandomColor: function() {
			var index = Math.floor(Math.random() * (palette.length - 1 - 0 + 1)) + 0;
			var refColor = palette[index];

			var color = new ColorManagement.Color();
			color.r = refColor.r;
			color.g = refColor.g;
			color.b = refColor.b;
			color.a = refColor.a;

			return color;
		}
	};

	var Environment = {
		SetCanvasSize: function() {
			canvas.height = window.innerHeight;
			canvas.width = window.innerWidth;
		}
	};

	var Events = {
		Init: function() {
			canvas = document.getElementById(canvasId);
			brush = canvas.getContext('2d');

			Events.Resize();
		},

		Resize: function() {
			clearInterval(clock);

			Environment.SetCanvasSize();
			DrawGrid();
			SquareManagement.GetAllSquares();

			clock = setInterval(Events.Tick, clockSpeed);
		},

		Tick: function()  {
			if(clockCycle === 7) {
				var square = SquareManagement.GetRandomSquare();

				if(square.State === null) {
					square.FadeIn();
				}
				else if(square.State === square.States.Full) {
					square.FadeOut();
				}

				clockCycle = 0;
			}
			else
			{
				clockCycle++;
			}

			var i = 0;
			var squares = SquareManagement.Squares;

			while(i < squares.length) {
				var square = squares[i];

				if(square.State === square.States.FadingIn) {
					square.FadeIn();
					square.Draw();
				}
				else if(square.State === square.States.FadingOut) {
					square.FadeOut();
					if(square.State !== null) {
						square.Draw();
					}
				}

				i++;
			}
		}
	};

	var DrawGrid = function() {
		var i = 0;
		var startingPoint = 0;

		brush.beginPath();

		brush.strokeStyle = gridColor.toString();
		brush.lineWidth = gridSize;

		while(startingPoint < canvas.height) {
			startingPoint = boxSize * i;

			brush.moveTo(0, startingPoint);

			brush.lineTo(canvas.width, startingPoint);

			i++;
		}

		i = 0;
		startingPoint = gridSize;

		while(startingPoint < canvas.width) {
			startingPoint = boxSize * i;

			brush.moveTo(startingPoint, 0);

			brush.lineTo(startingPoint, canvas.height);

			i++;
		}

		brush.stroke();

		brush.closePath();
	};

	var SquareManagement = {
		Square: function() {
			var self = this;

			this.Color = null;
			this.Length = 0;
			this.X = 0;
			this.Y = 0;

			this.State = null;

			this.Clear = function() {
				brush.clearRect(self.X, self.Y, self.Length, self.Length);
			};

			this.Destroy = function() {
				self.Clear();
				self.Color = null;
				self.State = null;
			};

			this.Draw = function() {
				var grd = brush.createRadialGradient(
	      			self.X + self.Length / 2, self.Y + self.Length / 2, 0,
	      			self.X + self.Length / 2, self.Y + self.Length / 2, boxSize);

				self.Clear();

				brush.beginPath();

				grd.addColorStop(0, self.Color);
      			grd.addColorStop(1, self.Color.Darken(64));

		    	brush.fillStyle = grd;
		    	brush.fillRect(self.X, self.Y, self.Length, self.Length);

				brush.stroke();

				brush.closePath();
				brush.fillStyle = null;
			}

			this.FadeIn = function() {
				self.State = self.States.FadingIn;

				if(self.Color === null) {
					self.Color = ColorManagement.GetRandomColor();
					self.Color.a = 0.0;
				}
				else if(self.Color.a >= 0.5) {
					self.State = self.States.Full;
				}
				else {
					self.Color.a += .01;
				}
			};

			this.FadeOut = function() {
				if(self.Color.a >= .01)
				{
					self.State = self.States.FadingOut;
					self.Color.a -= .01;
				}
				else
				{
					self.Destroy();
				}
			};

			this.States = {
				FadingIn: 'FadingIn',
				FadingOut: 'FadingOut',
				Full: 'Full'
			};
		},

		Squares: new Array(),

		GetAllSquares: function() {
			var xSquares = Math.ceil(window.innerWidth / boxSize);
			var ySquares = Math.ceil(window.innerHeight / boxSize);

			ix = 0;
			iy = 0;

			while(iy < ySquares)
			{
				while(ix < xSquares)
				{
					box = new SquareManagement.Square();
					box.X = ix * boxSize + gridSize - 2;		// Subtract 2 since the border center overlaps on the middle pixel.
					box.Y = iy * boxSize + gridSize - 2;		// Subtract 2 since the border center overlaps on the middle pixel.
					box.Length = boxSize - gridSize * 2 + 4;	// Add 4 to compensate for 2 pixels on each side being lost to border overlap.

					SquareManagement.Squares.push(box);

					ix++;
				}

				iy++;
				ix = 0;
			}
		},

		GetRandomSquare: function() {
			var index = Math.floor(Math.random() * (SquareManagement.Squares.length - 1 - 0 + 1)) + 0;
			var randomSquare = SquareManagement.Squares[index];

			return randomSquare;
		}
	}
};<commit_msg>Changed the scope of all of the GridFader properties so that they can be accessible publicly.<commit_after>'use strict';

var GridFader = function(canvasId) {
	this.palette = new Array();
	this.gridColor = null;
	this.canvas;
	this.brush;
	this.boxSize;
	this.gridSize;

	var self = this;

	var clock = 0;
	var clockCycle = 0;
	var clockSpeed = 500;

	this.BindEvents = function() {
		window.onload = Events.Init;
		window.onresize = Events.Resize;
	};

	this.ColorManagement = {
		Color: function(obj) {
			this.r = 0;
			this.g = 0;
			this.b = 0;
			this.a = 1;

			if(typeof obj !== 'undefined')
			{
				this.r = obj.r;
				this.g = obj.g;
				this.b = obj.b;
				this.a = typeof obj.a === 'undefined' ? this.a : obj.a;
			}

			this.Darken = function(amount) {
				var darkerColor = new self.ColorManagement.Color();

				darkerColor.r = Math.floor(this.r - amount >= 0 ? this.r - amount : 0);
				darkerColor.g = Math.floor(this.g - amount >= 0 ? this.g - amount : 0);
				darkerColor.b = Math.floor(this.b - amount >= 0 ? this.b - amount : 0);

				darkerColor.a = this.a;

				return darkerColor;
			};

			this.toString = function() {
				return 'rgba(' + Math.floor(this.r) + ', ' + Math.floor(this.g) + ', ' + Math.floor(this.b) + ', ' + this.a + ')';
			};
		},

		GetRandomColor: function() {
			var palette = self.palette;

			var index = Math.floor(Math.random() * (palette.length - 1 - 0 + 1)) + 0;
			var refColor = palette[index];

			var color = new self.ColorManagement.Color();
			color.r = refColor.r;
			color.g = refColor.g;
			color.b = refColor.b;
			color.a = refColor.a;

			return color;
		}
	};

	var Environment = {
		SetCanvasSize: function() {
			self.canvas.height = window.innerHeight;
			self.canvas.width = window.innerWidth;
		}
	};

	var Events = {
		Init: function() {
			self.canvas = document.getElementById(canvasId);
			self.brush = self.canvas.getContext('2d');

			Events.Resize();
		},

		Resize: function() {
			clearInterval(clock);

			Environment.SetCanvasSize();
			self.DrawGrid();
			self.SquareManagement.GetAllSquares();

			clock = setInterval(Events.Tick, clockSpeed);
		},

		Tick: function()  {
			if(clockCycle === 7) {
				var square = self.SquareManagement.GetRandomSquare();

				if(square.State === null) {
					square.FadeIn();
				}
				else if(square.State === square.States.Full) {
					square.FadeOut();
				}

				clockCycle = 0;
			}
			else
			{
				clockCycle++;
			}

			var i = 0;
			var squares = self.SquareManagement.Squares;

			while(i < squares.length) {
				var square = squares[i];

				if(square.State === square.States.FadingIn) {
					square.FadeIn();
					square.Draw();
				}
				else if(square.State === square.States.FadingOut) {
					square.FadeOut();
					if(square.State !== null) {
						square.Draw();
					}
				}

				i++;
			}
		}
	};

	this.DrawGrid = function() {
		var brush = self.brush;
		var canvas = self.canvas;
		var gridColor = self.gridColor;
		var gridSize = self.gridSize;
		var boxSize = self.boxSize;

		var i = 0;
		var startingPoint = 0;

		brush.beginPath();

		brush.strokeStyle = gridColor.toString();
		brush.lineWidth = gridSize;

		while(startingPoint < canvas.height) {
			startingPoint = boxSize * i;

			brush.moveTo(0, startingPoint);

			brush.lineTo(canvas.width, startingPoint);

			i++;
		}

		i = 0;
		startingPoint = gridSize;

		while(startingPoint < canvas.width) {
			startingPoint = boxSize * i;

			brush.moveTo(startingPoint, 0);

			brush.lineTo(startingPoint, canvas.height);

			i++;
		}

		brush.stroke();

		brush.closePath();
	};

	this.SquareManagement = {
		Square: function() {
			this.Color = null;
			this.Length = 0;
			this.X = 0;
			this.Y = 0;

			this.State = null;

			this.Clear = function() {
				self.brush.clearRect(this.X, this.Y, this.Length, this.Length);
			};

			this.Destroy = function() {
				this.Clear();
				this.Color = null;
				this.State = null;
			};

			this.Draw = function() {
				var brush = self.brush;
				var boxSize = self.boxSize;

				var grd = brush.createRadialGradient(
	      			this.X + this.Length / 2, this.Y + this.Length / 2, 0,
	      			this.X + this.Length / 2, this.Y + this.Length / 2, boxSize);

				this.Clear();

				brush.beginPath();

				grd.addColorStop(0, this.Color);
      			grd.addColorStop(1, this.Color.Darken(64));

		    	brush.fillStyle = grd;
		    	brush.fillRect(this.X, this.Y, this.Length, this.Length);

				brush.stroke();

				brush.closePath();
				brush.fillStyle = null;
			}

			this.FadeIn = function() {
				this.State = this.States.FadingIn;

				if(this.Color === null) {
					this.Color = self.ColorManagement.GetRandomColor();
					this.Color.a = 0.0;
				}
				else if(this.Color.a >= 0.5) {
					this.State = this.States.Full;
				}
				else {
					this.Color.a += .01;
				}
			};

			this.FadeOut = function() {
				if(this.Color.a >= .01)
				{
					this.State = this.States.FadingOut;
					this.Color.a -= .01;
				}
				else
				{
					this.Destroy();
				}
			};

			this.States = {
				FadingIn: 'FadingIn',
				FadingOut: 'FadingOut',
				Full: 'Full'
			};
		},

		Squares: new Array(),

		GetAllSquares: function() {
			var boxSize = self.boxSize;
			var gridSize = self.gridSize;

			var xSquares = Math.ceil(window.innerWidth / boxSize);
			var ySquares = Math.ceil(window.innerHeight / boxSize);

			var ix = 0;
			var iy = 0;

			while(iy < ySquares)
			{
				while(ix < xSquares)
				{
					var box = new self.SquareManagement.Square();
					box.X = ix * boxSize + gridSize - 2;		// Subtract 2 since the border center overlaps on the middle pixel.
					box.Y = iy * boxSize + gridSize - 2;		// Subtract 2 since the border center overlaps on the middle pixel.
					box.Length = boxSize - gridSize * 2 + 4;	// Add 4 to compensate for 2 pixels on each side being lost to border overlap.

					self.SquareManagement.Squares.push(box);

					ix++;
				}

				iy++;
				ix = 0;
			}
		},

		GetRandomSquare: function() {
			var index = Math.floor(Math.random() * (self.SquareManagement.Squares.length - 1 - 0 + 1)) + 0;
			var randomSquare = self.SquareManagement.Squares[index];

			return randomSquare;
		}
	}
};<|endoftext|>


<commit_before>ig.module( 'game.levels.test2' )
.requires( 'impact.image','game.entities.player','game.entities.levelTimer','game.entities.healthMeter','game.entities.bodyMeter','game.entities.soldier','game.entities.enemySpawner' )
.defines(function(){
LevelTest2=/*JSON[*/{
	"entities": [
		{
			"type": "EntityPlayer",
			"x": 108,
			"y": 572
		},
		{
			"type": "EntityLevelTimer",
			"x": 76,
			"y": 68,
			"settings": {
				"limit": 60
			}
		},
		{
			"type": "EntityHealthMeter",
			"x": 76,
			"y": 112
		},
		{
			"type": "EntityBodyMeter",
			"x": 76,
			"y": 160
		},
		{
			"type": "EntitySoldier",
			"x": 988,
			"y": 628
		},
		{
			"type": "EntityEnemySpawner",
			"x": 1040,
			"y": 40
		}
	],
	"layer": [
		{
			"name": "skyline",
			"width": 1,
			"height": 1,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "media/bg_sky.jpg",
			"repeat": false,
			"preRender": false,
			"distance": "9",
			"tilesize": 1024,
			"foreground": false,
			"data": [
				[1]
			]
		},
		{
			"name": "building",
			"width": 20,
			"height": 12,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "media/buildings.png",
			"repeat": false,
			"preRender": false,
			"distance": " 1",
			"tilesize": 64,
			"foreground": false,
			"data": [
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,14,14,7,7,7,5,0,5,5,5,5,0,0,0,0,0,0,0],
				[0,0,0,0,1,1,1,1,0,4,4,4,9,14,14,6,5,13,0,0],
				[0,0,0,0,5,9,1,1,0,13,5,1,1,14,14,1,1,1,0,0],
				[0,0,0,0,4,4,4,4,15,1,1,1,4,14,1,1,1,1,1,0],
				[0,0,0,0,1,1,7,8,15,7,8,1,1,14,1,9,1,1,1,0],
				[0,0,0,0,1,1,1,1,14,1,1,1,1,0,1,1,1,1,13,0],
				[0,0,0,0,6,6,1,7,0,8,8,7,8,0,7,7,1,1,1,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
			]
		},
		{
			"name": "street_tile",
			"width": 20,
			"height": 12,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "media/streetTile.png",
			"repeat": false,
			"preRender": false,
			"distance": "1",
			"tilesize": 64,
			"foreground": false,
			"data": [
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0]
			]
		},
		{
			"name": "collision",
			"width": 20,
			"height": 12,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "",
			"repeat": false,
			"preRender": false,
			"distance": 1,
			"tilesize": 64,
			"foreground": false,
			"data": [
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,12,12,12,12,0,12,12,12,12,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,12,12,0,0,0,0,12,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,12,12,0,12,12,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,12,12,0,12,0,12,12,12,12,0,0,0,0,0,0,0],
				[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
			]
		}
	]
}/*]JSON*/;
LevelTest2Resources=[new ig.Image('media/bg_sky.jpg'), new ig.Image('media/buildings.png'), new ig.Image('media/streetTile.png')];
});<commit_msg>longer street<commit_after>ig.module( 'game.levels.test2' )
.requires( 'impact.image','game.entities.player','game.entities.levelTimer','game.entities.healthMeter','game.entities.bodyMeter','game.entities.soldier','game.entities.enemySpawner' )
.defines(function(){
LevelTest2=/*JSON[*/{
	"entities": [
		{
			"type": "EntityPlayer",
			"x": 108,
			"y": 572
		},
		{
			"type": "EntityLevelTimer",
			"x": 76,
			"y": 68,
			"settings": {
				"limit": 60
			}
		},
		{
			"type": "EntityHealthMeter",
			"x": 76,
			"y": 112
		},
		{
			"type": "EntityBodyMeter",
			"x": 76,
			"y": 160
		},
		{
			"type": "EntitySoldier",
			"x": 988,
			"y": 628
		},
		{
			"type": "EntityEnemySpawner",
			"x": 1040,
			"y": 40
		}
	],
	"layer": [
		{
			"name": "skyline",
			"width": 1,
			"height": 1,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "media/bg_sky.jpg",
			"repeat": false,
			"preRender": false,
			"distance": "9",
			"tilesize": 1024,
			"foreground": false,
			"data": [
				[1]
			]
		},
		{
			"name": "building",
			"width": 20,
			"height": 12,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "media/buildings.png",
			"repeat": false,
			"preRender": false,
			"distance": " 1",
			"tilesize": 64,
			"foreground": false,
			"data": [
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,14,14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,14,14,7,7,7,5,0,5,5,5,5,0,0,0,0,0,0,0],
				[0,0,0,0,1,1,1,1,0,4,4,4,9,14,14,6,5,13,0,0],
				[0,0,0,0,5,9,1,1,0,13,5,1,1,14,14,1,1,1,0,0],
				[0,0,0,0,4,4,4,4,15,1,1,1,4,14,1,1,1,1,1,0],
				[0,0,0,0,1,1,7,8,15,7,8,1,1,14,1,9,1,1,1,0],
				[0,0,0,0,1,1,1,1,14,1,1,1,1,0,1,1,1,1,13,0],
				[0,0,0,0,6,6,1,7,0,8,8,7,8,0,7,7,1,1,1,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
			]
		},
		{
			"name": "street_tile",
			"width": 20,
			"height": 12,
			"linkWithCollision": false,
			"visible": 1,
			"tilesetName": "media/streetTile.png",
			"repeat": false,
			"preRender": false,
			"distance": "1",
			"tilesize": 64,
			"foreground": false,
			"data": [
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
			]
		},
		{
			"name": "collision",
			"width": 20,
			"height": 12,
			"linkWithCollision": false,
			"visible": 0,
			"tilesetName": "",
			"repeat": false,
			"preRender": false,
			"distance": 1,
			"tilesize": 64,
			"foreground": false,
			"data": [
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
				[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,12,12,12,12,0,12,12,12,12,0,0,0,0,0,0,1],
				[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,12,12,0,0,0,0,12,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,0,0,12,12,0,12,12,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
				[1,0,0,0,12,12,0,12,0,12,12,12,12,0,0,0,0,0,0,1],
				[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
			]
		}
	]
}/*]JSON*/;
LevelTest2Resources=[new ig.Image('media/bg_sky.jpg'), new ig.Image('media/buildings.png'), new ig.Image('media/streetTile.png')];
});<|endoftext|>


<commit_before>'use strict';

const util = require('util');
const assert = require('assert');
const wrapEmitter = require('emitter-listener');
const asyncHook = require('async-hook');

const CONTEXTS_SYMBOL = 'cls@contexts';
const ERROR_SYMBOL = 'error@context';

//const trace = [];

const invertedProviders = [];
for (let key in asyncHook.providers) {
  invertedProviders[asyncHook.providers[key]] = key;
}

const DEBUG_CLS_HOOKED = process.env.DEBUG_CLS_HOOKED;

let currentUid = -1;

module.exports = {
  getNamespace: getNamespace,
  createNamespace: createNamespace,
  destroyNamespace: destroyNamespace,
  reset: reset,
  //trace: trace,
  ERROR_SYMBOL: ERROR_SYMBOL
};

function Namespace(name) {
  this.name = name;
  // changed in 2.7: no default context
  this.active = null;
  this._set = [];
  this.id = null;
  this._contexts = new Map();
}

Namespace.prototype.set = function set(key, value) {
  if (!this.active) {
    throw new Error('No context available. ns.run() or ns.bind() must be called first.');
  }

  if (DEBUG_CLS_HOOKED) {
    debug2('    SETTING KEY:' + key + '=' + value + ' in ns:' + this.name + ' uid:' + currentUid + ' active:' +
      util.inspect(this.active, true));
  }
  this.active[key] = value;
  return value;
};

Namespace.prototype.get = function get(key) {
  if (!this.active) {
    if (DEBUG_CLS_HOOKED) {
      debug2('    GETTING KEY:' + key + '=undefined' + ' ' + this.name + ' uid:' + currentUid + ' active:' +
        util.inspect(this.active, true));
    }
    return undefined;
  }
  if (DEBUG_CLS_HOOKED) {
    debug2('    GETTING KEY:' + key + '=' + this.active[key] + ' ' + this.name + ' uid:' + currentUid + ' active:' +
      util.inspect(this.active, true));
  }
  return this.active[key];
};

Namespace.prototype.createContext = function createContext() {
  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATING Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' active:' +
      util.inspect(this.active, true, 2, true));
  }

  let context = Object.create(this.active ? this.active : Object.prototype);
  context._ns_name = this.name;
  context.id = currentUid;

  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATED Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' context:' +
      util.inspect(context, true, 2, true));
  }

  return context;
};

Namespace.prototype.run = function run(fn) {
  let context = this.createContext();
  this.enter(context);
  try {
    if (DEBUG_CLS_HOOKED) {
      debug2(' BEFORE RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
        util.inspect(context));
    }
    fn(context);
    return context;
  }
  catch (exception) {
    if (exception) {
      exception[ERROR_SYMBOL] = context;
    }
    throw exception;
  }
  finally {
    if (DEBUG_CLS_HOOKED) {
      debug2(' AFTER RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
        util.inspect(context));
    }
    this.exit(context);
  }
};

Namespace.prototype.runAndReturn = function runAndReturn(fn) {
  var value;
  this.run(function (context) {
    value = fn(context);
  });
  return value;
};

/**
 * Uses global Promise and assumes Promise is cls friendly or wrapped already.
 * @param {function} fn
 * @returns {*}
 */
Namespace.prototype.runPromise = function runPromise(fn) {
  let context = this.createContext();
  this.enter(context);

  let promise = fn(context);
  if (!promise || !promise.then || !promise.catch) {
    throw new Error('fn must return a promise.');
  }

  if (DEBUG_CLS_HOOKED) {
    debug2(' BEFORE runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
      util.inspect(context));
  }

  return promise
    .then(result => {
      if (DEBUG_CLS_HOOKED) {
        debug2(' AFTER runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
          util.inspect(context));
      }
      this.exit(context);
      return result;
    })
    .catch(err => {
      exception[ERROR_SYMBOL] = context;
      if (DEBUG_CLS_HOOKED) {
        debug2(' AFTER runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
          util.inspect(context));
      }
      this.exit(context);
      throw err;
    });
};

Namespace.prototype.bind = function bindFactory(fn, context) {
  if (!context) {
    if (!this.active) {
      context = this.createContext();
    }
    else {
      context = this.active;
    }
  }

  let self = this;
  return function clsBind() {
    self.enter(context);
    try {
      return fn.apply(this, arguments);
    }
    catch (exception) {
      if (exception) {
        exception[ERROR_SYMBOL] = context;
      }
      throw exception;
    }
    finally {
      self.exit(context);
    }
  };
};

Namespace.prototype.enter = function enter(context) {
  assert.ok(context, 'context must be provided for entering');
  if (DEBUG_CLS_HOOKED) {
    debug2('  ENTER ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' +
      util.inspect(context));
  }

  this._set.push(this.active);
  this.active = context;
};

Namespace.prototype.exit = function exit(context) {
  assert.ok(context, 'context must be provided for exiting');
  if (DEBUG_CLS_HOOKED) {
    debug2('  EXIT ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' +
      util.inspect(context));
  }

  // Fast path for most exits that are at the top of the stack
  if (this.active === context) {
    assert.ok(this._set.length, 'can\'t remove top context');
    this.active = this._set.pop();
    return;
  }

  // Fast search in the stack using lastIndexOf
  let index = this._set.lastIndexOf(context);

  if (index < 0) {
    if (DEBUG_CLS_HOOKED) {
      debug2('??ERROR?? context exiting but not entered - ignoring: ' + util.inspect(context));
    }
    assert.ok(index >= 0, 'context not currently entered; can\'t exit. \n' + util.inspect(this) + '\n' +
      util.inspect(context));
  } else {
    assert.ok(index, 'can\'t remove top context');
    this._set.splice(index, 1);
  }
};

Namespace.prototype.bindEmitter = function bindEmitter(emitter) {
  assert.ok(emitter.on && emitter.addListener && emitter.emit, 'can only bind real EEs');

  let namespace = this;
  let thisSymbol = 'context@' + this.name;

  // Capture the context active at the time the emitter is bound.
  function attach(listener) {
    if (!listener) {
      return;
    }
    if (!listener[CONTEXTS_SYMBOL]) {
      listener[CONTEXTS_SYMBOL] = Object.create(null);
    }

    listener[CONTEXTS_SYMBOL][thisSymbol] = {
      namespace: namespace,
      context: namespace.active
    };
  }

  // At emit time, bind the listener within the correct context.
  function bind(unwrapped) {
    if (!(unwrapped && unwrapped[CONTEXTS_SYMBOL])) {
      return unwrapped;
    }

    let wrapped = unwrapped;
    let unwrappedContexts = unwrapped[CONTEXTS_SYMBOL];
    Object.keys(unwrappedContexts).forEach(function (name) {
      let thunk = unwrappedContexts[name];
      wrapped = thunk.namespace.bind(wrapped, thunk.context);
    });
    return wrapped;
  }

  wrapEmitter(emitter, attach, bind);
};

/**
 * If an error comes out of a namespace, it will have a context attached to it.
 * This function knows how to find it.
 *
 * @param {Error} exception Possibly annotated error.
 */
Namespace.prototype.fromException = function fromException(exception) {
  return exception[ERROR_SYMBOL];
};

function getNamespace(name) {
  return process.namespaces[name];
}

function createNamespace(name) {
  assert.ok(name, 'namespace must be given a name.');

  if (DEBUG_CLS_HOOKED) {
    debug2('CREATING NAMESPACE ' + name);
  }
  let namespace = new Namespace(name);
  namespace.id = currentUid;

  asyncHook.addHooks({
    init(uid, handle, provider, parentUid, parentHandle) {
      //parentUid = parentUid || currentUid;  // Suggested usage but appears to work better for tracing modules.
      currentUid = uid;

      //CHAIN Parent's Context onto child if none exists. This is needed to pass net-events.spec
      if (parentUid) {
        namespace._contexts.set(uid, namespace._contexts.get(parentUid));
        if (DEBUG_CLS_HOOKED) {
          debug2('PARENTID: ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + provider);
        }
      } else {
        namespace._contexts.set(currentUid, namespace.active);
      }

      if (DEBUG_CLS_HOOKED) {
        debug2('INIT ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + invertedProviders[provider]
          + ' active:' + util.inspect(namespace.active, true));
      }

    },
    pre(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' +
            util.inspect(context));
        }

        namespace.enter(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    post(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' +
            util.inspect(context));
        }

        namespace.exit(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    destroy(uid) {
      currentUid = uid;

      if (DEBUG_CLS_HOOKED) {
        debug2('DESTROY ' + name + ' uid:' + uid + ' context:' + util.inspect(namespace._contexts.get(currentUid))
          + ' active:' + util.inspect(namespace.active, true));
      }

      namespace._contexts.delete(uid);
    }
  });

  process.namespaces[name] = namespace;
  return namespace;
}

function destroyNamespace(name) {
  let namespace = getNamespace(name);

  assert.ok(namespace, 'can\'t delete nonexistent namespace! "' + name + '"');
  assert.ok(namespace.id, 'don\'t assign to process.namespaces directly! ' + util.inspect(namespace));

  process.namespaces[name] = null;
}

function reset() {
  // must unregister async listeners
  if (process.namespaces) {
    Object.keys(process.namespaces).forEach(function (name) {
      destroyNamespace(name);
    });
  }
  process.namespaces = Object.create(null);
}

process.namespaces = {};

if (asyncHook._state && !asyncHook._state.enabled) {
  asyncHook.enable();
}

function debug2(msg) {
  if (process.env.DEBUG) {
    process._rawDebug(msg);
  }
}

/*function debug(from, ns) {
 process._rawDebug('DEBUG: ' + util.inspect({
 from: from,
 currentUid: currentUid,
 context: ns ? ns._contexts.get(currentUid) : 'no ns'
 }, true, 2, true));
 }*/

function getFunctionName(fn) {
  if (!fn) {
    return fn;
  }
  if (typeof fn === 'function') {
    if (fn.name) {
      return fn.name;
    }
    return (fn.toString().trim().match(/^function\s*([^\s(]+)/) || [])[1];
  } else if (fn.constructor && fn.constructor.name) {
    return fn.constructor.name;
  }
}

// Add back to callstack
if (DEBUG_CLS_HOOKED) {
  var stackChain = require('stack-chain');
  for (var modifier in stackChain.filter._modifiers) {
    stackChain.filter.deattach(modifier);
  }
}
<commit_msg>Use the correct variable name<commit_after>'use strict';

const util = require('util');
const assert = require('assert');
const wrapEmitter = require('emitter-listener');
const asyncHook = require('async-hook');

const CONTEXTS_SYMBOL = 'cls@contexts';
const ERROR_SYMBOL = 'error@context';

//const trace = [];

const invertedProviders = [];
for (let key in asyncHook.providers) {
  invertedProviders[asyncHook.providers[key]] = key;
}

const DEBUG_CLS_HOOKED = process.env.DEBUG_CLS_HOOKED;

let currentUid = -1;

module.exports = {
  getNamespace: getNamespace,
  createNamespace: createNamespace,
  destroyNamespace: destroyNamespace,
  reset: reset,
  //trace: trace,
  ERROR_SYMBOL: ERROR_SYMBOL
};

function Namespace(name) {
  this.name = name;
  // changed in 2.7: no default context
  this.active = null;
  this._set = [];
  this.id = null;
  this._contexts = new Map();
}

Namespace.prototype.set = function set(key, value) {
  if (!this.active) {
    throw new Error('No context available. ns.run() or ns.bind() must be called first.');
  }

  if (DEBUG_CLS_HOOKED) {
    debug2('    SETTING KEY:' + key + '=' + value + ' in ns:' + this.name + ' uid:' + currentUid + ' active:' +
      util.inspect(this.active, true));
  }
  this.active[key] = value;
  return value;
};

Namespace.prototype.get = function get(key) {
  if (!this.active) {
    if (DEBUG_CLS_HOOKED) {
      debug2('    GETTING KEY:' + key + '=undefined' + ' ' + this.name + ' uid:' + currentUid + ' active:' +
        util.inspect(this.active, true));
    }
    return undefined;
  }
  if (DEBUG_CLS_HOOKED) {
    debug2('    GETTING KEY:' + key + '=' + this.active[key] + ' ' + this.name + ' uid:' + currentUid + ' active:' +
      util.inspect(this.active, true));
  }
  return this.active[key];
};

Namespace.prototype.createContext = function createContext() {
  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATING Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' active:' +
      util.inspect(this.active, true, 2, true));
  }

  let context = Object.create(this.active ? this.active : Object.prototype);
  context._ns_name = this.name;
  context.id = currentUid;

  if (DEBUG_CLS_HOOKED) {
    debug2('   CREATED Context: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' + ' context:' +
      util.inspect(context, true, 2, true));
  }

  return context;
};

Namespace.prototype.run = function run(fn) {
  let context = this.createContext();
  this.enter(context);
  try {
    if (DEBUG_CLS_HOOKED) {
      debug2(' BEFORE RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
        util.inspect(context));
    }
    fn(context);
    return context;
  }
  catch (exception) {
    if (exception) {
      exception[ERROR_SYMBOL] = context;
    }
    throw exception;
  }
  finally {
    if (DEBUG_CLS_HOOKED) {
      debug2(' AFTER RUN: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
        util.inspect(context));
    }
    this.exit(context);
  }
};

Namespace.prototype.runAndReturn = function runAndReturn(fn) {
  var value;
  this.run(function (context) {
    value = fn(context);
  });
  return value;
};

/**
 * Uses global Promise and assumes Promise is cls friendly or wrapped already.
 * @param {function} fn
 * @returns {*}
 */
Namespace.prototype.runPromise = function runPromise(fn) {
  let context = this.createContext();
  this.enter(context);

  let promise = fn(context);
  if (!promise || !promise.then || !promise.catch) {
    throw new Error('fn must return a promise.');
  }

  if (DEBUG_CLS_HOOKED) {
    debug2(' BEFORE runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
      util.inspect(context));
  }

  return promise
    .then(result => {
      if (DEBUG_CLS_HOOKED) {
        debug2(' AFTER runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
          util.inspect(context));
      }
      this.exit(context);
      return result;
    })
    .catch(err => {
      err[ERROR_SYMBOL] = context;
      if (DEBUG_CLS_HOOKED) {
        debug2(' AFTER runPromise: ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' ' +
          util.inspect(context));
      }
      this.exit(context);
      throw err;
    });
};

Namespace.prototype.bind = function bindFactory(fn, context) {
  if (!context) {
    if (!this.active) {
      context = this.createContext();
    }
    else {
      context = this.active;
    }
  }

  let self = this;
  return function clsBind() {
    self.enter(context);
    try {
      return fn.apply(this, arguments);
    }
    catch (exception) {
      if (exception) {
        exception[ERROR_SYMBOL] = context;
      }
      throw exception;
    }
    finally {
      self.exit(context);
    }
  };
};

Namespace.prototype.enter = function enter(context) {
  assert.ok(context, 'context must be provided for entering');
  if (DEBUG_CLS_HOOKED) {
    debug2('  ENTER ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' +
      util.inspect(context));
  }

  this._set.push(this.active);
  this.active = context;
};

Namespace.prototype.exit = function exit(context) {
  assert.ok(context, 'context must be provided for exiting');
  if (DEBUG_CLS_HOOKED) {
    debug2('  EXIT ' + this.name + ' uid:' + currentUid + ' len:' + this._set.length + ' context: ' +
      util.inspect(context));
  }

  // Fast path for most exits that are at the top of the stack
  if (this.active === context) {
    assert.ok(this._set.length, 'can\'t remove top context');
    this.active = this._set.pop();
    return;
  }

  // Fast search in the stack using lastIndexOf
  let index = this._set.lastIndexOf(context);

  if (index < 0) {
    if (DEBUG_CLS_HOOKED) {
      debug2('??ERROR?? context exiting but not entered - ignoring: ' + util.inspect(context));
    }
    assert.ok(index >= 0, 'context not currently entered; can\'t exit. \n' + util.inspect(this) + '\n' +
      util.inspect(context));
  } else {
    assert.ok(index, 'can\'t remove top context');
    this._set.splice(index, 1);
  }
};

Namespace.prototype.bindEmitter = function bindEmitter(emitter) {
  assert.ok(emitter.on && emitter.addListener && emitter.emit, 'can only bind real EEs');

  let namespace = this;
  let thisSymbol = 'context@' + this.name;

  // Capture the context active at the time the emitter is bound.
  function attach(listener) {
    if (!listener) {
      return;
    }
    if (!listener[CONTEXTS_SYMBOL]) {
      listener[CONTEXTS_SYMBOL] = Object.create(null);
    }

    listener[CONTEXTS_SYMBOL][thisSymbol] = {
      namespace: namespace,
      context: namespace.active
    };
  }

  // At emit time, bind the listener within the correct context.
  function bind(unwrapped) {
    if (!(unwrapped && unwrapped[CONTEXTS_SYMBOL])) {
      return unwrapped;
    }

    let wrapped = unwrapped;
    let unwrappedContexts = unwrapped[CONTEXTS_SYMBOL];
    Object.keys(unwrappedContexts).forEach(function (name) {
      let thunk = unwrappedContexts[name];
      wrapped = thunk.namespace.bind(wrapped, thunk.context);
    });
    return wrapped;
  }

  wrapEmitter(emitter, attach, bind);
};

/**
 * If an error comes out of a namespace, it will have a context attached to it.
 * This function knows how to find it.
 *
 * @param {Error} exception Possibly annotated error.
 */
Namespace.prototype.fromException = function fromException(exception) {
  return exception[ERROR_SYMBOL];
};

function getNamespace(name) {
  return process.namespaces[name];
}

function createNamespace(name) {
  assert.ok(name, 'namespace must be given a name.');

  if (DEBUG_CLS_HOOKED) {
    debug2('CREATING NAMESPACE ' + name);
  }
  let namespace = new Namespace(name);
  namespace.id = currentUid;

  asyncHook.addHooks({
    init(uid, handle, provider, parentUid, parentHandle) {
      //parentUid = parentUid || currentUid;  // Suggested usage but appears to work better for tracing modules.
      currentUid = uid;

      //CHAIN Parent's Context onto child if none exists. This is needed to pass net-events.spec
      if (parentUid) {
        namespace._contexts.set(uid, namespace._contexts.get(parentUid));
        if (DEBUG_CLS_HOOKED) {
          debug2('PARENTID: ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + provider);
        }
      } else {
        namespace._contexts.set(currentUid, namespace.active);
      }

      if (DEBUG_CLS_HOOKED) {
        debug2('INIT ' + name + ' uid:' + uid + ' parent:' + parentUid + ' provider:' + invertedProviders[provider]
          + ' active:' + util.inspect(namespace.active, true));
      }

    },
    pre(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' +
            util.inspect(context));
        }

        namespace.enter(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' PRE MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    post(uid, handle) {
      currentUid = uid;
      let context = namespace._contexts.get(uid);
      if (context) {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle) + ' context:' +
            util.inspect(context));
        }

        namespace.exit(context);
      } else {
        if (DEBUG_CLS_HOOKED) {
          debug2(' POST MISSING CONTEXT ' + name + ' uid:' + uid + ' handle:' + getFunctionName(handle));
        }
      }
    },
    destroy(uid) {
      currentUid = uid;

      if (DEBUG_CLS_HOOKED) {
        debug2('DESTROY ' + name + ' uid:' + uid + ' context:' + util.inspect(namespace._contexts.get(currentUid))
          + ' active:' + util.inspect(namespace.active, true));
      }

      namespace._contexts.delete(uid);
    }
  });

  process.namespaces[name] = namespace;
  return namespace;
}

function destroyNamespace(name) {
  let namespace = getNamespace(name);

  assert.ok(namespace, 'can\'t delete nonexistent namespace! "' + name + '"');
  assert.ok(namespace.id, 'don\'t assign to process.namespaces directly! ' + util.inspect(namespace));

  process.namespaces[name] = null;
}

function reset() {
  // must unregister async listeners
  if (process.namespaces) {
    Object.keys(process.namespaces).forEach(function (name) {
      destroyNamespace(name);
    });
  }
  process.namespaces = Object.create(null);
}

process.namespaces = {};

if (asyncHook._state && !asyncHook._state.enabled) {
  asyncHook.enable();
}

function debug2(msg) {
  if (process.env.DEBUG) {
    process._rawDebug(msg);
  }
}

/*function debug(from, ns) {
 process._rawDebug('DEBUG: ' + util.inspect({
 from: from,
 currentUid: currentUid,
 context: ns ? ns._contexts.get(currentUid) : 'no ns'
 }, true, 2, true));
 }*/

function getFunctionName(fn) {
  if (!fn) {
    return fn;
  }
  if (typeof fn === 'function') {
    if (fn.name) {
      return fn.name;
    }
    return (fn.toString().trim().match(/^function\s*([^\s(]+)/) || [])[1];
  } else if (fn.constructor && fn.constructor.name) {
    return fn.constructor.name;
  }
}

// Add back to callstack
if (DEBUG_CLS_HOOKED) {
  var stackChain = require('stack-chain');
  for (var modifier in stackChain.filter._modifiers) {
    stackChain.filter.deattach(modifier);
  }
}
<|endoftext|>