<commit_before>'use strict';

angular.module('myApp.view1', ['ngMaterial', 'ngRoute', 'ngNotify'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$http', '$filter', '$interval', 'ngNotify', 'socketio', function (scope, http, filter, interval, ngNotify, socket) {
        /*
         var song1 = new Song(0,"test title","test interpret","test album",new SongImage(0,"http://kingofwallpapers.com/song/song-010.jpg","https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcR8x47T7Nr_A7F_tos3oKOB3K4DwzFD7ZcKizWmLMPIikNB56in4g"),null);
         var song2 = new Song(1,"Song 2","zweiter interpret","zweites album",new SongImage(1,null,null),null);
         var song3 = new Song(2,"Song 3","zweiter interpret","zweites album",new SongImage(2,"http://kingofwallpapers.com/song/song-001.jpg","https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcT8_SonIBak5_M_5V-IN6MSA2YRJR78X7pvw4hyVYioVwRKtaU-ew"),null);
         scope.allSongs = [song1,song2,song3];
         */
        // Songlist vom Server holen
        http.get('songlist.json').then(function (response) {
            scope.allSongs = response.data;
            scope.changeFilter();
            // scope.$apply();
        }, function (e) {
            console.log("Error: Songlist holen")
        });
        /*
         http.get('songlist.json').success(function (data) {
         scope.allSongs = data;
         scope.changeFilter();
         // scope.$apply();
         });
         */
        scope.addSongToQueue = function (id) {
            socket.emit("command:addToQueue", id);
            //Todo: Pruefung ob der Song wirklich der Queue hinzugefuegt wurde.
            ngNotify.set('Song added to queue!', {
                type: 'success',
                duration: 3000
            });
        };

        http.get('api/v01/getCurrentSong').then(function (response) {
            scope.changeCurrentSong(response.data);
        }, function (e) {
            console.log("Error: Current Song holen")
        });

        //Socket io
        //var socket = io();
        /*    http.get("api/v01/getCurrentSong").success(function (data) {
         scope.changeCurrentSong(data);
         });

         */
        scope.timeLeft = {
            "min": "",
            "sec": ""
        };
        var countdownCtrl;
        scope.changeCurrentSong = function (data) {
            if (data && data != null) {
                scope.playingSong = data;
                if (data.endTime) {
                    countdownCtrl = interval(function () {
                        var distance = scope.playingSong.endTime - new Date().getTime();
                        if (distance < -1) {
                            scope.timeLeft = {
                                "percent": 100,
                                "min": "",
                                "sec": "",
                                "h": ""
                            };
                            scope.changeCurrentSong(null);
                            interval.cancel(countdownCtrl);
                            // scope.playingSong = {"title": "none"};
                            return;
                        }
                        var houre = Math.floor((distance % (1000 * 60 * 60 * 60)) / (1000 * 60 * 60));
                        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                        var seconds = Math.floor((distance % (1000 * 60)) / 1000);
                        minutes = ("00" + minutes).substr(-2, 2);
                        seconds = ("00" + seconds).substr(-2, 2);

                        scope.timeLeft = {
                            "percent": ((1 - ((distance / 1000) / scope.playingSong.duration)) * 100),
                            "min": minutes,
                            "sec": seconds,
                            "h":houre
                        };
                        // console.log("min "+minutes+" sec "+seconds);
                    }, 100);
                }

            } else {
                scope.playingSong = {"title": "none"};
                interval.cancel(countdownCtrl);
                scope.timeLeft = {
                    "min": "",
                    "sec": ""
                };
                if (!scope.$$phase) {
                    scope.$apply();
                }
            }
            // scope.changeFilter();

        };
        scope.queryInput = "";
        socket.on('nowPlaying', function (data) {
            console.log("data " + data);
            scope.changeCurrentSong(data);
        });
        // Filter fuer die Songsuche
        scope.filteredSongs = filter('filter')(scope.allSongs, scope.queryInput);
        scope.selectedFilter = "all";
        scope.changeFilter = function () {

            var songFilterFunction = function (song) {

                switch (scope.selectedFilter) {
                    case "all":
                        var hasTitle = false;
                        if (song.title) {
                            hasTitle = song.title.toLowerCase().indexOf(scope.queryInput.toLocaleLowerCase() || '') !== -1;
                        }
                        var hasArtist = false;
                        if (song.artist) {
                            hasArtist = song.artist.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        var hasAlbum = false;
                        if (song.album) {
                            hasAlbum = song.album.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasTitle || hasArtist || hasAlbum;
                        break;
                    case "title":
                        var hasTitle = false;
                        if (song.title) {
                            hasTitle = song.title.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasTitle;
                        break;
                    case "album":
                        var hasAlbum = false;
                        if (song.album) {
                            hasAlbum = song.album.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasAlbum;
                        break;
                    case "artist":
                        var hasArtist = false;
                        if (song.artist) {
                            hasArtist = song.artist.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasArtist;
                        break;
                }
            };

            scope.filteredSongs = filter('filter')(scope.allSongs, songFilterFunction, scope.queryInput);
        }
    }]);<commit_msg>Anzeige der Stunden hinzugefügt<commit_after>'use strict';

angular.module('myApp.view1', ['ngMaterial', 'ngRoute', 'ngNotify'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$http', '$filter', '$interval', 'ngNotify', 'socketio', function (scope, http, filter, interval, ngNotify, socket) {
        /*
         var song1 = new Song(0,"test title","test interpret","test album",new SongImage(0,"http://kingofwallpapers.com/song/song-010.jpg","https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcR8x47T7Nr_A7F_tos3oKOB3K4DwzFD7ZcKizWmLMPIikNB56in4g"),null);
         var song2 = new Song(1,"Song 2","zweiter interpret","zweites album",new SongImage(1,null,null),null);
         var song3 = new Song(2,"Song 3","zweiter interpret","zweites album",new SongImage(2,"http://kingofwallpapers.com/song/song-001.jpg","https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcT8_SonIBak5_M_5V-IN6MSA2YRJR78X7pvw4hyVYioVwRKtaU-ew"),null);
         scope.allSongs = [song1,song2,song3];
         */
        // Songlist vom Server holen
        http.get('songlist.json').then(function (response) {
            scope.allSongs = response.data;
            scope.changeFilter();
            // scope.$apply();
        }, function (e) {
            console.log("Error: Songlist holen")
        });
        /*
         http.get('songlist.json').success(function (data) {
         scope.allSongs = data;
         scope.changeFilter();
         // scope.$apply();
         });
         */
        scope.addSongToQueue = function (id) {
            socket.emit("command:addToQueue", id);
            //Todo: Pruefung ob der Song wirklich der Queue hinzugefuegt wurde.
            ngNotify.set('Song added to queue!', {
                type: 'success',
                duration: 3000
            });
        };

        http.get('api/v01/getCurrentSong').then(function (response) {
            scope.changeCurrentSong(response.data);
        }, function (e) {
            console.log("Error: Current Song holen")
        });

        //Socket io
        //var socket = io();
        /*    http.get("api/v01/getCurrentSong").success(function (data) {
         scope.changeCurrentSong(data);
         });

         */
        scope.timeLeft = {
            "min": "",
            "sec": ""
        };
        var countdownCtrl;
        scope.changeCurrentSong = function (data) {
            if (data && data != null) {
                scope.playingSong = data;
                if (data.endTime) {
                    countdownCtrl = interval(function () {
                        var distance = scope.playingSong.endTime - new Date().getTime();
                        if (distance < -1) {
                            scope.timeLeft = {
                                "percent": 100,
                                "min": "",
                                "sec": "",
                                "h": ""
                            };
                            scope.changeCurrentSong(null);
                            interval.cancel(countdownCtrl);
                            // scope.playingSong = {"title": "none"};
                            return;
                        }
                        var houre = Math.floor((distance % (1000 * 60 * 60 * 60)) / (1000 * 60 * 60));
                        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
                        var seconds = Math.floor((distance % (1000 * 60)) / 1000);
                        minutes = ("00" + minutes).substr(-2, 2);
                        seconds = ("00" + seconds).substr(-2, 2);

                        scope.timeLeft = {
                            "percent": ((1 - ((distance / 1000) / scope.playingSong.duration)) * 100),
                            "min": minutes,
                            "sec": seconds,
                            "h":houre
                        };
                        // console.log("min "+minutes+" sec "+seconds);
                    }, 100);
                }

            } else {
                scope.playingSong = {"title": "none"};
                interval.cancel(countdownCtrl);
                scope.timeLeft = {
                    "min": "",
                    "sec": ""
                };
                if (!scope.$$phase) {
                    scope.$apply();
                }
            }
            // scope.changeFilter();

        };
        scope.queryInput = "";
        socket.on('nowPlaying', function (data) {
            console.log("data " + data);
            scope.changeCurrentSong(data);
        });
        // Filter fuer die Songsuche
        scope.filteredSongs = filter('filter')(scope.allSongs, scope.queryInput);
        scope.selectedFilter = "all";
        scope.changeFilter = function () {

            var songFilterFunction = function (song) {

                switch (scope.selectedFilter) {
                    case "all":
                        var hasTitle = false;
                        if (song.title) {
                            hasTitle = song.title.toLowerCase().indexOf(scope.queryInput.toLocaleLowerCase() || '') !== -1;
                        }
                        var hasArtist = false;
                        if (song.artist) {
                            hasArtist = song.artist.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        var hasAlbum = false;
                        if (song.album) {
                            hasAlbum = song.album.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasTitle || hasArtist || hasAlbum;
                        break;
                    case "title":
                        var hasTitle = false;
                        if (song.title) {
                            hasTitle = song.title.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasTitle;
                        break;
                    case "album":
                        var hasAlbum = false;
                        if (song.album) {
                            hasAlbum = song.album.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasAlbum;
                        break;
                    case "artist":
                        var hasArtist = false;
                        if (song.artist) {
                            hasArtist = song.artist.toLowerCase().indexOf(scope.queryInput.toLowerCase() || '') !== -1;
                        }
                        return hasArtist;
                        break;
                }
            };

            scope.filteredSongs = filter('filter')(scope.allSongs, songFilterFunction, scope.queryInput);
        }
    }]);<|endoftext|>


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

var View = function(env) {
  if(!this instanceof View) {
    return new View(env);
  }

  this.env = env;

  if(this.env.u) {
    var match = View.urlKeyRegexp.exec(this.env.u);
    if(match && match.length > 2) {
      this._urlKey = match[2];
      this._productId = match[4];
    }
  }
}

View.prototype = {
  urlKey: function() {
    return this._urlKey;
  },

  productId: function() {
    return this._productId;
  },

  event: function() {
    if(this.env.events) {
      if(this.env.events.match(/scAdd/)) {
        this._event = "cart_add";
      } else if(this.env.events === "purchase") {
        this._event = "purchase";
      }
    }

    this.event = function() { return this._event; }
    return this._event;
  }
};

View.urlKeyRegexp = new RegExp(/^http:\/\/[^\/]+(\/s\/|\/sale\/splash\/)([^\/\?]+)\/?(product\/)?(\d+)?/);

exports.View = View;
<commit_msg>Fix broken spec<commit_after>var sys = require('sys');

var View = function(env) {
  if(!this instanceof View) {
    return new View(env);
  }

  this.env = env;

  if(this.env.u) {
    var match = View.urlKeyRegexp.exec(this.env.u);
    if(match && match.length > 2) {
      this._urlKey = match[2];
      this._productId = match[4];
    }
  }
}

View.prototype = {
  urlKey: function() {
    return this._urlKey;
  },

  productId: function() {
    return parseInt(this._productId);
  },

  event: function() {
    if(this.env.events) {
      if(this.env.events.match(/scAdd/)) {
        this._event = "cart_add";
      } else if(this.env.events === "purchase") {
        this._event = "purchase";
      }
    }

    this.event = function() { return this._event; }
    return this._event;
  }
};

View.urlKeyRegexp = new RegExp(/^http:\/\/[^\/]+(\/s\/|\/sale\/splash\/)([^\/\?]+)\/?(product\/)?(\d+)?/);

exports.View = View;
<|endoftext|>


<commit_before>(function() {
  // returns how much "power" a user's votes have
  var getVotePower = function(user){
    return (user && user.isAdmin) ? 5 : 1;
  };

  var modifyKarma = function(userId, karma){
    Meteor.users.update({_id: userId}, {$inc: {karma: karma}});
  };

  var hasUpvotedItem= function(item, user){
    return item.upvoters && item.upvoters.indexOf(user._id) != -1
  }

  var hasDownvotedItem= function(item, user){
    return item.downvoters && item.downvoters.indexOf(user._id) != -1
  }

  var upvoteItem = function(collection, item) {
    var user = Meteor.user(),
        votePower = getVotePower(user);

    // make sure user has rights to upvote first
    if (!user || !canUpvote(user, collection, true)  || hasUpvotedItem(item, user))
      return false;

    // if user is upvoting a previously downvoted item, cancel downvote first
    if (hasDownvotedItem(item, user))
      cancelDownvote(collection, item, user)

    // Votes & Score
    var result = collection.update({_id: item._id},{
      $addToSet: {upvoters: user._id},
      $pull: {downvoters: user._id},
      $inc: {votes: 1, baseScore: votePower},
      $set: {inactive: false}
    });

    updateScore(item, collection, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  var downvoteItem = function(collection, item) {
    var user = Meteor.user(),
        votePower = getVotePower(user);

    // make sure user has rights to downvote first
    if (!user || !canDownvote(user, collection, true)  || hasDownvotedItem(item, user))
      return false;

    // if user is downvoting a previously upvoted item, cancel upvote first
    if (hasUpvotedItem(item, user))
      cancelUpvote(collection, item, user)

    // Votes & Score
    collection.update({_id: id},{
      $addToSet: {downvoters: user._id},
      $pull: {upvoters: user._id},
      $inc: {votes: -1, baseScore: -votePower},
      $set: {inactive: false}
    });

    updateScore(item, collection, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  var cancelUpvote = function(collection, item) {
    var user = Meteor.user();
        votePower = getVotePower(user);

    // if user isn't among the upvoters, abort
    if(!hasUpvotedItem(item, user))
      return false;

    // Votes & Score
    collection.update({_id: id},{
      $pull: {upvoters: user._id},
      $inc: {votes: -1, baseScore: -votePower},
      $set: {inactive: false}
    });

    updateScore(collection, id, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  var cancelDownvote = function(collection, item) {
    var user = Meteor.user(),
      votePower = getVotePower(user);

    // if user isn't among the downvoters, abort
    if(!hasUpvotedItem(item, user))
      return false;

    // Votes & Score
    collection.update({_id: id},{
      $pull: {downvoters: user._id},
      $inc: {votes: 1, baseScore: votePower},
      $set: {inactive: false}
    });

    updateScore(collection, id, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  // note: doesn't actually seem very useful to enable admins to vote for other users. Remove this?
  var getUser = function(user){
    // only let admins specify different users for voting
    // if no user is specified, use current user by default
    return (isAdmin(Meteor.user()) && typeof user !== 'undefined') ? user : Meteor.user();
  }

  Meteor.methods({
    upvotePost: function(post, user){
      return upvoteItem.call(this, Posts, post);
    },
    downvotePost: function(post, user){
      return downvoteItem.call(this, Posts, post);
    },
    cancelUpvotePost: function(post, user){
      return cancelUpvote.call(this, Posts, post);
    },
    cancelDownvotePost: function(post, user){
      return cancelDownvote.call(this, Posts, post);
    },
    upvoteComment: function(comment, user){
      return upvoteItem.call(this, Comments, comment);
    },
    downvoteComment: function(comment, user){
      return upvoteItem.call(this, Comments, comment);
    },
    cancelUpvoteComment: function(comment, user){
      return cancelUpvote.call(this, Comments, comment);
    },
    cancelDownvoteComment: function(comment, user){
      return cancelDownvote.call(this, Comments, comment);
    }
  });

})();<commit_msg>extending post item to calculate score<commit_after>(function() {
  // returns how much "power" a user's votes have
  var getVotePower = function(user){
    return (user && user.isAdmin) ? 5 : 1;
  };

  var modifyKarma = function(userId, karma){
    Meteor.users.update({_id: userId}, {$inc: {karma: karma}});
  };

  var hasUpvotedItem= function(item, user){
    return item.upvoters && item.upvoters.indexOf(user._id) != -1
  }

  var hasDownvotedItem= function(item, user){
    return item.downvoters && item.downvoters.indexOf(user._id) != -1
  }

  var upvoteItem = function(collection, item) {
    var user = Meteor.user(),
        votePower = getVotePower(user);

    // make sure user has rights to upvote first
    if (!user || !canUpvote(user, collection, true)  || hasUpvotedItem(item, user))
      return false;

    // if user is upvoting a previously downvoted item, cancel downvote first
    if (hasDownvotedItem(item, user))
      cancelDownvote(collection, item, user)

    // Votes & Score
    var result = collection.update({_id: item._id},{
      $addToSet: {upvoters: user._id},
      $pull: {downvoters: user._id},
      $inc: {votes: 1, baseScore: votePower},
      $set: {inactive: false}
    });

    // extend item with baseScore to help calculate newScore
    item = _.extend(item, {baseScore: (item.baseScore + votePower)});
    updateScore(item, collection, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  var downvoteItem = function(collection, item) {
    var user = Meteor.user(),
        votePower = getVotePower(user);

    // make sure user has rights to downvote first
    if (!user || !canDownvote(user, collection, true)  || hasDownvotedItem(item, user))
      return false;

    // if user is downvoting a previously upvoted item, cancel upvote first
    if (hasUpvotedItem(item, user))
      cancelUpvote(collection, item, user)

    // Votes & Score
    collection.update({_id: id},{
      $addToSet: {downvoters: user._id},
      $pull: {upvoters: user._id},
      $inc: {votes: -1, baseScore: -votePower},
      $set: {inactive: false}
    });

    // extend item with baseScore to help calculate newScore
    item = _.extend(item, {baseScore: (item.baseScore + votePower)});
    updateScore(item, collection, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  var cancelUpvote = function(collection, item) {
    var user = Meteor.user();
        votePower = getVotePower(user);

    // if user isn't among the upvoters, abort
    if(!hasUpvotedItem(item, user))
      return false;

    // Votes & Score
    collection.update({_id: id},{
      $pull: {upvoters: user._id},
      $inc: {votes: -1, baseScore: -votePower},
      $set: {inactive: false}
    });

    // extend item with baseScore to help calculate newScore
    item = _.extend(item, {baseScore: (item.baseScore + votePower)});
    updateScore(collection, id, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  var cancelDownvote = function(collection, item) {
    var user = Meteor.user(),
      votePower = getVotePower(user);

    // if user isn't among the downvoters, abort
    if(!hasUpvotedItem(item, user))
      return false;

    // Votes & Score
    collection.update({_id: id},{
      $pull: {downvoters: user._id},
      $inc: {votes: 1, baseScore: votePower},
      $set: {inactive: false}
    });

    // extend item with baseScore to help calculate newScore
    item = _.extend(item, {baseScore: (item.baseScore + votePower)});
    updateScore(collection, id, true);

    // if the item is being upvoted by its own author, don't give karma
    if (item.userId != user._id)
      modifyKarma(item.userId, votePower);

    return true;
  };

  // note: doesn't actually seem very useful to enable admins to vote for other users. Remove this?
  var getUser = function(user){
    // only let admins specify different users for voting
    // if no user is specified, use current user by default
    return (isAdmin(Meteor.user()) && typeof user !== 'undefined') ? user : Meteor.user();
  }

  Meteor.methods({
    upvotePost: function(post, user){
      return upvoteItem.call(this, Posts, post);
    },
    downvotePost: function(post, user){
      return downvoteItem.call(this, Posts, post);
    },
    cancelUpvotePost: function(post, user){
      return cancelUpvote.call(this, Posts, post);
    },
    cancelDownvotePost: function(post, user){
      return cancelDownvote.call(this, Posts, post);
    },
    upvoteComment: function(comment, user){
      return upvoteItem.call(this, Comments, comment);
    },
    downvoteComment: function(comment, user){
      return upvoteItem.call(this, Comments, comment);
    },
    cancelUpvoteComment: function(comment, user){
      return cancelUpvote.call(this, Comments, comment);
    },
    cancelDownvoteComment: function(comment, user){
      return cancelDownvote.call(this, Comments, comment);
    }
  });

})();<|endoftext|>


<commit_before>/**
 * Walks the contents of a specified path and processes each file.
 *
 * @package generator
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Dependencies
 */
var async   = require('async'),
    bin     = require('commander'),
    colors  = require('colors'),
    fs      = require('fs'),
    findit  = require('findit');

var exec    = require('child_process').exec;

/**
 * Constructor
 */
function Walk (path, name, verbose) {
    var self = this;
    self.dictionary = new Object(null);

    /**
     * Handle arguments
     */
    self.dictionary['__name__'] = name;
    if (typeof verbose === 'undefined') {
        verbose = false;
    }

    /**
     * File processor queue (FIFO)
     */
    var queue = async.queue(function (file, callback) {
        process(file, function (err, buffer) {
            fs.writeFile(file, buffer, callback);
        });
    }, 1);

    queue.drain = function () {
        console.log('Template ready. Running "make"...'.green);
        exec('make generator', {
            cwd: path
        }, function (err, stdout, stderr) {
            console.log('Complete!'.green);
            process.exit(0);
        });
    };

    /**
     * Add files to the queue.
     */
    var finder = findit.find(path);
    finder.on('file', function (file, stat) {
        queue.push(file);
    });

    /**
     * File processor
     */
    function process(file, callback) {
        fs.readFile(file, function (err, data) {
            if (err) return callback(err);
            var buffer = data.toString();

            // Queue command line prompts
            var q = async.queue(function (key, callback) {
                // Exclude GCC-style macros
                if (key.toUpperCase() === key) {
                    callback();
                } else {
                    // Replace
                    if (typeof self.dictionary[key] !== 'undefined') {
                        buffer = buffer.replace(key, self.dictionary[key]);
                        callback();
                    } else {
                        var human = key.replace(/__/g, '');
                        bin.prompt(human + ': ', function (value) {
                            self.dictionary[key] = value;
                            buffer = buffer.replace(key, self.dictionary[key]);
                            callback();
                        });
                    }
                }
            }, 1);

            // Create the match list and push to queue
            var regex = /__(.*?)__/ig;
            var match = buffer.match(regex);
            if (match === null) {
                return callback(null, buffer);
            } else {
                q.push(match);
            }

            // Continue
            q.drain = function () {
                callback(null, buffer);
            };
        });
    }
};

/**
 * Export
 */
module.exports = Walk;
<commit_msg>Fix process function conflict with global process<commit_after>/**
 * Walks the contents of a specified path and processes each file.
 *
 * @package generator
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Dependencies
 */
var async   = require('async'),
    bin     = require('commander'),
    colors  = require('colors'),
    fs      = require('fs'),
    findit  = require('findit');

var exec    = require('child_process').exec;

/**
 * Constructor
 */
function Walk (path, name, verbose) {
    var self = this;
    self.dictionary = new Object(null);

    /**
     * Handle arguments
     */
    self.dictionary['__name__'] = name;
    if (typeof verbose === 'undefined') {
        verbose = false;
    }

    /**
     * File processor queue (FIFO)
     */
    var queue = async.queue(function (file, callback) {
        processFile(file, function (err, buffer) {
            fs.writeFile(file, buffer, callback);
        });
    }, 1);

    queue.drain = function () {
        console.log('Template ready. Running "make"...'.green);
        exec('make generator', {
            cwd: path
        }, function (err, stdout, stderr) {
            console.log('Complete!'.green);
            process.exit(0);
        });
    };

    /**
     * Add files to the queue.
     */
    var finder = findit.find(path);
    finder.on('file', function (file, stat) {
        queue.push(file);
    });

    /**
     * File processor
     */
    function processFile(file, callback) {
        fs.readFile(file, function (err, data) {
            if (err) return callback(err);
            var buffer = data.toString();

            // Queue command line prompts
            var q = async.queue(function (key, callback) {
                // Exclude GCC-style macros
                if (key.toUpperCase() === key) {
                    callback();
                } else {
                    // Replace
                    if (typeof self.dictionary[key] !== 'undefined') {
                        buffer = buffer.replace(key, self.dictionary[key]);
                        callback();
                    } else {
                        var human = key.replace(/__/g, '');
                        bin.prompt(human + ': ', function (value) {
                            self.dictionary[key] = value;
                            buffer = buffer.replace(key, self.dictionary[key]);
                            callback();
                        });
                    }
                }
            }, 1);

            // Create the match list and push to queue
            var regex = /__(.*?)__/ig;
            var match = buffer.match(regex);
            if (match === null) {
                return callback(null, buffer);
            } else {
                q.push(match);
            }

            // Continue
            q.drain = function () {
                callback(null, buffer);
            };
        });
    }
};

/**
 * Export
 */
module.exports = Walk;
<|endoftext|>


<commit_before>///
/// Class: GPU
///
/// Initialises the GPU.js library class which manages the WebGL context for the created functions.
///
var GPU = (function() {
	return gpu_core;
})();
<commit_msg>support_webgl() public function<commit_after>///
/// Class: GPU
///
/// Initialises the GPU.js library class which manages the WebGL context for the created functions.
///
var GPU = (function() {
	var GPU = gpu_core;

	///
	/// Function: support_webgl
	///
	/// Return TRUE, if browser supports webgl AND canvas
	///
	/// Note: This function can also be called directly `GPU.support_webgl()`
	///
	/// Returns:
	/// 	{Boolean} TRUE if browser supports webgl
	///
	function support_webgl() {
		return gpu_utils.browserSupport_webgl();
	}
	GPU.prototype.support_webgl = support_webgl;

	return GPU;
})();
<|endoftext|>


<commit_before>$(function () {
  messages_control();
});

/**
 * Gestion los efectos automaticos de los mensajes
 */
function messages_control() {
  $(".show_message").hide();
  $(".show_message").fadeIn(500);
  setInterval(function () {
    $(".auto_hide").hide(1000);
  }, 3500);
}

/**
 * convierte un porcentaje indicado en pixeles con base en la resolución de la pantalla (ancho, alto).
 *
 * @param {int} percent Es el porcentaje que se desea convertir a pixeles.
 *
 * @param {boolean} is_width Indica si la conversion se hace respecto al ancho(true) o alto(false). true por omisión.
 *
 * @author Jose Wilson Capera Castaño - josewilsoncc@hotmail.com
 * @date 2015/01/06
 */

function percentage_dimension(percent, is_width) {
  is_width = is_width !== undefined? is_width : true;
  var total = document.body ?
          (is_width ? document.body.clientWidth : document.body.clientHeight) :
          (is_width ? window.innerWidth : window.innerHeight);
  return (percent * total) / 100;
}<commit_msg>My_ci.js percent dimention. resolve #41<commit_after>$(function () {
  messages_control();
});

/**
 * Gestion los efectos automaticos de los mensajes
 */
function messages_control() {
  $(".show_message").hide();
  $(".show_message").fadeIn(500);
  setInterval(function () {
    $(".auto_hide").hide(1000);
  }, 3500);
}

/**
 * Convierte un porcentaje indicado en pixeles con base en la resolución de la pantalla (ancho, alto).
 *
 * @param {int} percent Es el porcentaje que se desea convertir a pixeles.
 *
 * @param {boolean} is_width Indica si la conversion se hace respecto al ancho(true) o alto(false). true por omisión.
 *
 * @author Jose Wilson Capera Castaño - josewilsoncc@hotmail.com
 * @date 2015/01/06
 */

function percentage_dimension(percent, is_width) {
  is_width = is_width !== undefined? is_width : true;
  var total = document.body ?
          (is_width ? document.body.clientWidth : document.body.clientHeight) :
          (is_width ? window.innerWidth : window.innerHeight);
  return (percent * total) / 100;
}<|endoftext|>


<commit_before>GUI = function (game, gameData) {
    Phaser.Group.call(this, game);
    this.y = game.height-80

    this.dictionary = game.cache.getJSON('dic-eng-std')
    this.gameData = gameData
    this.markedList = []

    this.add(game.add.button(10, 9, 'sprites', this.clear, this, 'clear', 'clear'))
    this.add(game.add.button(75, 9, 'sprites', this.accept, this, 'accept', 'accept'))

    var panel  = this.create(0, 0, 'sprites', 'panel')

    var style = { font: "15px Arial", align: "center" };
    this.scoreText = game.add.text(game.world.centerX,
				   14,
				   "0",
				   style)
    this.scoreText.anchor.setTo(0.5)
    this.add(this.scoreText)

    this.word = game.add.text(game.world.centerX-30,
    			      35)
    this.add(this.word)

    // Hotkeys
    var space = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR)
    space.onDown.add(this.accept, this);

    var x = game.input.keyboard.addKey(Phaser.Keyboard.X)
    x.onDown.add(this.clear, this);
}

GUI.prototype = Object.create(Phaser.Group.prototype)
GUI.prototype.constructor = GUI

GUI.prototype.clear = function () {
    this.markedList.forEach(function(box) {
	box.mark(false)
    }, this);
    this.markedList = []
    this.word.text = ""
}

GUI.prototype.accept = function () {

    var word = this.word.text.toLowerCase()

    // Check if word is in dictionary
    if(this.word.text.length < 2 ||
       this.dictionary.indexOf(word) == -1)
	return

    // Remove all word letters
    var score = 0
    this.markedList.forEach(function(box) {
	score += box.points
	this.gameData.tiles_cleared++
	box.remove()
    }, this);

    if( score > this.gameData.best_word.score){
	this.gameData.best_word.score = score
	this.gameData.best_word.word = word
    }

    this.gameData.karma += score - 6
    this.gameData.score += score
    this.scoreText.setText(this.gameData.score)

    this.clear()
}

GUI.prototype.box_clicked = function (box) {
    if( box.marked )
	this.markedList.push(box)
    else{
	var index = this.markedList.findIndex(b => b.id == box.id)
	this.markedList.splice(index, 1)
    }

    this.word.text = ""
    this.markedList.forEach(function(b) {
	this.word.text += b.text.text
    }, this)
}
<commit_msg>Add word score to gui<commit_after>GUI = function (game, gameData) {
    Phaser.Group.call(this, game);
    this.y = game.height-80

    this.dictionary = game.cache.getJSON('dic-eng-std')
    this.gameData = gameData
    this.markedList = []

    this.add(game.add.button(10, 9, 'sprites', this.clear, this, 'clear', 'clear'))
    this.add(game.add.button(75, 9, 'sprites', this.accept, this, 'accept', 'accept'))

    var panel  = this.create(0, 0, 'sprites', 'panel')

    var style = { font: "15px Arial", align: "center" };
    this.scoreText = game.add.text(game.world.centerX,
				   14,
				   "0",
				   style)
    this.scoreText.anchor.setTo(0.5)
    this.add(this.scoreText)

    this.word = game.add.text(game.world.centerX-30,
    			      35)
    this.add(this.word)

    var ws_style = { font: "10px Arial", align: "center" };
    this.wordScore = game.add.text(5, -5, "0", ws_style)
    this.word.addChild(this.wordScore)

    // Hotkeys
    var space = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR)
    space.onDown.add(this.accept, this);

    var x = game.input.keyboard.addKey(Phaser.Keyboard.X)
    x.onDown.add(this.clear, this);
}

GUI.prototype = Object.create(Phaser.Group.prototype)
GUI.prototype.constructor = GUI

GUI.prototype.clear = function () {
    this.markedList.forEach(function(box) {
	box.mark(false)
    }, this);
    this.markedList = []
    this.word.text = ""
}

GUI.prototype.accept = function () {

    var word = this.word.text.toLowerCase()

    // Check if word is in dictionary
    if(this.word.text.length < 2 ||
       this.dictionary.indexOf(word) == -1)
	return

    // Remove all word letters
    var score = 0
    this.markedList.forEach(function(box) {
	score += box.points
	this.gameData.tiles_cleared++
	box.remove()
    }, this);

    if( score > this.gameData.best_word.score){
	this.gameData.best_word.score = score
	this.gameData.best_word.word = word
    }

    this.gameData.karma += score - 6
    this.gameData.score += score
    this.scoreText.setText(this.gameData.score)

    this.clear()
}

GUI.prototype.box_clicked = function (box) {
    if( box.marked )
	this.markedList.push(box)
    else{
	var index = this.markedList.findIndex(b => b.id == box.id)
	this.markedList.splice(index, 1)
    }

    this.word.text = ""
    var points = 0
    this.markedList.forEach(function(b) {
	this.word.text += b.text.text
	points += b.points
    }, this)
    this.wordScore.x = this.word.width
    this.wordScore.text = points
}
<|endoftext|>


<commit_before>'use strict';

angular.module('exampleApp').controller('employeesCtrl', ['$scope', '$sailsBind', '$q', '$http', 'departments',
  function ($scope, $sailsBind, $q, $http, departments) {
    $scope.departments = departments;
    $sailsBind.bind('api/employee', $scope);
    $sailsBind.bind('api/department', $scope);

    $scope.showDepartment = function(employee) {
      return _.result(_.find($scope.departments, { id: employee.department }), 'name');
    };

    $scope.updateDepartment = function(employee, data) {
      var d = $q.defer();

      $http.put('api/employee/' + employee.id, {
        department: data
      })
      .success(function(response) {
        d.resolve(false);
      })
      .error(function(response) {
        if(angular.isObject(response)) {
          if(response.hasOwnProperty('message')) {
            d.reject(response.message);
          } else {
            d.reject('API Error!');
          }
        } else {
          d.reject('Unknown API Error!');
        }
      });

      return d.promise;
    };

    $scope.updateSalary = function(employee, data) {
      var d = $q.defer();

      $http.put('api/employee/' + employee.id, {
        salary: data
      })
      .success(function(response) {
        d.resolve(false);
      })
      .error(function(response) {
        if(angular.isObject(response)) {
          if(response.hasOwnProperty('message')) {
            d.reject(response.message);
          } else {
            d.reject('API Error!');
          }
        } else {
          d.reject('Unknown API Error!');
        }
      });

      return d.promise;
    };
  }
]);
<commit_msg>debugging<commit_after>'use strict';

angular.module('exampleApp').controller('employeesCtrl', ['$scope', '$sailsBind', '$q', '$http',
  function ($scope, $sailsBind, $q, $http ) {
    $scope.departments = departments;
    $sailsBind.bind('api/employee', $scope);
    $sailsBind.bind('api/department', $scope);

    $scope.showDepartment = function(employee) {
      return _.result(_.find($scope.departments, { id: employee.department }), 'name');
    };

    $scope.updateDepartment = function(employee, data) {
      var d = $q.defer();

      $http.put('api/employee/' + employee.id, {
        department: data
      })
      .success(function(response) {
        d.resolve(false);
      })
      .error(function(response) {
        if(angular.isObject(response)) {
          if(response.hasOwnProperty('message')) {
            d.reject(response.message);
          } else {
            d.reject('API Error!');
          }
        } else {
          d.reject('Unknown API Error!');
        }
      });

      return d.promise;
    };

    $scope.updateSalary = function(employee, data) {
      var d = $q.defer();

      $http.put('api/employee/' + employee.id, {
        salary: data
      })
      .success(function(response) {
        d.resolve(false);
      })
      .error(function(response) {
        if(angular.isObject(response)) {
          if(response.hasOwnProperty('message')) {
            d.reject(response.message);
          } else {
            d.reject('API Error!');
          }
        } else {
          d.reject('Unknown API Error!');
        }
      });

      return d.promise;
    };
  }
]);
<|endoftext|>


<commit_before>// this class is not really related to a sampleToc but can be used for any TOC

import API from 'src/util/api';
import Versioning from 'src/util/versioning';

let defaultOptions = {
  group: 'all',
  varName: 'sampleToc',
  viewName: 'sample_toc',
  filter: (entry) => !entry.value.hidden,
  sort: (a, b) => {
    if (a.value.modified && a.value.modified > b.value.modified) {
      return -1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate > b.value.modificationDate
    ) {
      return -1;
    } else if (a.value.modified && a.value.modified < b.value.modified) {
      return 1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate < b.value.modificationDate
    ) {
      return 1;
    } else {
      return 0;
    }
  },
};

class Toc {
  /**
   * Create an object managing the Toc
   * @param {object} [options={}]
   * @param {object} [roc=undefined]
   * @param {string} [options.group='mine'] Group to retrieve products. mine, all of a specific group name
   * @param {string} [options.varName='sampleToc']
   * @param {string} [options.viewName='sample_toc']
   * @param {function} [options.sort] Callback, by default sort by reverse date
   * @param {function} [options.filter] Callback to filter the result
   */
  constructor(roc, options = {}) {
    this.roc = roc;
    this.options = Object.assign({}, defaultOptions, options);
  }

  setFilter(filter) {
    this.options.filter = filter;
    return this.refresh();
  }

  /**
   * Retrieve the toc and put the result in the specified variable
   *
   */
  refresh(options = {}) {
    let {
      group,
      sort,
      filter,
      viewName,
      limit,
      startkey,
      endkey,
      key,
      descending,
    } = Object.assign({}, this.options, options);
    let mine = 0;
    let groups = '';
    group = String(group);
    if (group === 'mine') {
      mine = 1;
    } else if (group !== 'all') {
      groups = group;
    }
    return this.roc
      .query(viewName, {
        groups,
        mine,
        sort,
        filter,
        limit,
        startkey,
        endkey,
        key,
        descending,
        varName: this.options.varName,
      })
      .then((entries) => {
        if (this.options.callback) {
          entries.forEach(this.options.callback);
        }
        return entries;
      });
  }

  /**
   * Retrieve the allowed groups for the logged in user and create 'groupForm'
   * variable and 'groupFormSchema' (for onde module). It will keep in a cookie
   * the last selected group. Calling this method should reload automatically
   * @param {object} [options={}]
   * @param {string} [varName='groupForm'] contains the name of the variable containing the form value
   * @param {string} [schemaVarName='groupFormSchema'] contains the name of the variable containing the form schema
   * @param {string} [cookieName='eln-default-sample-group''] cookie name containing the last selected group
   * @param {string} [filter] filter applied on first refresh
   * @param {string} [autoRefresh=true] refresh least after initialization
   * @param {boolean} [listAllGroups=true] select from any group, even if not the a member
   * @return {string} the form to select group}
   */
  async initializeGroupForm(options = {}) {
    const {
      schemaVarName = 'groupFormSchema',
      varName = 'groupForm',
      cookieName = 'eln-default-sample-group',
      filter,
      autoRefresh = true,
      listAllGroups = false,
    } = options;

    let groups = [];
    if (listAllGroups) {
      groups = (await this.roc.getGroupsInfo()).map((g) => g.name);
    } else {
      groups = (await this.roc.getGroupMembership()).map((g) => g.name);
    }

    var possibleGroups = ['all', 'mine'].concat(groups);
    var defaultGroup = localStorage.getItem(cookieName);
    if (possibleGroups.indexOf(defaultGroup) === -1) {
      defaultGroup = 'all';
    }
    var schema = {
      type: 'object',
      properties: {
        group: {
          type: 'string',
          enum: possibleGroups,
          default: defaultGroup,
          required: true,
        },
      },
    };
    API.createData(schemaVarName, schema);

    let groupForm = await API.createData(varName, { group: defaultGroup });

    this.options.group = groupForm.group;
    if (autoRefresh) {
      await this.refresh(filter);
    }
    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        localStorage.setItem(cookieName, groupForm.group);
        this.options.group = String(groupForm.group);
        this.refresh();
      }
    });

    return groupForm;
  }
}

module.exports = Toc;
<commit_msg>feat: Toc deals with initializeSampleFilter and twig templates<commit_after>// this class is not really related to a sampleToc but can be used for any TOC

import API from 'src/util/api';
import Versioning from 'src/util/versioning';

let defaultOptions = {
  group: 'all',
  varName: 'sampleToc',
  viewName: 'sample_toc',
  filter: (entry) => !entry.value.hidden,
  sort: (a, b) => {
    if (a.value.modified && a.value.modified > b.value.modified) {
      return -1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate > b.value.modificationDate
    ) {
      return -1;
    } else if (a.value.modified && a.value.modified < b.value.modified) {
      return 1;
    } else if (
      a.value.modificationDate &&
      a.value.modificationDate < b.value.modificationDate
    ) {
      return 1;
    } else {
      return 0;
    }
  },
};

class Toc {
  /**
   * Create an object managing the Toc
   * @param {object} [options={}]
   * @param {object} [roc=undefined]
   * @param {string} [options.group='mine'] Group to retrieve products. mine, all of a specific group name
   * @param {string} [options.varName='sampleToc']
   * @param {string} [options.viewName='sample_toc']
   * @param {function} [options.sort] Callback, by default sort by reverse date
   * @param {function} [options.filter] Callback to filter the result
   */
  constructor(roc, options = {}) {
    this.roc = roc;
    this.options = Object.assign({}, defaultOptions, options);
  }

  setFilter(filter) {
    this.options.filter = filter;
    return this.refresh();
  }

  /**
   * Retrieve the toc and put the result in the specified variable
   *
   */
  refresh(options = {}) {
    let {
      group,
      sort,
      filter,
      viewName,
      limit,
      startkey,
      endkey,
      key,
      descending,
    } = Object.assign({}, this.options, options);
    let mine = 0;
    let groups = '';
    group = String(group);
    if (group === 'mine') {
      mine = 1;
    } else if (group !== 'all') {
      groups = group;
    }
    return this.roc
      .query(viewName, {
        groups,
        mine,
        sort,
        filter,
        limit,
        startkey,
        endkey,
        key,
        descending,
        varName: this.options.varName,
      })
      .then((entries) => {
        if (this.options.callback) {
          entries.forEach(this.options.callback);
        }
        return entries;
      });
  }

  async initializeSampleFilter(options = {}) {
    const {
      twigVarName = 'sampleFilterTwig',
      varName = 'sampleFilter',
      cookieName = 'eln-default-sample-filter',
      filter,
      autoRefresh = true,
      listAllGroups = false,
    } = options;

    let groups = [];
    if (listAllGroups) {
      groups = (await this.roc.getGroupsInfo()).map((g) => g.name);
    } else {
      groups = (await this.roc.getGroupMembership()).map((g) => g.name);
    }

    const defaultSampleFilter = {
      group: 'mine',
      startEpoch: 24 * 3600 * 1000 * 31,
      endEpoch: '',
    };
    const sampleFilter = localStorage.getItem(cookieName)
      ? JSON.parse(localStorage.getItem(cookieName))
      : defaultSampleFilter;
    API.createData(varName, sampleFilter);

    this.updateOptions(sampleFilter);

    const sampleFilterTwig = `
Group: <select name="group">
<option value='all'>All</option>
<option value='mine'>Mine</option>
${groups.map((group) => '<option value="' + group + '">' + group + '</option>')}
</select>
Period: <select name="startEpoch">
<option value='${24 * 3600 * 1000 * 31}'>Last month</option>
<option value='${24 * 3600 * 1000 * 91}'>Last 3 months</option>
<option value='${24 * 3600 * 1000 * 182}'>Last 6 months</option>
<option value='${24 * 3600 * 1000 * 365}'>Last year</option>
<option value='${24 * 3600 * 1000 * 730}'>Last 2 years</option>
<option value='${24 * 3600 * 1000 * 1830}'>Last 5 years</option>
<option value=''>Any time</option>
</select>
`;
    API.createData(twigVarName, sampleFilterTwig);

    if (autoRefresh) {
      await this.refresh(filter);
    }
    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        const currentSampleFilter = API.getData(varName).resurrect();
        localStorage.setItem(cookieName, JSON.stringify(currentSampleFilter));
        this.updateOptions(currentSampleFilter);
        this.refresh();
      }
    });
  }

  updateOptions(options) {
    this.options.group = options.group;
    this.options.startkey = options.startEpoch
      ? Date.now() - options.startEpoch
      : undefined;
    this.options.endkey = undefined;
  }

  /**
   * Retrieve the allowed groups for the logged in user and create 'groupForm'
   * variable and 'groupFormSchema' (for onde module). It will keep in a cookie
   * the last selected group. Calling this method should reload automatically
   * @param {object} [options={}]
   * @param {string} [varName='groupForm'] contains the name of the variable containing the form value
   * @param {string} [schemaVarName='groupFormSchema'] contains the name of the variable containing the form schema
   * @param {string} [cookieName='eln-default-sample-group''] cookie name containing the last selected group
   * @param {string} [filter] filter applied on first refresh
   * @param {string} [autoRefresh=true] refresh least after initialization
   * @param {boolean} [listAllGroups=true] select from any group, even if not the a member
   * @return {string} the form to select group}
   */
  async initializeGroupForm(options = {}) {
    const {
      schemaVarName = 'groupFormSchema',
      varName = 'groupForm',
      cookieName = 'eln-default-sample-group',
      filter,
      autoRefresh = true,
      listAllGroups = false,
    } = options;

    let groups = [];
    if (listAllGroups) {
      groups = (await this.roc.getGroupsInfo()).map((g) => g.name);
    } else {
      groups = (await this.roc.getGroupMembership()).map((g) => g.name);
    }

    var possibleGroups = ['all', 'mine'].concat(groups);
    var defaultGroup = localStorage.getItem(cookieName);
    if (possibleGroups.indexOf(defaultGroup) === -1) {
      defaultGroup = 'all';
    }
    var schema = {
      type: 'object',
      properties: {
        group: {
          type: 'string',
          enum: possibleGroups,
          default: defaultGroup,
          required: true,
        },
      },
    };
    API.createData(schemaVarName, schema);

    let groupForm = await API.createData(varName, { group: defaultGroup });

    this.options.group = groupForm.group;
    if (autoRefresh) {
      await this.refresh(filter);
    }
    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        localStorage.setItem(cookieName, groupForm.group);
        this.options.group = String(groupForm.group);
        this.refresh();
      }
    });

    return groupForm;
  }
}

module.exports = Toc;
<|endoftext|>


<commit_before>/**
 * An implementation of Google Maps' MVCObject.
 * @see https://developers.google.com/maps/articles/mvcfun
 * @see https://developers.google.com/maps/documentation/javascript/reference
 */

goog.provide('ol.Object');
goog.provide('ol.ObjectEvent');
goog.provide('ol.ObjectEventType');

goog.require('goog.array');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.functions');
goog.require('goog.object');
goog.require('ol.Observable');

/**
 * @enum {string}
 */
ol.ObjectEventType = {
  /**
   * Triggered before a property is changed.
   * @event ol.ObjectEvent#beforepropertychange
   * @todo stability experimental
   */
  BEFOREPROPERTYCHANGE: 'beforepropertychange',
  /**
   * Triggered when a property is changed.
   * @event ol.ObjectEvent#propertychange
   * @todo stability experimental
   */
  PROPERTYCHANGE: 'propertychange'
};

/**
 * Object representing a property change event.
 *
 * @param {string} type The event type.
 * @param {string} key The property name.
 * @extends {goog.events.Event}
 * @implements {oli.ObjectEvent}
 * @constructor
 */
ol.ObjectEvent = function(type, key) {
  goog.base(this, type);

  // Call goog.getUid to ensure that the order of objects' ids is the same as
  // the order in which they were created.  This also helps to ensure that
  // object properties are always added in the same order, which helps many
  // JavaScript engines generate faster code.
  goog.getUid(this);

  /**
   * The name of the property whose value is changing.
   * @type {string}
   */
  this.key = key;

};
goog.inherits(ol.ObjectEvent, goog.events.Event);

/**
 * @constructor
 * @param {ol.Object} target
 * @param {string} key
 * @todo stability experimental
 */
ol.ObjectAccessor = function(target, key) {

  /**
   * @type {ol.Object}
   */
  this.target = target;

  /**
   * @type {string}
   */
  this.key = key;

  /**
   * @type {function(?): ?}
   */
  this.from = goog.functions.identity;

  /**
   * @type {function(?): ?}
   */
  this.to = goog.functions.identity;
};

/**
 * @param {function(?): ?} from A function that transforms the source value
 *     before it is set to the target.
 * @param {function(?): ?} to A function that transforms the target value
 *     before it is set to the source.
 */
ol.ObjectAccessor.prototype.transform = function(from, to) {
  this.from = from;
  this.to = to;

  this.target.notify(this.key);
};

/**
 * Base class implementing KVO (Key Value Observing).
 * @constructor
 * @extends {ol.Observable}
 * @param {Object.<string, *>=} opt_values Values.
 * @fires {@link ol.ObjectEvent} ol.ObjectEvent
 * @todo stability experimental
 */
ol.Object = function(opt_values) {
  goog.base(this);

  /**
   * @private
   * @type {Object.<string, *>}
   */
  this.values_ = {};

  /**
   * @private
   * @type {Object.<string, ol.ObjectAccessor>}
   */
  this.accessors_ = {};

  /**
   * Lookup of beforechange listener keys.
   * @type {Object.<string, goog.events.Key>}
   * @private
   */
  this.beforeChangeListeners_ = {};

  /**
   * @private
   * @type {Object.<string, goog.events.Key>}
   */
  this.listeners_ = {};

  if (goog.isDef(opt_values)) {
    this.setValues(opt_values);
  }
};
goog.inherits(ol.Object, ol.Observable);

/**
 * @private
 * @type {Object.<string, string>}
 */
ol.Object.changeEventTypeCache_ = {};

/**
 * @private
 * @type {Object.<string, string>}
 */
ol.Object.getterNameCache_ = {};

/**
 * @private
 * @type {Object.<string, string>}
 */
ol.Object.setterNameCache_ = {};

/**
 * @param {string} str String.
 * @return {string} Capitalized string.
 */
ol.Object.capitalize = function(str) {
  return str.substr(0, 1).toUpperCase() + str.substr(1);
};

/**
 * @param {string} key Key name.
 * @return {string} Change name.
 */
ol.Object.getChangeEventType = function(key) {
  return ol.Object.changeEventTypeCache_.hasOwnProperty(key) ?
      ol.Object.changeEventTypeCache_[key] :
      (ol.Object.changeEventTypeCache_[key] = 'change:' + key.toLowerCase());
};

/**
 * @param {string} key String.
 * @return {string} Getter name.
 */
ol.Object.getGetterName = function(key) {
  return ol.Object.getterNameCache_.hasOwnProperty(key) ?
      ol.Object.getterNameCache_[key] :
      (ol.Object.getterNameCache_[key] = 'get' + ol.Object.capitalize(key));
};

/**
 * @param {string} key String.
 * @return {string} Setter name.
 */
ol.Object.getSetterName = function(key) {
  return ol.Object.setterNameCache_.hasOwnProperty(key) ?
      ol.Object.setterNameCache_[key] :
      (ol.Object.setterNameCache_[key] = 'set' + ol.Object.capitalize(key));
};

/**
 * The bindTo method allows you to set up a two-way binding between a
 * `source` and `target` object. The method returns an
 * ol.ObjectAccessor with a transform method that lets you transform
 * values on the way from the source to the target and on the way back.
 *
 * For example, if you had two map views (sourceView and targetView)
 * and you wanted the target view to have double the resolution of the
 * source view, you could transform the resolution on the way to and
 * from the target with the following:
 *
 *     sourceView.bindTo('resolution', targetView)
 *       .transform(
 *         function(sourceResolution) {
 *           // from sourceView.resolution to targetView.resolution
 *           return 2 * sourceResolution;
 *         },
 *         function(targetResolution) {
 *           // from targetView.resolution to sourceView.resolution
 *           return targetResolution / 2;
 *         }
 *       );
 *
 * @param {string} key Key name.
 * @param {ol.Object} target Target.
 * @param {string=} opt_targetKey Target key.
 * @return {ol.ObjectAccessor}
 * @todo stability experimental
 */
ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
  var targetKey = opt_targetKey || key;
  this.unbind(key);

  // listen for change:targetkey events
  var eventType = ol.Object.getChangeEventType(targetKey);
  this.listeners_[key] = goog.events.listen(target, eventType,
      /**
       * @this {ol.Object}
       */
      function() {
        this.notifyInternal_(key);
      }, undefined, this);

  // listen for beforechange events and relay if key matches
  this.beforeChangeListeners_[key] = goog.events.listen(target,
      ol.ObjectEventType.BEFOREPROPERTYCHANGE,
      this.createBeforeChangeListener_(key, targetKey),
      undefined, this);

  var accessor = new ol.ObjectAccessor(target, targetKey);
  this.accessors_[key] = accessor;
  this.notifyInternal_(key);
  return accessor;
};

/**
 * Create a listener for beforechange events on a target object.  This listener
 * will relay events on this object if the event key matches the provided target
 * key.
 * @param {string} key The key on this object whose value will be changing.
 * @param {string} targetKey The key on the target object.
 * @return {function(this: ol.Object, ol.ObjectEvent)} Listener.
 * @private
 */
ol.Object.prototype.createBeforeChangeListener_ = function(key, targetKey) {
  /**
   * Conditionally relay beforechange events if event key matches target key.
   * @param {ol.ObjectEvent} event The beforechange event from the target.
   * @this {ol.Object}
   */
  return function(event) {
    if (event.key === targetKey) {
      this.dispatchEvent(
          new ol.ObjectEvent(ol.ObjectEventType.BEFOREPROPERTYCHANGE, key));
    }
  };
};

/**
 * Gets a value.
 * @param {string} key Key name.
 * @return {*} Value.
 * @todo stability experimental
 */
ol.Object.prototype.get = function(key) {
  var value;
  var accessors = this.accessors_;
  if (accessors.hasOwnProperty(key)) {
    var accessor = accessors[key];
    var target = accessor.target;
    var targetKey = accessor.key;
    var getterName = ol.Object.getGetterName(targetKey);
    var getter = /** @type {function(): *|undefined} */
        (goog.object.get(target, getterName));
    if (goog.isDef(getter)) {
      value = getter.call(target);
    } else {
      value = target.get(targetKey);
    }
    value = accessor.to(value);
  } else if (this.values_.hasOwnProperty(key)) {
    value = this.values_[key];
  }
  return value;
};

/**
 * Get a list of object property names.
 * @return {Array.<string>} List of property names.
 */
ol.Object.prototype.getKeys = function() {
  var accessors = this.accessors_;
  var keysObject;
  if (goog.object.isEmpty(this.values_)) {
    if (goog.object.isEmpty(accessors)) {
      return [];
    } else {
      keysObject = accessors;
    }
  } else {
    if (goog.object.isEmpty(accessors)) {
      keysObject = this.values_;
    } else {
      keysObject = {};
      var key;
      for (key in this.values_) {
        keysObject[key] = true;
      }
      for (key in accessors) {
        keysObject[key] = true;
      }
    }
  }
  return goog.object.getKeys(keysObject);
};

/**
 * Get an object of all property names and values.
 * @return {Object.<string, *>} Object.
 * @todo stability experimental
 */
ol.Object.prototype.getProperties = function() {
  var properties = {};
  var key;
  for (key in this.values_) {
    properties[key] = this.values_[key];
  }
  for (key in this.accessors_) {
    properties[key] = this.get(key);
  }
  return properties;
};

/**
 * Notify all observers of a change on this property. This notifies both
 * objects that are bound to the object's property as well as the object
 * that it is bound to.
 * @param {string} key Key name.
 * @todo stability experimental
 */
ol.Object.prototype.notify = function(key) {
  var accessors = this.accessors_;
  if (accessors.hasOwnProperty(key)) {
    var accessor = accessors[key];
    var target = accessor.target;
    var targetKey = accessor.key;
    target.notify(targetKey);
  } else {
    this.notifyInternal_(key);
  }
};

/**
 * @param {string} key Key name.
 * @private
 */
ol.Object.prototype.notifyInternal_ = function(key) {
  var eventType = ol.Object.getChangeEventType(key);
  this.dispatchEvent(eventType);
  this.dispatchEvent(
      new ol.ObjectEvent(ol.ObjectEventType.PROPERTYCHANGE, key));
};

/**
 * Sets a value.
 * @param {string} key Key name.
 * @param {*} value Value.
 * @todo stability experimental
 */
ol.Object.prototype.set = function(key, value) {
  this.dispatchEvent(
      new ol.ObjectEvent(ol.ObjectEventType.BEFOREPROPERTYCHANGE, key));
  var accessors = this.accessors_;
  if (accessors.hasOwnProperty(key)) {
    var accessor = accessors[key];
    var target = accessor.target;
    var targetKey = accessor.key;
    value = accessor.from(value);
    var setterName = ol.Object.getSetterName(targetKey);
    var setter = /** @type {function(*)|undefined} */
        (goog.object.get(target, setterName));
    if (goog.isDef(setter)) {
      setter.call(target, value);
    } else {
      target.set(targetKey, value);
    }
  } else {
    this.values_[key] = value;
    this.notifyInternal_(key);
  }
};

/**
 * Sets a collection of key-value pairs.
 * @param {Object.<string, *>} values Values.
 * @todo stability experimental
 */
ol.Object.prototype.setValues = function(values) {
  var key;
  for (key in values) {
    this.set(key, values[key]);
  }
};

/**
 * Removes a binding. Unbinding will set the unbound property to the current
 *     value. The object will not be notified, as the value has not changed.
 * @param {string} key Key name.
 * @todo stability experimental
 */
ol.Object.prototype.unbind = function(key) {
  var listeners = this.listeners_;
  var listener = listeners[key];
  if (listener) {
    delete listeners[key];
    goog.events.unlistenByKey(listener);
    var value = this.get(key);
    delete this.accessors_[key];
    this.values_[key] = value;
  }

  // unregister any beforechange listener
  var listenerKey = this.beforeChangeListeners_[key];
  if (listenerKey) {
    goog.events.unlistenByKey(listenerKey);
    delete this.beforeChangeListeners_[key];
  }
};

/**
 * Removes all bindings.
 * @todo stability experimental
 */
ol.Object.prototype.unbindAll = function() {
  for (var key in this.listeners_) {
    this.unbind(key);
  }
};
<commit_msg>Fix location of call to goog.getUid, thanks @elemoine<commit_after>/**
 * An implementation of Google Maps' MVCObject.
 * @see https://developers.google.com/maps/articles/mvcfun
 * @see https://developers.google.com/maps/documentation/javascript/reference
 */

goog.provide('ol.Object');
goog.provide('ol.ObjectEvent');
goog.provide('ol.ObjectEventType');

goog.require('goog.array');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.functions');
goog.require('goog.object');
goog.require('ol.Observable');

/**
 * @enum {string}
 */
ol.ObjectEventType = {
  /**
   * Triggered before a property is changed.
   * @event ol.ObjectEvent#beforepropertychange
   * @todo stability experimental
   */
  BEFOREPROPERTYCHANGE: 'beforepropertychange',
  /**
   * Triggered when a property is changed.
   * @event ol.ObjectEvent#propertychange
   * @todo stability experimental
   */
  PROPERTYCHANGE: 'propertychange'
};

/**
 * Object representing a property change event.
 *
 * @param {string} type The event type.
 * @param {string} key The property name.
 * @extends {goog.events.Event}
 * @implements {oli.ObjectEvent}
 * @constructor
 */
ol.ObjectEvent = function(type, key) {
  goog.base(this, type);

  /**
   * The name of the property whose value is changing.
   * @type {string}
   */
  this.key = key;

};
goog.inherits(ol.ObjectEvent, goog.events.Event);

/**
 * @constructor
 * @param {ol.Object} target
 * @param {string} key
 * @todo stability experimental
 */
ol.ObjectAccessor = function(target, key) {

  /**
   * @type {ol.Object}
   */
  this.target = target;

  /**
   * @type {string}
   */
  this.key = key;

  /**
   * @type {function(?): ?}
   */
  this.from = goog.functions.identity;

  /**
   * @type {function(?): ?}
   */
  this.to = goog.functions.identity;
};

/**
 * @param {function(?): ?} from A function that transforms the source value
 *     before it is set to the target.
 * @param {function(?): ?} to A function that transforms the target value
 *     before it is set to the source.
 */
ol.ObjectAccessor.prototype.transform = function(from, to) {
  this.from = from;
  this.to = to;

  this.target.notify(this.key);
};

/**
 * Base class implementing KVO (Key Value Observing).
 * @constructor
 * @extends {ol.Observable}
 * @param {Object.<string, *>=} opt_values Values.
 * @fires {@link ol.ObjectEvent} ol.ObjectEvent
 * @todo stability experimental
 */
ol.Object = function(opt_values) {
  goog.base(this);

  // Call goog.getUid to ensure that the order of objects' ids is the same as
  // the order in which they were created.  This also helps to ensure that
  // object properties are always added in the same order, which helps many
  // JavaScript engines generate faster code.
  goog.getUid(this);

  /**
   * @private
   * @type {Object.<string, *>}
   */
  this.values_ = {};

  /**
   * @private
   * @type {Object.<string, ol.ObjectAccessor>}
   */
  this.accessors_ = {};

  /**
   * Lookup of beforechange listener keys.
   * @type {Object.<string, goog.events.Key>}
   * @private
   */
  this.beforeChangeListeners_ = {};

  /**
   * @private
   * @type {Object.<string, goog.events.Key>}
   */
  this.listeners_ = {};

  if (goog.isDef(opt_values)) {
    this.setValues(opt_values);
  }
};
goog.inherits(ol.Object, ol.Observable);

/**
 * @private
 * @type {Object.<string, string>}
 */
ol.Object.changeEventTypeCache_ = {};

/**
 * @private
 * @type {Object.<string, string>}
 */
ol.Object.getterNameCache_ = {};

/**
 * @private
 * @type {Object.<string, string>}
 */
ol.Object.setterNameCache_ = {};

/**
 * @param {string} str String.
 * @return {string} Capitalized string.
 */
ol.Object.capitalize = function(str) {
  return str.substr(0, 1).toUpperCase() + str.substr(1);
};

/**
 * @param {string} key Key name.
 * @return {string} Change name.
 */
ol.Object.getChangeEventType = function(key) {
  return ol.Object.changeEventTypeCache_.hasOwnProperty(key) ?
      ol.Object.changeEventTypeCache_[key] :
      (ol.Object.changeEventTypeCache_[key] = 'change:' + key.toLowerCase());
};

/**
 * @param {string} key String.
 * @return {string} Getter name.
 */
ol.Object.getGetterName = function(key) {
  return ol.Object.getterNameCache_.hasOwnProperty(key) ?
      ol.Object.getterNameCache_[key] :
      (ol.Object.getterNameCache_[key] = 'get' + ol.Object.capitalize(key));
};

/**
 * @param {string} key String.
 * @return {string} Setter name.
 */
ol.Object.getSetterName = function(key) {
  return ol.Object.setterNameCache_.hasOwnProperty(key) ?
      ol.Object.setterNameCache_[key] :
      (ol.Object.setterNameCache_[key] = 'set' + ol.Object.capitalize(key));
};

/**
 * The bindTo method allows you to set up a two-way binding between a
 * `source` and `target` object. The method returns an
 * ol.ObjectAccessor with a transform method that lets you transform
 * values on the way from the source to the target and on the way back.
 *
 * For example, if you had two map views (sourceView and targetView)
 * and you wanted the target view to have double the resolution of the
 * source view, you could transform the resolution on the way to and
 * from the target with the following:
 *
 *     sourceView.bindTo('resolution', targetView)
 *       .transform(
 *         function(sourceResolution) {
 *           // from sourceView.resolution to targetView.resolution
 *           return 2 * sourceResolution;
 *         },
 *         function(targetResolution) {
 *           // from targetView.resolution to sourceView.resolution
 *           return targetResolution / 2;
 *         }
 *       );
 *
 * @param {string} key Key name.
 * @param {ol.Object} target Target.
 * @param {string=} opt_targetKey Target key.
 * @return {ol.ObjectAccessor}
 * @todo stability experimental
 */
ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
  var targetKey = opt_targetKey || key;
  this.unbind(key);

  // listen for change:targetkey events
  var eventType = ol.Object.getChangeEventType(targetKey);
  this.listeners_[key] = goog.events.listen(target, eventType,
      /**
       * @this {ol.Object}
       */
      function() {
        this.notifyInternal_(key);
      }, undefined, this);

  // listen for beforechange events and relay if key matches
  this.beforeChangeListeners_[key] = goog.events.listen(target,
      ol.ObjectEventType.BEFOREPROPERTYCHANGE,
      this.createBeforeChangeListener_(key, targetKey),
      undefined, this);

  var accessor = new ol.ObjectAccessor(target, targetKey);
  this.accessors_[key] = accessor;
  this.notifyInternal_(key);
  return accessor;
};

/**
 * Create a listener for beforechange events on a target object.  This listener
 * will relay events on this object if the event key matches the provided target
 * key.
 * @param {string} key The key on this object whose value will be changing.
 * @param {string} targetKey The key on the target object.
 * @return {function(this: ol.Object, ol.ObjectEvent)} Listener.
 * @private
 */
ol.Object.prototype.createBeforeChangeListener_ = function(key, targetKey) {
  /**
   * Conditionally relay beforechange events if event key matches target key.
   * @param {ol.ObjectEvent} event The beforechange event from the target.
   * @this {ol.Object}
   */
  return function(event) {
    if (event.key === targetKey) {
      this.dispatchEvent(
          new ol.ObjectEvent(ol.ObjectEventType.BEFOREPROPERTYCHANGE, key));
    }
  };
};

/**
 * Gets a value.
 * @param {string} key Key name.
 * @return {*} Value.
 * @todo stability experimental
 */
ol.Object.prototype.get = function(key) {
  var value;
  var accessors = this.accessors_;
  if (accessors.hasOwnProperty(key)) {
    var accessor = accessors[key];
    var target = accessor.target;
    var targetKey = accessor.key;
    var getterName = ol.Object.getGetterName(targetKey);
    var getter = /** @type {function(): *|undefined} */
        (goog.object.get(target, getterName));
    if (goog.isDef(getter)) {
      value = getter.call(target);
    } else {
      value = target.get(targetKey);
    }
    value = accessor.to(value);
  } else if (this.values_.hasOwnProperty(key)) {
    value = this.values_[key];
  }
  return value;
};

/**
 * Get a list of object property names.
 * @return {Array.<string>} List of property names.
 */
ol.Object.prototype.getKeys = function() {
  var accessors = this.accessors_;
  var keysObject;
  if (goog.object.isEmpty(this.values_)) {
    if (goog.object.isEmpty(accessors)) {
      return [];
    } else {
      keysObject = accessors;
    }
  } else {
    if (goog.object.isEmpty(accessors)) {
      keysObject = this.values_;
    } else {
      keysObject = {};
      var key;
      for (key in this.values_) {
        keysObject[key] = true;
      }
      for (key in accessors) {
        keysObject[key] = true;
      }
    }
  }
  return goog.object.getKeys(keysObject);
};

/**
 * Get an object of all property names and values.
 * @return {Object.<string, *>} Object.
 * @todo stability experimental
 */
ol.Object.prototype.getProperties = function() {
  var properties = {};
  var key;
  for (key in this.values_) {
    properties[key] = this.values_[key];
  }
  for (key in this.accessors_) {
    properties[key] = this.get(key);
  }
  return properties;
};

/**
 * Notify all observers of a change on this property. This notifies both
 * objects that are bound to the object's property as well as the object
 * that it is bound to.
 * @param {string} key Key name.
 * @todo stability experimental
 */
ol.Object.prototype.notify = function(key) {
  var accessors = this.accessors_;
  if (accessors.hasOwnProperty(key)) {
    var accessor = accessors[key];
    var target = accessor.target;
    var targetKey = accessor.key;
    target.notify(targetKey);
  } else {
    this.notifyInternal_(key);
  }
};

/**
 * @param {string} key Key name.
 * @private
 */
ol.Object.prototype.notifyInternal_ = function(key) {
  var eventType = ol.Object.getChangeEventType(key);
  this.dispatchEvent(eventType);
  this.dispatchEvent(
      new ol.ObjectEvent(ol.ObjectEventType.PROPERTYCHANGE, key));
};

/**
 * Sets a value.
 * @param {string} key Key name.
 * @param {*} value Value.
 * @todo stability experimental
 */
ol.Object.prototype.set = function(key, value) {
  this.dispatchEvent(
      new ol.ObjectEvent(ol.ObjectEventType.BEFOREPROPERTYCHANGE, key));
  var accessors = this.accessors_;
  if (accessors.hasOwnProperty(key)) {
    var accessor = accessors[key];
    var target = accessor.target;
    var targetKey = accessor.key;
    value = accessor.from(value);
    var setterName = ol.Object.getSetterName(targetKey);
    var setter = /** @type {function(*)|undefined} */
        (goog.object.get(target, setterName));
    if (goog.isDef(setter)) {
      setter.call(target, value);
    } else {
      target.set(targetKey, value);
    }
  } else {
    this.values_[key] = value;
    this.notifyInternal_(key);
  }
};

/**
 * Sets a collection of key-value pairs.
 * @param {Object.<string, *>} values Values.
 * @todo stability experimental
 */
ol.Object.prototype.setValues = function(values) {
  var key;
  for (key in values) {
    this.set(key, values[key]);
  }
};

/**
 * Removes a binding. Unbinding will set the unbound property to the current
 *     value. The object will not be notified, as the value has not changed.
 * @param {string} key Key name.
 * @todo stability experimental
 */
ol.Object.prototype.unbind = function(key) {
  var listeners = this.listeners_;
  var listener = listeners[key];
  if (listener) {
    delete listeners[key];
    goog.events.unlistenByKey(listener);
    var value = this.get(key);
    delete this.accessors_[key];
    this.values_[key] = value;
  }

  // unregister any beforechange listener
  var listenerKey = this.beforeChangeListeners_[key];
  if (listenerKey) {
    goog.events.unlistenByKey(listenerKey);
    delete this.beforeChangeListeners_[key];
  }
};

/**
 * Removes all bindings.
 * @todo stability experimental
 */
ol.Object.prototype.unbindAll = function() {
  for (var key in this.listeners_) {
    this.unbind(key);
  }
};
<|endoftext|>


<commit_before>var http = require("http");
var url = require("url");
var request = require('request');
var async = require('async');

var port = process.env['PORT'] || process.argv[2] || 8899;
var clientPort = process.env['CLIENT_PORT'] || process.argv[3] || 8888;

var clients = {};

http.createServer(function(req, res) {
  var uri = url.parse(req.url,true);
  var pathname = uri.pathname;
  var query = uri.query;
  if(/^\/?client-ping$/.test(pathname)){
    if(query.address){
      var ip = query.address;
    } else {
      var ip = getClientIp(req);
    }
    clients[ip] = new Date().getTime();
    res.writeHead(200, {"Content-Type":"application/json"});
    res.write(JSON.stringify({response : "client ip recognized : " + ip}));
    res.end();
  } else if(/^\/?skip$/.test(pathname)){
    var ips = Object.keys(clients);
    async.map(ips,function(client,done){
      var address = /:/.test(client) ? client : client + ":" + clientPort;
      console.log("dispatching skip request to: ",address);
      request({
        url : address,
        qs : query
      },function(err,res,body){
        try {
          var response = JSON.parse(body)
        } catch(e){
          var response = {error : "error parsing response : " + e.message}
        } finally {
          done(null,response);
        }
      })
    },function(err,responses){
      if(err){
        res.writeHead(500, {"Content-Type": "text/plain"});
        res.write("Error encountered:\n",err);
        res.end();
      } else {
        res.writeHead(200, {"Content-Type":"application/json"});
        var response = {};
        ips.forEach(function(ip,idx){
          response[ip] = responses[idx];
        })
        res.write(JSON.stringify({responses : response}));
        res.end();
      }
    })
  } else {
      res.writeHead(404, {"Content-Type": "text/plain"});
      res.write("404 Not Found\n");
      res.end();
  }
}).listen(parseInt(port, 10));

console.log("Skip server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

process.on('uncaughtException',function(err){
  console.error("ERROR: uncaught exception",err);
})

// snippet taken from http://catapulty.tumblr.com/post/8303749793/heroku-and-node-js-how-to-get-the-client-ip-address
function getClientIp(req) {
  var ipAddress;
  // The request may be forwarded from local web server.
  var forwardedIpsStr = req.headers['x-forwarded-for'];
  if (forwardedIpsStr) {
    // 'x-forwarded-for' header may return multiple IP addresses in
    // the format: "client IP, proxy 1 IP, proxy 2 IP" so take the
    // the first one
    var forwardedIps = forwardedIpsStr.split(',');
    ipAddress = forwardedIps[0];
  }
  if (!ipAddress) {
    // If request was not forwarded
    ipAddress = req.connection.remoteAddress;
  }
  return ipAddress;
};

var reaper = setInterval(function(){
  Object.keys(clients).forEach(function(client){
    if(new Date().getTime() - clients[client] > 30000){
      // remove old clients
      delete clients[client]
    }
  })
},5000)<commit_msg>make skip work<commit_after>var http = require("http");
var url = require("url");
var request = require('request');
var async = require('async');

var port = process.env['PORT'] || process.argv[2] || 8899;

var clients = {};

http.createServer(function(req, res) {
  var uri = url.parse(req.url,true);
  var pathname = uri.pathname;
  var query = uri.query;
  if(/^\/?client-ping$/.test(pathname)){
    if(query.address){
      var ip = query.address;
    } else {
      var ip = getClientIp(req);
    }
    clients[ip] = new Date().getTime();
    res.writeHead(200, {"Content-Type":"application/json"});
    res.write(JSON.stringify({response : "client ip recognized : " + ip}));
    res.end();
  } else if(/^\/?skip$/.test(pathname)){
    var ips = Object.keys(clients);
    async.map(ips,function(client,done){
      console.log("dispatching skip request to: ",client);
      request({
        url : client + '/' + pathname,
        qs : query
      },function(err,res,body){
        try {
          var response = JSON.parse(body)
        } catch(e){
          var response = {error : "error parsing response : " + e.message}
        } finally {
          done(null,response);
        }
      })
    },function(err,responses){
      if(err){
        res.writeHead(500, {"Content-Type": "text/plain"});
        res.write("Error encountered:\n",err);
        res.end();
      } else {
        res.writeHead(200, {"Content-Type":"application/json"});
        var response = {};
        ips.forEach(function(ip,idx){
          response[ip] = responses[idx];
        })
        res.write(JSON.stringify({responses : response}));
        res.end();
      }
    })
  } else {
      res.writeHead(404, {"Content-Type": "text/plain"});
      res.write("404 Not Found\n");
      res.end();
  }
}).listen(parseInt(port, 10));

console.log("Skip server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

process.on('uncaughtException',function(err){
  console.error("ERROR: uncaught exception",err);
})

// snippet taken from http://catapulty.tumblr.com/post/8303749793/heroku-and-node-js-how-to-get-the-client-ip-address
function getClientIp(req) {
  var ipAddress;
  // The request may be forwarded from local web server.
  var forwardedIpsStr = req.headers['x-forwarded-for'];
  if (forwardedIpsStr) {
    // 'x-forwarded-for' header may return multiple IP addresses in
    // the format: "client IP, proxy 1 IP, proxy 2 IP" so take the
    // the first one
    var forwardedIps = forwardedIpsStr.split(',');
    ipAddress = forwardedIps[0];
  }
  if (!ipAddress) {
    // If request was not forwarded
    ipAddress = req.connection.remoteAddress;
  }
  return ipAddress;
};

var reaper = setInterval(function(){
  Object.keys(clients).forEach(function(client){
    if(new Date().getTime() - clients[client] > 30000){
      // remove old clients
      delete clients[client]
    }
  })
},5000)<|endoftext|>