<commit_before>/**
 * jsonalyzer Python code linting
 *
 * @copyright 2015, Ajax.org B.V.
 * @author Lennart Kats <lennart add c9.io>
 */
define(function(require, exports, module) {

var baseHandler = require("plugins/c9.ide.language/base_handler");
var workerUtil = require("plugins/c9.ide.language/worker_util");

var handler = module.exports = Object.create(baseHandler);
var pythonVersion = "python2";
var pythonPath = "";
var launchCommand;
var ssh;
var PYLINT_OPTIONS = [
    "-d", "all",
    "-e", "E",
    "-e", "F",
    "-e", "W0101", // Unreachable code
    "-e", "W0109", // Duplicate key in dictionary
    "-e", "W0199", // Assert called on a 2-tuple. Did you mean \'assert x,y\'?
    "-e", "W0612", // Unused variable
    "-e", "W0602", // Used global without assignment
    "-r", "n",
    "--msg-template={line}:{column}:\\ [{msg_id}]\\ {msg}"
];

handler.handlesLanguage = function(language) {
    return language === "python";
};

handler.init = function(callback) {
    var emitter = handler.getEmitter();
    emitter.on("set_python_config", function(e) {
        pythonVersion = e.pythonVersion;
        pythonPath = e.pythonPath;
    });
    emitter.on("set_python_scripts", function(e) {
        launchCommand = e.launchCommand;
        ssh = e.ssh;
    });
    callback();
};

handler.analyze = function(docValue, fullAst, options, callback) {
    // Get a copy of pylint. For ssh workspaces we need to use a helper script;
    // in other cases we have the "pylint2" and "pylint3" commands.
    var commands = ssh
        ? ["-c", launchCommand, "--", pythonVersion, "$ENV/bin/pylint"]
        : ["-c", pythonVersion === "python2" ? "pylint2" : "pylint3"];
    commands[commands.length - 1] += " " + PYLINT_OPTIONS.join(" ") + " $FILE";

    var hasStarImports = /from\s+[^\s]+\s+import\s+\*/.test(docValue);
    var markers = [];
    workerUtil.execAnalysis(
        "bash",
        {
            mode: "tempfile",
            args: commands,
            maxCallInterval: 1200,
            env: {
                PYTHONPATH: pythonPath
            }
        },
        function(err, stdout, stderr) {
            if (err && err.code !== 2) return callback(err);

            stdout.split("\n").forEach(function(line) {
                var marker = parseLine(line, hasStarImports);
                marker && markers.push(marker);
            });

            callback(null, markers);
        }
    );
};

function parseLine(line, hasStarImports) {
    var match = line.match(/(\d+):(\d+): \[([^\]]+)\] (.*)/);
    if (!match)
        return;
    var row = match[1];
    var column = match[2];
    var code = match[3];
    var message = match[4];
    var level = getLevel(code);

    if (/print statement used/.test(message))
        return;
    if (hasStarImports && /undefined variable/i.test(message)) {
        level = "info";
        message += "?";
    }

    return {
        pos: {
            sl: parseInt(row, 10) - 1,
            sc: parseInt(column, 10)
        },
        message: message,
        code: code,
        level: level
    };
}

function getLevel(code) {
    if (code[0] === "E" || code[0] === "F")
        return "error";
    if (code === "W0612") // unused variable
        return "info";
    if (code === "W0602") // global without assignment
        return "info";
    return "warning";
}

});<commit_msg>Reduce lint delay<commit_after>/**
 * jsonalyzer Python code linting
 *
 * @copyright 2015, Ajax.org B.V.
 * @author Lennart Kats <lennart add c9.io>
 */
define(function(require, exports, module) {

var baseHandler = require("plugins/c9.ide.language/base_handler");
var workerUtil = require("plugins/c9.ide.language/worker_util");

var handler = module.exports = Object.create(baseHandler);
var pythonVersion = "python2";
var pythonPath = "";
var launchCommand;
var ssh;
var PYLINT_OPTIONS = [
    "-d", "all",
    "-e", "E",
    "-e", "F",
    "-e", "W0101", // Unreachable code
    "-e", "W0109", // Duplicate key in dictionary
    "-e", "W0199", // Assert called on a 2-tuple. Did you mean \'assert x,y\'?
    "-e", "W0612", // Unused variable
    "-e", "W0602", // Used global without assignment
    "-r", "n",
    "--msg-template={line}:{column}:\\ [{msg_id}]\\ {msg}"
];

handler.handlesLanguage = function(language) {
    return language === "python";
};

handler.init = function(callback) {
    var emitter = handler.getEmitter();
    emitter.on("set_python_config", function(e) {
        pythonVersion = e.pythonVersion;
        pythonPath = e.pythonPath;
    });
    emitter.on("set_python_scripts", function(e) {
        launchCommand = e.launchCommand;
        ssh = e.ssh;
    });
    callback();
};

handler.analyze = function(docValue, fullAst, options, callback) {
    // Get a copy of pylint. For ssh workspaces we need to use a helper script;
    // in other cases we have the "pylint2" and "pylint3" commands.
    var commands = ssh
        ? ["-c", launchCommand, "--", pythonVersion, "$ENV/bin/pylint"]
        : ["-c", pythonVersion === "python2" ? "pylint2" : "pylint3"];
    commands[commands.length - 1] += " " + PYLINT_OPTIONS.join(" ") + " $FILE";

    var hasStarImports = /from\s+[^\s]+\s+import\s+\*/.test(docValue);
    var markers = [];
    workerUtil.execAnalysis(
        "bash",
        {
            mode: "tempfile",
            args: commands,
            maxCallInterval: 800,
            env: {
                PYTHONPATH: pythonPath
            }
        },
        function(err, stdout, stderr) {
            if (err && err.code !== 2) return callback(err);

            stdout.split("\n").forEach(function(line) {
                var marker = parseLine(line, hasStarImports);
                marker && markers.push(marker);
            });

            callback(null, markers);
        }
    );
};

function parseLine(line, hasStarImports) {
    var match = line.match(/(\d+):(\d+): \[([^\]]+)\] (.*)/);
    if (!match)
        return;
    var row = match[1];
    var column = match[2];
    var code = match[3];
    var message = match[4];
    var level = getLevel(code);

    if (/print statement used/.test(message))
        return;
    if (hasStarImports && /undefined variable/i.test(message)) {
        level = "info";
        message += "?";
    }

    return {
        pos: {
            sl: parseInt(row, 10) - 1,
            sc: parseInt(column, 10)
        },
        message: message,
        code: code,
        level: level
    };
}

function getLevel(code) {
    if (code[0] === "E" || code[0] === "F")
        return "error";
    if (code === "W0612") // unused variable
        return "info";
    if (code === "W0602") // global without assignment
        return "info";
    return "warning";
}

});<|endoftext|>


<commit_before>var apiMarkAsRead=function(id) {
  $.getJSON("api/"+id+"/read", function(data) {
     $("#description"+id).html(data.description);
     $('img').addClass('img-responsive');
  });

}

var apiStar=function(id) {
  $.getJSON("api/"+id+"/star", function(data) {

  })
}

var apiUnstar=function(id) {
  $.getJSON("api/"+id+"/unstar", function() {

  })
}

var starArticle = function(id) {
  apiStar(id);
  $('#star'+id).addClass('btn-warning');
}

var unstarArticle = function(id) {
  apiUnstar(id);
  $('#star'+id).removeClass('btn-warning');
}

var readArticle = function(id) {
  $('#body'+id).show();
  $('#hide'+id).show();
  $('#expand'+id).hide();
  $('#summary'+id).hide();
  apiMarkAsRead(id);
}

var hideArticle = function(id) {
  $('#body'+id).hide();
  $('#hide'+id).hide();
  $('#summary'+id).show();
  $('#expand'+id).show();
}

var removeArticle = function(id) {
  $('#'+id).hide();
  apiMarkAsRead(id);
}

var readAll = function() {
  $('.showable').show(1);
}

var addFeed = function() {
  var data = {url : $('#url').val()}
  $.getJSON("api/feed/add", data,  function(retval) {
    $('#addfeedback').html("
"+retval.message+"
");
  })
  return false;
}

var addTag = function(feedid) {

  var data = {tag : $('#tagName').val()}
  $.getJSON("api/feed/"+feedid+"/tag/add", data,  function(retval) {
    location.reload();
  })
  return false;
}

var removeTag = function(feedid, tag) {
  var data = {tag : tag}
  $.getJSON("api/feed/"+feedid+"/tag/remove", data,  function(retval) {
    location.reload();
  })
  return false;
}

var removeFeed = function(feedid) {
  $.getJSON("api/feed/"+feedid+"/remove",  function(retval) {
    location.href="#!/feeds";
  })
  return false;
}

var showAll = function() {
  $('.article').each(function(index){
    readArticle(this.id);
  });
}

var doBrowse = function() {
  $("#target").html("
...
");
  $.ajax({
    url: "api/html/next",
    cache: false
  }).done(function( html ) {
    $("#target").html(html);
    $('#browsemodecount').html(latest_unread);
    $(".nbc").collapse('hide')   ;
    $('img').addClass('img-responsive');
  });
}

var doUnread = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/unread",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide')
  });
}

var doRead = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/readed",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide');
  });
}

var doStarred = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/starred",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide')
  });
}

var doFeeds = function() {
  $("#target").html("
...
");
  $.ajax({
    url: "api/html/feeds",
    cache: false
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide')
  });
}

var doSingleFeed = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/feed",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
  });
}

var doSearch = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/search",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
  });
};

var doAddForm = function() {
  $("#target").html("
...
");
  $.ajax({
    url: "api/html/add",
    cache: false
  }).done(function( html ) {
    $("#target").html(html);
  });
}

var searchRedirect = function() {
  var url = "#!/search?keywords=" + escape($('#keywords').val());
  window.location = url;
  return false;
}

var latest_unread = '0';

$(document).ready(function () {
  $(".nbc").collapse('hide');
  var socket = io.connect(window.location.hostname);
  socket.on('news', function (data) {
    latest_unread = data.unread;
    $('#browsecount').html(data.unread);
    $('#unreadcount').html(data.unread);
    $('#readcount').html(data.read);
    $('#starredcount').html(data.starred);
    if($('#browsemodecount')) {
      $('#browsemodecount').html(data.unread);
    }
  });

  socket.on('connect', function () {
    $('#connected').html(" ");
  });
  socket.on('disconnect', function () {
    $('#connected').html(" ");
  });

});

Path.map("#!/browse").to(function(){
  doBrowse();
});

Path.map("#!/unread").to(function(){
  doUnread();
});

Path.map("#!/read").to(function(){
  doRead();
});

Path.map("#!/starred").to(function(){
  doStarred();
});

Path.map("#!/feeds").to(function(){
  doFeeds();
});

Path.map("#!/search").to(function(){
  doSearch();
});

Path.map("#!/add").to(function(){
  doAddForm();
});

Path.map("#!/feed").to(function(){
  doSingleFeed();
});

Path.root("#!/browse");

Path.listen();

<commit_msg>attempt to make iframe videos responsive<commit_after>var apiMarkAsRead=function(id) {
  $.getJSON("api/"+id+"/read", function(data) {
     $("#description"+id).html(data.description);
     $('img').addClass('img-responsive');
     $('img').addClass('iframe-responsive');
  });

}

var apiStar=function(id) {
  $.getJSON("api/"+id+"/star", function(data) {

  })
}

var apiUnstar=function(id) {
  $.getJSON("api/"+id+"/unstar", function() {

  })
}

var starArticle = function(id) {
  apiStar(id);
  $('#star'+id).addClass('btn-warning');
}

var unstarArticle = function(id) {
  apiUnstar(id);
  $('#star'+id).removeClass('btn-warning');
}

var readArticle = function(id) {
  $('#body'+id).show();
  $('#hide'+id).show();
  $('#expand'+id).hide();
  $('#summary'+id).hide();
  apiMarkAsRead(id);
}

var hideArticle = function(id) {
  $('#body'+id).hide();
  $('#hide'+id).hide();
  $('#summary'+id).show();
  $('#expand'+id).show();
}

var removeArticle = function(id) {
  $('#'+id).hide();
  apiMarkAsRead(id);
}

var readAll = function() {
  $('.showable').show(1);
}

var addFeed = function() {
  var data = {url : $('#url').val()}
  $.getJSON("api/feed/add", data,  function(retval) {
    $('#addfeedback').html("
"+retval.message+"
");
  })
  return false;
}

var addTag = function(feedid) {

  var data = {tag : $('#tagName').val()}
  $.getJSON("api/feed/"+feedid+"/tag/add", data,  function(retval) {
    location.reload();
  })
  return false;
}

var removeTag = function(feedid, tag) {
  var data = {tag : tag}
  $.getJSON("api/feed/"+feedid+"/tag/remove", data,  function(retval) {
    location.reload();
  })
  return false;
}

var removeFeed = function(feedid) {
  $.getJSON("api/feed/"+feedid+"/remove",  function(retval) {
    location.href="#!/feeds";
  })
  return false;
}

var showAll = function() {
  $('.article').each(function(index){
    readArticle(this.id);
  });
}

var doBrowse = function() {
  $("#target").html("
...
");
  $.ajax({
    url: "api/html/next",
    cache: false
  }).done(function( html ) {
    $("#target").html(html);
    $('#browsemodecount').html(latest_unread);
    $(".nbc").collapse('hide')   ;
    $('img').addClass('img-responsive');
    $('iframe').addClass('iframe-responsive');
  });
}

var doUnread = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/unread",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide')
  });
}

var doRead = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/readed",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide');
  });
}

var doStarred = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/starred",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide')
  });
}

var doFeeds = function() {
  $("#target").html("
...
");
  $.ajax({
    url: "api/html/feeds",
    cache: false
  }).done(function( html ) {
    $("#target").html(html);
    $(".nbc").collapse('hide')
  });
}

var doSingleFeed = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/feed",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
  });
}

var doSearch = function() {
  $("#target").html("
...
");
  var bits = window.location.href.split("?");
  var data = "";
  if(bits.length > 0) {
    data = bits[1];
  }
  $.ajax({
    url: "api/html/search",
    cache: false,
    data: data
  }).done(function( html ) {
    $("#target").html(html);
  });
};

var doAddForm = function() {
  $("#target").html("
...
");
  $.ajax({
    url: "api/html/add",
    cache: false
  }).done(function( html ) {
    $("#target").html(html);
  });
}

var searchRedirect = function() {
  var url = "#!/search?keywords=" + escape($('#keywords').val());
  window.location = url;
  return false;
}

var latest_unread = '0';

$(document).ready(function () {
  $(".nbc").collapse('hide');
  var socket = io.connect(window.location.hostname);
  socket.on('news', function (data) {
    latest_unread = data.unread;
    $('#browsecount').html(data.unread);
    $('#unreadcount').html(data.unread);
    $('#readcount').html(data.read);
    $('#starredcount').html(data.starred);
    if($('#browsemodecount')) {
      $('#browsemodecount').html(data.unread);
    }
  });

  socket.on('connect', function () {
    $('#connected').html(" ");
  });
  socket.on('disconnect', function () {
    $('#connected').html(" ");
  });

});

Path.map("#!/browse").to(function(){
  doBrowse();
});

Path.map("#!/unread").to(function(){
  doUnread();
});

Path.map("#!/read").to(function(){
  doRead();
});

Path.map("#!/starred").to(function(){
  doStarred();
});

Path.map("#!/feeds").to(function(){
  doFeeds();
});

Path.map("#!/search").to(function(){
  doSearch();
});

Path.map("#!/add").to(function(){
  doAddForm();
});

Path.map("#!/feed").to(function(){
  doSingleFeed();
});

Path.root("#!/browse");

Path.listen();

<|endoftext|>


<commit_before>window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

// in-browser tweaking stuff
// window.xxx = 100;
// window.yyy = 100;
// $(window).keypress(function(e) {
//   switch (e.which) {
//     case 113: xxx -= 0.5; break; //q
//     case 81: xxx -= 10; break; //Q
//     case 101: xxx += 0.5; break; //e
//     case 69: xxx += 10; break; //E
//     case 97: yyy -= 0.5; break; //a
//     case 65: yyy -= 10; break; //A
//     case 100: yyy += 0.5; break; //d
//     case 68: yyy += 10; break; //D
//   }
//   console.log('xxx=', xxx, 'yyy=', yyy);
// });

// fire on load, after items are all rendered and positioned
$(window).load(function() {
  var panels = [];
  var text = []
  var cacheOffsets = function() {
    panels = $('.shadow-div').get().map(function(item) {
      return {
        $el: $(item),
        offsetX: $(item).offset().left + $(item).width()/2,
        offsetY: $(item).offset().top + $(item).height()/2,
      }
    });
    texts = $('.shadow-text').get().map(function(item) {
      return {
        $el: $(item),
        offsetX: $(item).offset().left + $(item).width()/2,
        offsetY: $(item).offset().top + $(item).height()/2,
      }
    });
  }
  // grab items, cache offsets up front to avoid reflow costs when calculating shadows
  cacheOffsets();

  // store screen size for normalization
  var screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  var screenH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

  $(window).resize(function() {
    // recache offsets when window resizes
    cacheOffsets();
    // refresh screen size as well
    screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    screenH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
  });

  // EXPERIMENTAL: split up texts into words so they each have their own shadow
  // var originalTexts = $('.shadow-text');
  // var texts = [];
  // for (var i = originalTexts.length - 1; i >= 0; i--) {
  //   var contents = originalTexts.eq(i).contents()
  //   for (var j = contents.length - 1; j >= 0; j--) {
  //     var content = contents[j];
  //     if (content.nodeName == '#text') {
  //       var newHTML = content.nodeValue.replace(/[^\s]+/g, "$&");
  //       $(newHTML).insertBefore(content);
  //       content.remove();
  //     } else {
  //       content.innerHTML = content.innerHTML.replace(/[^\s]+/g, "$&");
  //     }
  //   };
  //   texts = texts.concat(originalTexts.eq(i).find('span').get().map(function(item) {
  //     return {
  //       $el: $(item),
  //       offsetX: $(item).offset().left + $(item).width()/2,
  //       offsetY: $(item).offset().top + $(item).height()/2,
  //     }
  //   }));
  // };

  // on-demand mouse position
  var mouseX = -1;
  var mouseY = -1;
  var lastMouseTime = 0;
  $('html').mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
    lastMouseTime = new Date().getTime();
  });
  // gyro for mobile
  var gyroB = null;
  var gyroG = null;
  var lastGyroTime = 0;
  if (gyro.hasFeature('devicemotion')) {
    gyro.frequency = 100;
    gyro.startTracking(function(orientation) {
      if (gyroB !== orientation.beta || gyroG !== orientation.gamma) {
        gyroB = orientation.beta || gyroB;
        gyroG = orientation.gamma || gyroG;
        lastGyroTime = new Date().getTime();
      }
    });
  }

  // constantly recalculate shadows as mouse moves around screen
  var magnitude = function(vector) { return Math.sqrt(vector.x*vector.x + vector.y*vector.y); };
  var magnitude2 = function(vector) { return vector.x*vector.x + vector.y*vector.y; };
  var getNormalizedShadowVector = function(item) {
    if (lastGyroTime > lastMouseTime) {
      return { x: gyroG / 90, y: gyroB / 90 };
    } else {
      return { x: (item.offsetX - mouseX)/(screenW/2), y: (item.offsetY - mouseY)/(screenH/2) };
    }
  };
  var recalculateShadows = function() {
    requestAnimFrame(recalculateShadows);
    //console.log(mouseX, mouseY, gyroB, gyroG);
    if (lastMouseTime || lastGyroTime) { // don't do mouse shadowing until there's a mouse/gyro event
      for (var i = 0; i < panels.length; i++) {
        var panel = panels[i];
        var shadowVector = getNormalizedShadowVector(panel);
        var shadowX = shadowVector.x / 0.2;
        var shadowY = shadowVector.y / 0.3;
        var shadowBlur = Math.max(10 - magnitude(shadowVector) * 8, 1);
        var shadowSize = magnitude(shadowVector) / 0.74;
        var shadowAlpha = Math.max(0.75 - magnitude2(shadowVector), 0.5);
        panel.$el.css('box-shadow', shadowX + 'px ' + shadowY + 'px ' + shadowBlur + 'px ' + shadowSize + 'px rgba(0,0,0,' + shadowAlpha + ')')
        panel.$el.css('-webkit-box-shadow', shadowX + 'px ' + shadowY + 'px ' + shadowBlur + 'px ' + shadowSize + 'px rgba(0,0,0,' + shadowAlpha + ')')
      };
      for (var i = 0; i < texts.length; i++) {
        var text = texts[i]
        var shadowVector = getNormalizedShadowVector(text);
        var shadowX = Math.sign(shadowVector.x) * Math.sqrt(Math.abs(shadowVector.x)) * 3.5;
        var shadowY = Math.sign(shadowVector.y) * Math.sqrt(Math.abs(shadowVector.y)) * 2.5;
        var shadowBlur = Math.max(4 - magnitude(shadowVector) / 0.2, 0);
        var shadowAlpha = Math.max(0.75 - magnitude2(shadowVector), 0.5);
        text.$el.css('text-shadow', shadowX + 'px ' + shadowY + 'px ' + shadowBlur + 'px rgba(0,0,0,' + shadowAlpha + ')')
      };
    }
  }
  requestAnimFrame(recalculateShadows);
})<commit_msg>Better comments<commit_after>window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

//// in-browser tweaking stuff
// window.xxx = 100;
// window.yyy = 100;
// $(window).keypress(function(e) {
//   switch (e.which) {
//     case 113: xxx -= 0.5; break; //q
//     case 81: xxx -= 10; break; //Q
//     case 101: xxx += 0.5; break; //e
//     case 69: xxx += 10; break; //E
//     case 97: yyy -= 0.5; break; //a
//     case 65: yyy -= 10; break; //A
//     case 100: yyy += 0.5; break; //d
//     case 68: yyy += 10; break; //D
//   }
//   console.log('xxx=', xxx, 'yyy=', yyy);
// });

// fire on load, after items are all rendered and positioned
$(window).load(function() {
  var panels = [];
  var text = []
  var cacheOffsets = function() {
    panels = $('.shadow-div').get().map(function(item) {
      return {
        $el: $(item),
        offsetX: $(item).offset().left + $(item).width()/2,
        offsetY: $(item).offset().top + $(item).height()/2,
      }
    });
    texts = $('.shadow-text').get().map(function(item) {
      return {
        $el: $(item),
        offsetX: $(item).offset().left + $(item).width()/2,
        offsetY: $(item).offset().top + $(item).height()/2,
      }
    });
  }
  // cache offsets up front to avoid reflow costs when calculating shadows
  cacheOffsets();

  // store screen size for shadow calculations
  var screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  var screenH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

  $(window).resize(function() {
    // recache offsets when window resizes
    cacheOffsets();
    // refresh screen size as well
    screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    screenH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
  });

  //// EXPERIMENTAL: split up texts into words so they each have their own shadow
  // var originalTexts = $('.shadow-text');
  // var texts = [];
  // for (var i = originalTexts.length - 1; i >= 0; i--) {
  //   var contents = originalTexts.eq(i).contents()
  //   for (var j = contents.length - 1; j >= 0; j--) {
  //     var content = contents[j];
  //     if (content.nodeName == '#text') {
  //       var newHTML = content.nodeValue.replace(/[^\s]+/g, "$&");
  //       $(newHTML).insertBefore(content);
  //       content.remove();
  //     } else {
  //       content.innerHTML = content.innerHTML.replace(/[^\s]+/g, "$&");
  //     }
  //   };
  //   texts = texts.concat(originalTexts.eq(i).find('span').get().map(function(item) {
  //     return {
  //       $el: $(item),
  //       offsetX: $(item).offset().left + $(item).width()/2,
  //       offsetY: $(item).offset().top + $(item).height()/2,
  //     }
  //   }));
  // };

  // on-demand mouse position
  var mouseX = -1;
  var mouseY = -1;
  var lastMouseTime = 0;
  $('html').mousemove(function(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
    lastMouseTime = new Date().getTime();
  });
  // gyro for mobile
  var gyroB = null;
  var gyroG = null;
  var lastGyroTime = 0;
  if (gyro.hasFeature('devicemotion')) {
    gyro.frequency = 100;
    gyro.startTracking(function(orientation) {
      if (gyroB !== orientation.beta || gyroG !== orientation.gamma) {
        gyroB = orientation.beta || gyroB;
        gyroG = orientation.gamma || gyroG;
        lastGyroTime = new Date().getTime();
      }
    });
  }

  // constantly recalculate shadows as mouse moves around screen
  var magnitude = function(vector) { return Math.sqrt(vector.x*vector.x + vector.y*vector.y); };
  var magnitude2 = function(vector) { return vector.x*vector.x + vector.y*vector.y; };
  var getNormalizedShadowVector = function(item) { // normalizes gyro/mouse to [-1, 1]
    if (lastGyroTime > lastMouseTime) {
      return { x: gyroG / 90, y: gyroB / 90 };
    } else {
      return { x: (item.offsetX - mouseX)/(screenW/2), y: (item.offsetY - mouseY)/(screenH/2) };
    }
  };
  var recalculateShadows = function() {
    requestAnimFrame(recalculateShadows);
    //console.log(mouseX, mouseY, gyroB, gyroG);
    if (lastMouseTime || lastGyroTime) { // don't do mouse shadowing until there's a mouse/gyro event
      for (var i = 0; i < panels.length; i++) {
        var panel = panels[i];
        var shadowVector = getNormalizedShadowVector(panel);
        var shadowX = shadowVector.x / 0.2;
        var shadowY = shadowVector.y / 0.3;
        var shadowBlur = Math.max(10 - magnitude(shadowVector) * 8, 1);
        var shadowSize = magnitude(shadowVector) / 0.74;
        var shadowAlpha = Math.max(0.75 - magnitude2(shadowVector), 0.5);
        panel.$el.css('box-shadow', shadowX + 'px ' + shadowY + 'px ' + shadowBlur + 'px ' + shadowSize + 'px rgba(0,0,0,' + shadowAlpha + ')')
        panel.$el.css('-webkit-box-shadow', shadowX + 'px ' + shadowY + 'px ' + shadowBlur + 'px ' + shadowSize + 'px rgba(0,0,0,' + shadowAlpha + ')')
      };
      for (var i = 0; i < texts.length; i++) {
        var text = texts[i]
        var shadowVector = getNormalizedShadowVector(text);
        var shadowX = Math.sign(shadowVector.x) * Math.sqrt(Math.abs(shadowVector.x)) * 3.5;
        var shadowY = Math.sign(shadowVector.y) * Math.sqrt(Math.abs(shadowVector.y)) * 2.5;
        var shadowBlur = Math.max(4 - magnitude(shadowVector) / 0.2, 0);
        var shadowAlpha = Math.max(0.75 - magnitude2(shadowVector), 0.5);
        text.$el.css('text-shadow', shadowX + 'px ' + shadowY + 'px ' + shadowBlur + 'px rgba(0,0,0,' + shadowAlpha + ')')
      };
    }
  }
  requestAnimFrame(recalculateShadows);
})<|endoftext|>


<commit_before>var vows = require('vows'),
assert = require('assert'),
portfinder = require('portfinder'),

data = require('../test-utils/data'),
heads = JSON.parse(data.event.json),
macros = require('../test-utils/macros'),
cov = require('../test-utils/coverage'),

Server = cov.require('../../lib/esl/server').Server;

vows.describe('esl.Server').addBatch({
    'Should': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port }, function() {
                    t.callback(null, server);
                });
            });
        },
        'have the correct exports': function(s) {
            //is function
            assert.isFunction(Server);

            //is instance
            assert.isTrue(s instanceof Server);

            //private functions
            assert.isFunction(s._onConnection);
            assert.isFunction(s._onListening);
            assert.isFunction(s._generateId);

            //var defaults
            assert.isObject(s.connections);
            assert.isNumber(s.port);
            assert.strictEqual(s.host, '127.0.0.1');
        },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open'),
            'connection::ready': macros.testServerConnectionEvent('connection::ready', data.event.channelData),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        },
        'use': {
            topic: macros.getEchoServerSocket(function(o) {
                var t = this;

                o.eslServer = new Server({ server: o.server }, function() {
                    t.callback(null, o);
                });
            }),
            'custom server instance': function(o) {
                assert.equal(o.server, o.eslServer.server);
            }
        }
    }
}).export(module);<commit_msg>Adding myevents to test suite. The idea is that connection::open will parse extra info coming from the socket, right after event subscription<commit_after>var vows = require('vows'),
assert = require('assert'),
portfinder = require('portfinder'),

data = require('../test-utils/data'),
heads = JSON.parse(data.event.json),
macros = require('../test-utils/macros'),
cov = require('../test-utils/coverage'),

Server = cov.require('../../lib/esl/server').Server;

vows.describe('esl.Server').addBatch({
    'Should': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port }, function() {
                    t.callback(null, server);
                });
            });
        },
        'have the correct exports': function(s) {
            //is function
            assert.isFunction(Server);

            //is instance
            assert.isTrue(s instanceof Server);

            //private functions
            assert.isFunction(s._onConnection);
            assert.isFunction(s._onListening);
            assert.isFunction(s._generateId);

            //var defaults
            assert.isObject(s.connections);
            assert.isNumber(s.port);
            assert.strictEqual(s.host, '127.0.0.1');
        },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open'),
            'connection::ready': macros.testServerConnectionEvent('connection::ready', data.event.channelData),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        },
        'use': {
            topic: macros.getEchoServerSocket(function(o) {
                var t = this;

                o.eslServer = new Server({ server: o.server }, function() {
                    t.callback(null, o);
                });
            }),
            'custom server instance': function(o) {
                assert.equal(o.server, o.eslServer.server);
            }
        }
    },
    'Bind events': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port , myevents: true}, function() {
                    t.callback(null, server);
                });
            });
        },
        'exist': {
        topic: function(s) { return s;},
        'bind_events': function(s) {
            assert.equal(s.bind_events, true);
        }
    },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open', data.event.cmdReply('ok')),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        },
    }
}).export(module);

<|endoftext|>


<commit_before>var tab_bar = (function () {

var exports = {};

function make_tab(title, hash, data, extra_class) {
    return {active: "inactive",
            cls: extra_class || "",
            title: title,
            hash: hash,
            data: data};
}

function make_tab_data() {
    var tabs = [];
    var filter = narrow.filter();

    // Root breadcrumb item: Either Home or All Messages
    if (filter !== undefined &&
        ((filter.has_operator("stream") &&
          !stream_data.in_home_view(filter.operands("stream")[0])) ||
         filter.has_operand("in", "all"))) {
        tabs.push(make_tab("All Messages", "#narrow/in/all", undefined, "root"));
    } else {
        tabs.push(make_tab("Home", "#", "home", "root"));
    }

    if (narrow.active() && narrow.operators().length > 0) {
        var stream, ops = narrow.operators();
        var hash = hashchange.operators_to_hash(ops);
        // Second breadcrumb item
        var hashed = hashchange.operators_to_hash(ops.slice(0, 1));
        if (filter.has_operator("stream")) {
            stream = filter.operands("stream")[0];
            tabs.push(make_tab(stream, hashed, stream, 'stream'));
        } else if (filter.has_operator("pm-with") ||
                   filter.has_operand("is", "private")) {

            tabs.push(make_tab("Private Messages", '#narrow/is/private',
                                undefined, 'private_message '));

            if (filter.has_operator("pm-with")) {
                var emails = filter.operands("pm-with")[0].split(',');
                var names = _.map(emails, function (email) {
                    if (! people_dict.has(email)) {
                        return email;
                    }
                    return people_dict.get(email).full_name;
                });

                tabs.push(make_tab(names.join(', '), hashed));
            }

        } else if (filter.has_operand("is", "starred")) {
            tabs.push(make_tab("Starred", hashed));
        } else if (filter.has_operator("near")) {
            tabs.push(make_tab("Near " + filter.operands("near")[0], hashed));
        } else if (filter.has_operator("id")) {
            tabs.push(make_tab("ID " + filter.operands("id")[0], hashed));
        } else if (filter.has_operand("is", "mentioned")) {
            tabs.push(make_tab("Mentions", hashed));
        } else if (filter.has_operator("sender")) {
            var sender = filter.operands("sender")[0];
            if (people_dict.has(sender)) {
                sender = people_dict.get(sender).full_name;
            }
            tabs.push(make_tab("Sent by " + sender, hashed));
        }  else if (filter.has_operator("search")) {
            // Search is not a clickable link, since we don't have
            // a search narrow
            tabs.push(make_tab("Search results", false));
        }

        // Third breadcrumb item for stream-subject naarrows
        if (filter.has_operator("stream") &&
            filter.has_operator("topic")) {
            stream = filter.operands("stream")[0];
            var subject = filter.operands("topic")[0];
            hashed = hashchange.operators_to_hash(ops.slice(0, 2));

            tabs.push(make_tab(subject, hashed, null));
        }
    }

    // Last tab is not a link
    tabs[tabs.length - 1].hash = false;

    return tabs;
}

exports.colorize_tab_bar = function () {
    // The stream tab, if it exists, should be the same color as that stream's chosen color
    // Likewise, the border and outline should be the stream color as well
    var stream_tab = $('#tab_list .stream');
    if (stream_tab.length > 0) {
        var stream_name = stream_tab.data('name');
        if (stream_name === undefined) {
            return;
        }
        stream_name = stream_name.toString();

        var stream_color = stream_data.get_color(stream_name);

        if (!stream_tab.hasClass('active')) {
            stream_tab.css('border-color', stream_color);
        }

        $('#tab_list li.active').css('border-color', stream_color);
    }
};

function build_tab_bar() {
    var tabs = make_tab_data();

    // Insert the narrow spacer between each tab
    if (tabs.length > 1) {
        var idx = -1;
        while (Math.abs(idx) < tabs.length) {
            tabs.splice(idx, 0, {cls: "narrow_spacer", icon: true});
            idx -= 2;
        }
    }

    var tab_bar = $("#tab_bar");
    tab_bar.empty();

    tabs[tabs.length - 1].active = "active";
    var rendered =  templates.render('tab_bar', {tabs: tabs});

    tab_bar.append(rendered);
    exports.colorize_tab_bar();
    tab_bar.removeClass('notdisplayed');
}

$(function () {
    $(document).on('narrow_activated.zulip', function (event) {
        build_tab_bar();
    });
    $(document).on('narrow_deactivated.zulip', function (event) {
        build_tab_bar();
    });

    build_tab_bar();
});

return exports;

}());
<commit_msg>Improve tab bar for embedded narrowed widget.<commit_after>var tab_bar = (function () {

var exports = {};

function make_tab(title, hash, data, extra_class) {
    return {active: "inactive",
            cls: extra_class || "",
            title: title,
            hash: hash,
            data: data};
}

function make_tab_data() {
    var tabs = [];
    var filter = narrow.filter();

    // Root breadcrumb item: Either Home or All Messages
    if (filter !== undefined &&
        ((filter.has_operator("stream") &&
          !stream_data.in_home_view(filter.operands("stream")[0])) ||
         filter.has_operand("in", "all"))) {
        tabs.push(make_tab("All Messages", "#narrow/in/all", undefined, "root"));
    } else if (page_params.narrow !== undefined) {
        tabs.push(make_tab("Stream " + page_params.narrow_stream,
                           hashchange.operators_to_hash(page_params.narrow[0]),
                           page_params.narrow_stream, 'stream'));
    } else {
        tabs.push(make_tab("Home", "#", "home", "root"));
    }

    if (narrow.active() && narrow.operators().length > 0) {
        var stream, ops = narrow.operators();
        var hash = hashchange.operators_to_hash(ops);
        // Second breadcrumb item
        var hashed = hashchange.operators_to_hash(ops.slice(0, 1));
        if (filter.has_operator("stream")) {
            stream = filter.operands("stream")[0];
            tabs.push(make_tab(stream, hashed, stream, 'stream'));
        } else if (filter.has_operator("pm-with") ||
                   filter.has_operand("is", "private")) {

            tabs.push(make_tab("Private Messages", '#narrow/is/private',
                                undefined, 'private_message '));

            if (filter.has_operator("pm-with")) {
                var emails = filter.operands("pm-with")[0].split(',');
                var names = _.map(emails, function (email) {
                    if (! people_dict.has(email)) {
                        return email;
                    }
                    return people_dict.get(email).full_name;
                });

                tabs.push(make_tab(names.join(', '), hashed));
            }

        } else if (filter.has_operand("is", "starred")) {
            tabs.push(make_tab("Starred", hashed));
        } else if (filter.has_operator("near")) {
            tabs.push(make_tab("Near " + filter.operands("near")[0], hashed));
        } else if (filter.has_operator("id")) {
            tabs.push(make_tab("ID " + filter.operands("id")[0], hashed));
        } else if (filter.has_operand("is", "mentioned")) {
            tabs.push(make_tab("Mentions", hashed));
        } else if (filter.has_operator("sender")) {
            var sender = filter.operands("sender")[0];
            if (people_dict.has(sender)) {
                sender = people_dict.get(sender).full_name;
            }
            tabs.push(make_tab("Sent by " + sender, hashed));
        }  else if (filter.has_operator("search")) {
            // Search is not a clickable link, since we don't have
            // a search narrow
            tabs.push(make_tab("Search results", false));
        }

        // Third breadcrumb item for stream-subject naarrows
        if (filter.has_operator("stream") &&
            filter.has_operator("topic")) {
            stream = filter.operands("stream")[0];
            var subject = filter.operands("topic")[0];
            hashed = hashchange.operators_to_hash(ops.slice(0, 2));

            tabs.push(make_tab(subject, hashed, null));
        }
    }

    // Last tab is not a link
    tabs[tabs.length - 1].hash = false;

    return tabs;
}

exports.colorize_tab_bar = function () {
    // The stream tab, if it exists, should be the same color as that stream's chosen color
    // Likewise, the border and outline should be the stream color as well
    var stream_tab = $('#tab_list .stream');
    if (stream_tab.length > 0) {
        var stream_name = stream_tab.data('name');
        if (stream_name === undefined) {
            return;
        }
        stream_name = stream_name.toString();

        var stream_color = stream_data.get_color(stream_name);

        if (!stream_tab.hasClass('active')) {
            stream_tab.css('border-color', stream_color);
        }

        $('#tab_list li.active').css('border-color', stream_color);
    }
};

function build_tab_bar() {
    var tabs = make_tab_data();

    // Insert the narrow spacer between each tab
    if (tabs.length > 1) {
        var idx = -1;
        while (Math.abs(idx) < tabs.length) {
            tabs.splice(idx, 0, {cls: "narrow_spacer", icon: true});
            idx -= 2;
        }
    }

    var tab_bar = $("#tab_bar");
    tab_bar.empty();

    tabs[tabs.length - 1].active = "active";
    var rendered =  templates.render('tab_bar', {tabs: tabs});

    tab_bar.append(rendered);
    exports.colorize_tab_bar();
    tab_bar.removeClass('notdisplayed');
}

$(function () {
    $(document).on('narrow_activated.zulip', function (event) {
        build_tab_bar();
    });
    $(document).on('narrow_deactivated.zulip', function (event) {
        build_tab_bar();
    });

    build_tab_bar();
});

return exports;

}());
<|endoftext|>


<commit_before>// The Grid component allows an element to be located
//  on a grid of tiles
Crafty.c('Grid', {
  init: function() {
    this.attr({
      w: Game.map_grid.tile.width,
      h: Game.map_grid.tile.height
    })
  },

  // Locate this entity at the given position on the grid
  at: function(x, y) {
    if (x === undefined && y === undefined) {
      return { x: this.x/Game.map_grid.tile.width, y: this.y/Game.map_grid.tile.height }
    } else {
      this.attr({ x: x * Game.map_grid.tile.width, y: y * Game.map_grid.tile.height });
      return this;
    }
  }
});

Crafty.c('Log', {
  _logElement: null,

  init: function() {
    this._logElement = document.getElementById('log');
  },

  log: function(message) {
    this._logElement.value += "\n";
    this._logElement.value += message;
    console.log(message);
  },

  clearLog: function() {
    this._logElement.value = "";
  }

});

// An "Actor" is an entity that is drawn in 2D on canvas
//  via our logical coordinate grid
Crafty.c('Actor', {
  init: function() {
    this.requires('2D, Canvas, Grid');
  },
});

// A Wall stops motion and cannot be down by the player
Crafty.c('Wall', {
  init: function() {
    this.requires('Actor, Color, Solid')
      .color('rgb(255, 116, 2)'); //FF6402
  },
});

// A Tree stops motion and can be cut down by the player
Crafty.c('Tree', {
  init: function() {
    this.requires('Actor, platoTree, Solid');
  },

  fell: function() {
    this.destroy();
    Crafty.trigger('TreeFelled', this);
  }

});

// A combatant has a number of points which is decremented upon suffering damage.
// When the point count decrements to zero, the combatant dies
Crafty.c("Combatant", {
  _points: 0,
  _maximumPoints: 0,

  points: function (inPoints) {
    if (!inPoints) return this._points;
    this._points = inPoints;
    this._maximumPoints = Math.max(this._points, this._maximumPoints);
    this.trigger("Change");
    return this;
  },

  maximumPoints: function () {
    return this._maximumPoints;
  },

  gainPoints: function (inPoints) {
    console.log(this.name() + " gainPoints " + inPoints);
    this._points = this._points + inPoints;
    this._maximumPoints = Math.max(this._points, this._maximumPoints);
    this.trigger("Change");
  },

  sufferDamage: function (inDamagePoints) {
    console.log(this.name() + " suffer damage " + inDamagePoints);
    this._points = this._points - inDamagePoints;
    this.trigger("Change");
    if (this._points <= 0) {
      this.trigger("Died");
    }
  }
});

// A Monster causes all kinds of trouble
Crafty.c('Monster', {
  _name: 'Monster',
  _hitVerb: 'hit',
  _killedVerb: 'killed',
  _worth: 0,

  init: function() {
    this.requires('Actor, Combatant, Fourway, Solid, Collision, Log')
      .onHit('PlayerCharacter', this.attackPlayerCharacter)
      .bind('Died', this.monsterDied)
      .onHit('Solid', this.stopMovement);

    // set up points for combat
    this.points(1 + ((5 * Math.random()) | 0));
  },

  name: function(inName) {
    if (!inName) return this._name;
    this._name = inName;
  },

  worth: function (inWorth) {
    if (!inWorth) return this._worth;
    this._worth = inWorth;
    this.trigger("Change");
    return this;
  },

  hitVerb: function (inHitVerb) {
    if (!inHitVerb) return this._hitVerb;
    this._hitVerb = inHitVerb;
    this.trigger("Change");
    return this;
  },

  killedVerb: function (inKilledVerb) {
    if (!inKilledVerb) return this._killedVerb;
    this._killedVerb = inKilledVerb;
    this.trigger("Change");
    return this;
  },

  computeDamage: function() {
    var damage = 3 * Math.random() + (this.points() / 8) + (this.worth() / 4);
    return Math.round(damage);
  },

  monsterDied: function() {
    this.destroy();
    Crafty.trigger('MonsterKilled', this);
  },

  attackPlayerCharacter: function(data) {
    this.log('The ' + this.name() + ' attacks you');
    data[0].obj.sufferDamage(this.computeDamage());
  },

  // Stops the movement
  stopMovement: function() {
    this._speed = 0;
    if (this._movement) {
      this.x -= this._movement.x;
      this.y -= this._movement.y;
    }
  },

});

function createMonster(inSprite, inName, inHitVerb, inKilledVerb, inPoints, inWorth) {
  Crafty.c(inName, {
    init: function() {
      this.requires('Monster, ' + inSprite);
      this.name(inName);
      this.hitVerb(inHitVerb);
      this.killedVerb(inKilledVerb);
      this.points(inPoints);
      this.worth(inWorth);
    },
  });
}

var monstersTable = [
  { sprite: 'platoCrab', name: 'Gnat', hitVerb: 'hit', killedVerb: 'smashed', points: 2, worth: 2 },
  { sprite: 'platoHoplite', name: 'Nomad', hitVerb: 'slashed', killedVerb: 'bested', points: 10, worth: 2 },
  { sprite: 'platoAlien', name: 'Spider', hitVerb: 'poked', killedVerb: 'squished', points: 13, worth: 4 },
  { sprite: 'platoChavin', name: 'Moth', hitVerb: 'swatted at', killedVerb: 'flattened', points: 18, worth: 5 },
  { sprite: 'platoTree2', name: 'Tree of Death', hitVerb: 'hacked at', killedVerb: 'felled', points: 20, worth: 3 },
  { sprite: 'platoChavin', name: 'Snark', hitVerb: 'thwarted', killedVerb: 'disposed of', points: 28, worth: 9 },
  { sprite: 'platoChavin', name: 'Bolotomus', hitVerb: 'stomped', killedVerb: 'dispatched', points: 28, worth: 9 },
  { sprite: 'platoChavin', name: 'Nimbus', hitVerb: 'hit', killedVerb: 'killed', points: 36, worth: 11 },
];

for (var index = 0; index < monstersTable.length; index++) {
  var monsterData = monstersTable[index];

  console.log("initializing monster " + monsterData['name']);
  createMonster(monsterData['sprite'], monsterData['name'], monsterData['hitVerb'], monsterData['killedVerb'], monsterData['points'], monsterData['worth']);
}

// A Chest has either gold or treasure items inside it
// When the player visits the Chest, it is destroyed.
Crafty.c('Chest', {
  init: function() {
    this._gold = (1 + 50 * Math.random()) | 0;
    this.requires('Actor, platoChest, Solid');
  },

  collect: function() {
    this.destroy();
    Crafty.trigger('ChestVisited', this);
  }
});

// A castle is a tile on the grid where the player is safe from attack and
// where the Player can purchase Arrows and other goodies.
Crafty.c('Castle', {
  init: function() {
    this.requires('Actor, platoCastle, Solid');
  },
});

// This is the player-controlled character
Crafty.c('PlayerCharacter', {
  init: function() {
    // from the turbo pascal: "exp := 24.0; arrows := 20; gold := 10; which_swd := 0;"

    this._gold = 10;
    this._arrows = 10;
    this._inUseItems = [];
    this._unusedItems = [];

    // creates a player that moves four ways and stops on collision with solid actors
    this.requires('Actor, Fourway, platoPlayer, Solid, Combatant, Collision, Log')
      .bind('KeyDown', function(e) {
          this.clearLog();
          this._movement = {x: 0, y: 0};

          if(e.key == Crafty.keys['A']) {
            this._movement.x = -Game.map_grid.tile.width;
          } else if (e.key == Crafty.keys['Q']) {
            this._movement.x = -Game.map_grid.tile.width;
            this._movement.y = -Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['W']) {
            this._movement.y = -Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['E']) {
            this._movement.x = Game.map_grid.tile.width;
            this._movement.y = -Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['D']) {
            this._movement.x = Game.map_grid.tile.width;
          } else if (e.key == Crafty.keys['C']) {
            this._movement.x = Game.map_grid.tile.width;
            this._movement.y = Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['X']) {
            this._movement.y = Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['Z']) {
            this._movement.x = -Game.map_grid.tile.width;
            this._movement.y = Game.map_grid.tile.height;
          }

          this.x += this._movement.x;
          this.y += this._movement.y;
          // console.log("player " + this.x + ", " + this.y);
          this.trigger('Moved');
      })
      .onHit('Tree', this.fellTree)
      .onHit('Monster', this.attackMonster)
      .onHit('Chest', this.visitChest)
      .onHit('Castle', this.visitCastle)
      .onHit('Solid', this.stopMovement)
      .bind('MonsterKilled', function (monster) {
        this.gainPoints(monster.worth());
        this.log("You have " + monster.killedVerb() + " the " + monster.name());
      })
      .bind('Died', this.playerDied)
      .bind('Change', function() {
        document.getElementById('points').innerHTML = this.points() + "/" + this.maximumPoints();
      })
      .bind('Moved', this.attractMonsters);

    this.points(24);
  },

  name: function() {
    return 'Player';
  },

  computeDamage: function() {
    if (this.points() > 1) {
      var swordStrength = 1;
      var damage = (swordStrength * this.points() / (2.0 * Math.log(this.points()))) + (swordStrength + 3) * Math.random();
      return Math.round(damage);
    } else {
      return 1;
    }
  },

  fellTree: function(data) {
    this.log("You felled the tree");
    tree = data[0].obj;
    tree.fell();
    this.gainPoints(1);
  },

  playerDied: function() {
    this.destroy();
    Crafty.trigger('PlayerKilled', this);
    this.log("You died");
  },

  attractMonsters: function() {
    var player = this;

    Crafty('Monster').each(function (index) {
      var distance = Math.abs(player.at().y - this.at().y) + Math.abs(player.at().x - this.at().x);

      if (distance > 6) {
        // console.log("distant monster did not seek player");
      } else {
        console.log("monster seeks player");
        var goNorth = (player.at().y < this.at().y);
        var goSouth = (player.at().y > this.at().y);
        var goEast = (player.at().x > this.at().x);
        var goWest = (player.at().x < this.at().x);

        this._movement = {x: 0, y: 0};

        if (goNorth) { this._movement.y = -Game.map_grid.tile.height ; }
        else if (goSouth) { this._movement.y = Game.map_grid.tile.height; }

        if (goEast) { this._movement.x = Game.map_grid.tile.width; }
        else if (goWest) { this._movement.x = -Game.map_grid.tile.width; }

        if ((player.at().x == this.at().x) && (player.at().y == this.at().y)) {
          this.attackPlayerCharacter([{obj: player}])
        }

        this.x += this._movement.x;
        this.y += this._movement.y;
        this.trigger('Moved');
      }
    });
  },

  // Attacks the monster
  attackMonster: function(data) {
    monster = data[0].obj
    this.log("You " + monster.hitVerb() + " the " + monster.name());
    monster.sufferDamage(this.computeDamage());
  },

  // Stops the movement
  stopMovement: function() {
    this._speed = 0;
    if (this._movement) {
      this.x -= this._movement.x;
      this.y -= this._movement.y;
    }
    console.log("STOP MOVEMENT player " + this.x + ", " + this.y);
  },

  // Respond to this player visiting a chest
  visitChest: function(data) {
    chest = data[0].obj;
    this._gold = this._gold + chest._gold;
    this.log("You opened the chest and got " + chest._gold + " gold pieces");
    document.getElementById('gold').innerHTML = this._gold;
    chest.collect();
    this.log(Crafty('Chest').length + " chests left");
  },

  // Respond to this player visiting a chest
  visitCastle: function(data) {
    this.log("You visit the castle");
  }

});

<commit_msg>show points for combat logs<commit_after>// The Grid component allows an element to be located
//  on a grid of tiles
Crafty.c('Grid', {
  init: function() {
    this.attr({
      w: Game.map_grid.tile.width,
      h: Game.map_grid.tile.height
    })
  },

  // Locate this entity at the given position on the grid
  at: function(x, y) {
    if (x === undefined && y === undefined) {
      return { x: this.x/Game.map_grid.tile.width, y: this.y/Game.map_grid.tile.height }
    } else {
      this.attr({ x: x * Game.map_grid.tile.width, y: y * Game.map_grid.tile.height });
      return this;
    }
  }
});

Crafty.c('Log', {
  _logElement: null,

  init: function() {
    this._logElement = document.getElementById('log');
  },

  log: function(message) {
    this._logElement.value += "\n";
    this._logElement.value += message;
    console.log(message);
  },

  clearLog: function() {
    this._logElement.value = "";
  }

});

// An "Actor" is an entity that is drawn in 2D on canvas
//  via our logical coordinate grid
Crafty.c('Actor', {
  init: function() {
    this.requires('2D, Canvas, Grid');
  },
});

// A Wall stops motion and cannot be down by the player
Crafty.c('Wall', {
  init: function() {
    this.requires('Actor, Color, Solid')
      .color('rgb(255, 116, 2)'); //FF6402
  },
});

// A Tree stops motion and can be cut down by the player
Crafty.c('Tree', {
  init: function() {
    this.requires('Actor, platoTree, Solid');
  },

  fell: function() {
    this.destroy();
    Crafty.trigger('TreeFelled', this);
  }

});

// A combatant has a number of points which is decremented upon suffering damage.
// When the point count decrements to zero, the combatant dies
Crafty.c("Combatant", {
  _points: 0,
  _maximumPoints: 0,

  points: function (inPoints) {
    if (!inPoints) return this._points;
    this._points = inPoints;
    this._maximumPoints = Math.max(this._points, this._maximumPoints);
    this.trigger("Change");
    return this;
  },

  maximumPoints: function () {
    return this._maximumPoints;
  },

  gainPoints: function (inPoints) {
    console.log(this.name() + " gainPoints " + inPoints);
    this._points = this._points + inPoints;
    this._maximumPoints = Math.max(this._points, this._maximumPoints);
    this.trigger("Change");
  },

  sufferDamage: function (inDamagePoints) {
    console.log(this.name() + " suffer damage " + inDamagePoints);
    this._points = this._points - inDamagePoints;
    this.trigger("Change");
    if (this._points <= 0) {
      this.trigger("Died");
    }
  }
});

// A Monster causes all kinds of trouble
Crafty.c('Monster', {
  _name: 'Monster',
  _hitVerb: 'hit',
  _killedVerb: 'killed',
  _worth: 0,

  init: function() {
    this.requires('Actor, Combatant, Fourway, Solid, Collision, Log')
      .onHit('PlayerCharacter', this.attackPlayerCharacter)
      .bind('Died', this.monsterDied)
      .onHit('Solid', this.stopMovement);

    // set up points for combat
    this.points(1 + ((5 * Math.random()) | 0));
  },

  name: function(inName) {
    if (!inName) return this._name;
    this._name = inName;
  },

  worth: function (inWorth) {
    if (!inWorth) return this._worth;
    this._worth = inWorth;
    this.trigger("Change");
    return this;
  },

  hitVerb: function (inHitVerb) {
    if (!inHitVerb) return this._hitVerb;
    this._hitVerb = inHitVerb;
    this.trigger("Change");
    return this;
  },

  killedVerb: function (inKilledVerb) {
    if (!inKilledVerb) return this._killedVerb;
    this._killedVerb = inKilledVerb;
    this.trigger("Change");
    return this;
  },

  computeDamage: function() {
    var damage = 3 * Math.random() + (this.points() / 8) + (this.worth() / 4);
    return Math.round(damage);
  },

  monsterDied: function() {
    this.destroy();
    console.log(Crafty('Monster').length + " monsters left");
    Crafty.trigger('MonsterKilled', this);
  },

  attackPlayerCharacter: function(data) {
    var damage = this.computeDamage();
    this.log('The ' + this.name() + ' hit you for ' + damage + ' points');
    data[0].obj.sufferDamage(this.computeDamage());
  },

  // Stops the movement
  stopMovement: function() {
    this._speed = 0;
    if (this._movement) {
      this.x -= this._movement.x;
      this.y -= this._movement.y;
    }
  },

});

function createMonster(inSprite, inName, inHitVerb, inKilledVerb, inPoints, inWorth) {
  Crafty.c(inName, {
    init: function() {
      this.requires('Monster, ' + inSprite);
      this.name(inName);
      this.hitVerb(inHitVerb);
      this.killedVerb(inKilledVerb);
      this.points(inPoints);
      this.worth(inWorth);
    },
  });
}

var monstersTable = [
  { sprite: 'platoCrab', name: 'Gnat', hitVerb: 'hit', killedVerb: 'smashed', points: 2, worth: 2 },
  { sprite: 'platoHoplite', name: 'Nomad', hitVerb: 'slashed', killedVerb: 'bested', points: 10, worth: 2 },
  { sprite: 'platoAlien', name: 'Spider', hitVerb: 'poked', killedVerb: 'squished', points: 13, worth: 4 },
  { sprite: 'platoChavin', name: 'Moth', hitVerb: 'swatted at', killedVerb: 'flattened', points: 18, worth: 5 },
  { sprite: 'platoTree2', name: 'Tree of Death', hitVerb: 'hacked at', killedVerb: 'felled', points: 20, worth: 3 },
  { sprite: 'platoChavin', name: 'Snark', hitVerb: 'thwarted', killedVerb: 'disposed of', points: 28, worth: 9 },
  { sprite: 'platoChavin', name: 'Bolotomus', hitVerb: 'stomped', killedVerb: 'dispatched', points: 28, worth: 9 },
  { sprite: 'platoChavin', name: 'Nimbus', hitVerb: 'hit', killedVerb: 'killed', points: 36, worth: 11 },
];

for (var index = 0; index < monstersTable.length; index++) {
  var monsterData = monstersTable[index];

  console.log("initializing monster " + monsterData['name']);
  createMonster(monsterData['sprite'], monsterData['name'], monsterData['hitVerb'], monsterData['killedVerb'], monsterData['points'], monsterData['worth']);
}

// A Chest has either gold or treasure items inside it
// When the player visits the Chest, it is destroyed.
Crafty.c('Chest', {
  init: function() {
    this._gold = (1 + 50 * Math.random()) | 0;
    this.requires('Actor, platoChest, Solid');
  },

  collect: function() {
    this.destroy();
    Crafty.trigger('ChestVisited', this);
  }
});

// A castle is a tile on the grid where the player is safe from attack and
// where the Player can purchase Arrows and other goodies.
Crafty.c('Castle', {
  init: function() {
    this.requires('Actor, platoCastle, Solid');
  },
});

// This is the player-controlled character
Crafty.c('PlayerCharacter', {
  init: function() {
    // from the turbo pascal: "exp := 24.0; arrows := 20; gold := 10; which_swd := 0;"

    this._gold = 10;
    this._arrows = 10;
    this._inUseItems = [];
    this._unusedItems = [];

    // creates a player that moves four ways and stops on collision with solid actors
    this.requires('Actor, Fourway, platoPlayer, Solid, Combatant, Collision, Log')
      .bind('KeyDown', function(e) {
          this.clearLog();
          this._movement = {x: 0, y: 0};

          if(e.key == Crafty.keys['A']) {
            this._movement.x = -Game.map_grid.tile.width;
          } else if (e.key == Crafty.keys['Q']) {
            this._movement.x = -Game.map_grid.tile.width;
            this._movement.y = -Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['W']) {
            this._movement.y = -Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['E']) {
            this._movement.x = Game.map_grid.tile.width;
            this._movement.y = -Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['D']) {
            this._movement.x = Game.map_grid.tile.width;
          } else if (e.key == Crafty.keys['C']) {
            this._movement.x = Game.map_grid.tile.width;
            this._movement.y = Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['X']) {
            this._movement.y = Game.map_grid.tile.height;
          } else if (e.key == Crafty.keys['Z']) {
            this._movement.x = -Game.map_grid.tile.width;
            this._movement.y = Game.map_grid.tile.height;
          }

          this.x += this._movement.x;
          this.y += this._movement.y;
          // console.log("player " + this.x + ", " + this.y);
          this.trigger('Moved');
      })
      .onHit('Tree', this.fellTree)
      .onHit('Monster', this.attackMonster)
      .onHit('Chest', this.visitChest)
      .onHit('Castle', this.visitCastle)
      .onHit('Solid', this.stopMovement)
      .bind('MonsterKilled', function (monster) {
        this.gainPoints(monster.worth());
        this.log("You have " + monster.killedVerb() + " the " + monster.name());
      })
      .bind('Died', this.playerDied)
      .bind('Change', function() {
        document.getElementById('points').innerHTML = this.points() + "/" + this.maximumPoints();
      })
      .bind('Moved', this.attractMonsters);

    this.points(24);
  },

  name: function() {
    return 'Player';
  },

  computeDamage: function() {
    if (this.points() > 1) {
      var swordStrength = 1;
      var damage = (swordStrength * this.points() / (2.0 * Math.log(this.points()))) + (swordStrength + 3) * Math.random();
      return Math.round(damage);
    } else {
      return 1;
    }
  },

  fellTree: function(data) {
    this.log("You felled the tree");
    tree = data[0].obj;
    tree.fell();
    this.gainPoints(1);
  },

  playerDied: function() {
    this.destroy();
    Crafty.trigger('PlayerKilled', this);
    this.log("You died");
  },

  attractMonsters: function() {
    var player = this;

    Crafty('Monster').each(function (index) {
      var distance = Math.abs(player.at().y - this.at().y) + Math.abs(player.at().x - this.at().x);

      if (distance > 6) {
        // console.log("distant monster did not seek player");
      } else {
        console.log("monster seeks player");
        var goNorth = (player.at().y < this.at().y);
        var goSouth = (player.at().y > this.at().y);
        var goEast = (player.at().x > this.at().x);
        var goWest = (player.at().x < this.at().x);

        this._movement = {x: 0, y: 0};

        if (goNorth) { this._movement.y = -Game.map_grid.tile.height ; }
        else if (goSouth) { this._movement.y = Game.map_grid.tile.height; }

        if (goEast) { this._movement.x = Game.map_grid.tile.width; }
        else if (goWest) { this._movement.x = -Game.map_grid.tile.width; }

        if ((player.at().x == this.at().x) && (player.at().y == this.at().y)) {
          this.attackPlayerCharacter([{obj: player}])
        }

        this.x += this._movement.x;
        this.y += this._movement.y;
        this.trigger('Moved');
      }
    });
  },

  // Attacks the monster
  attackMonster: function(data) {
    var monster = data[0].obj;
    var damage = this.computeDamage();
    this.log("You " + monster.hitVerb() + " the " + monster.name() + " for " + damage + " points");
    monster.sufferDamage(damage);
  },

  // Stops the movement
  stopMovement: function() {
    this._speed = 0;
    if (this._movement) {
      this.x -= this._movement.x;
      this.y -= this._movement.y;
    }
    console.log("STOP MOVEMENT player " + this.x + ", " + this.y);
  },

  // Respond to this player visiting a chest
  visitChest: function(data) {
    chest = data[0].obj;
    this._gold = this._gold + chest._gold;
    this.log("You opened the chest and got " + chest._gold + " gold pieces");
    document.getElementById('gold').innerHTML = this._gold;
    chest.collect();
    this.log(Crafty('Chest').length + " chests left");
  },

  // Respond to this player visiting a chest
  visitCastle: function(data) {
    this.log("You visit the castle");
  }

});

<|endoftext|>


<commit_before>jQuery(document).ready(function() {

    $.extend( $.ui.autocomplete.prototype, {

    	_renderItem: function( ul, item) {
        return $( "

" )
          .data( "item.autocomplete", item )
          .append( $( "" ).html( item.html || item.label ) )
          .appendTo( ul );
      }
    });

    var precooked = null;

    $.ajax( {
      url: "/search/precooked",
      dataType: "jsonp",
      jsonpCallback: "precookedf",
      cache: true,
      success: function(data) {
        precooked = data;
      }
    });

    //hide instructions
     $('#search_hint').hide();

    //search hint
    $('#main_autocomplete').blur(
      function(){
        $('#main_autocomplete').val("I'm looking for...");
        $('#search_hint').hide();
      }
    );

    $('#main_autocomplete').focus(
      function(){
        $('#main_autocomplete').val("");
        $('#search_hint').show();
      }
    );

    var filter_terms = function(search_term,data) {
       var highlight_term = function(string,term) {
              html_safe = html_escape(string);
              var terms = term.split(' ');
              for (var i in terms)  {
                var clean_term = html_escape(terms[i].replace(/^\s+|\s+$/g, ''));
                if (clean_term != "") {
                  var regex = new RegExp("("+clean_term+")","ig");
                  html_safe = html_safe.replace(regex,'$1');
                }
              }
              return html_safe;
        };

       return $.map(data, function(item) {
          return {
              label: html_escape(item.label),
              html:  highlight_term(item.label,search_term),
              url:   item.url + "?q=" + encodeURIComponent(item.label)
          };
       });
    }

    var html_escape = function( string) {
        return $('
').text(string).html();
    };

    $("#main_autocomplete").autocomplete({
        delay: 0,
        source: function( request, response ) {

          var search_site = function(search_term) {
            return {
                label: "search the site for "+html_escape(search_term),
                html:  "search the site for "+html_escape(search_term)+"",
                url:   "/search?q="+encodeURIComponent(search_term)
              };
          };

          var loading = function(term) {
            var data = [];
            if (precooked) {
              if (precooked[term]) {
                data = filter_terms(term,precooked[term]);
              }
            }
            data.push(search_site(request.term));
            response(data);
          };

          var ajax = function() {
            $.ajax({
              url: "/search/autocomplete",
              dataType: "jsonp",
              jsonpCallback: "search_received",
              data: { term: request.term },
              cache: true,
              success: function( data ) {
                var search_term = request.term;
                data = filter_terms(search_term,data.slice(0,10));
                data.push(search_site(search_term));
                response( data );
              }
            });
          };

          term = request.term;
          if (term.length == 0) {
            response([]);
          } else if (term.length == 1) {
            loading(term);
          } else {
            ajax();
          }

        },
        select: function(event, ui) {
          location.href = ui.item.url
        },
        open: function(event, ui){
          // console.debug(event);
        }
    });

});
<commit_msg>Fix javascript hightlighting regexp not to highlight the middle of words<commit_after>jQuery(document).ready(function() {

    $.extend( $.ui.autocomplete.prototype, {

    	_renderItem: function( ul, item) {
        return $( "

" )
          .data( "item.autocomplete", item )
          .append( $( "" ).html( item.html || item.label ) )
          .appendTo( ul );
      }
    });

    var precooked = null;

    $.ajax( {
      url: "/search/precooked",
      dataType: "jsonp",
      jsonpCallback: "precookedf",
      cache: true,
      success: function(data) {
        precooked = data;
      }
    });

    //hide instructions
     $('#search_hint').hide();

    //search hint
    $('#main_autocomplete').blur(
      function(){
        $('#main_autocomplete').val("I'm looking for...");
        $('#search_hint').hide();
      }
    );

    $('#main_autocomplete').focus(
      function(){
        $('#main_autocomplete').val("");
        $('#search_hint').show();
      }
    );

    var filter_terms = function(search_term,data) {
       var highlight_term = function(string,term) {
              html_safe = html_escape(string);
              var terms = term.split(' ');
              for (var i in terms)  {
                var clean_term = html_escape(terms[i].replace(/^\s+|\s+$/g, ''));
                if (clean_term != "") {
                  var regex = new RegExp("\\b("+clean_term+")","ig");
                  html_safe = html_safe.replace(regex,'$1');
                }
              }
              return html_safe;
        };

       return $.map(data, function(item) {
          return {
              label: html_escape(item.label),
              html:  highlight_term(item.label,search_term),
              url:   item.url + "?q=" + encodeURIComponent(item.label)
          };
       });
    }

    var html_escape = function( string) {
        return $('
').text(string).html();
    };

    $("#main_autocomplete").autocomplete({
        delay: 0,
        source: function( request, response ) {

          var search_site = function(search_term) {
            return {
                label: "search the site for "+html_escape(search_term),
                html:  "search the site for "+html_escape(search_term)+"",
                url:   "/search?q="+encodeURIComponent(search_term)
              };
          };

          var loading = function(term) {
            var data = [];
            if (precooked) {
              if (precooked[term]) {
                data = filter_terms(term,precooked[term]);
              }
            }
            data.push(search_site(request.term));
            response(data);
          };

          var ajax = function() {
            $.ajax({
              url: "/search/autocomplete",
              dataType: "jsonp",
              jsonpCallback: "search_received",
              data: { term: request.term },
              cache: true,
              success: function( data ) {
                var search_term = request.term;
                data = filter_terms(search_term,data.slice(0,10));
                data.push(search_site(search_term));
                response( data );
              }
            });
          };

          term = request.term;
          if (term.length == 0) {
            response([]);
          } else if (term.length == 1) {
            loading(term);
          } else {
            ajax();
          }

        },
        select: function(event, ui) {
          location.href = ui.item.url
        },
        open: function(event, ui){
          // console.debug(event);
        }
    });

});
<|endoftext|>


<commit_before>var vows = require('vows'),
assert = require('assert'),
portfinder = require('portfinder'),

data = require('../test-utils/data'),
heads = JSON.parse(data.event.json),
macros = require('../test-utils/macros'),
cov = require('../test-utils/coverage'),

Server = cov.require('../../lib/esl/server').Server;

vows.describe('esl.Server').addBatch({
    'Should': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port }, function() {
                    t.callback(null, server);
                });
            });
        },
        'have the correct exports': function(s) {
            //is function
            assert.isFunction(Server);

            //is instance
            assert.isTrue(s instanceof Server);

            //private functions
            assert.isFunction(s._onConnection);
            assert.isFunction(s._onListening);
            assert.isFunction(s._generateId);

            //var defaults
            assert.isObject(s.connections);
            assert.isNumber(s.port);
            assert.strictEqual(s.host, '127.0.0.1');
        },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open'),
            'connection::ready': macros.testServerConnectionEvent('connection::ready', data.event.channelData),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        },
        'use': {
            topic: macros.getEchoServerSocket(function(o) {
                var t = this;

                o.eslServer = new Server({ server: o.server }, function() {
                    t.callback(null, o);
                });
            }),
            'custom server instance': function(o) {
                assert.equal(o.server, o.eslServer.server);
            }
        }
    },
    'Bind events': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port , myevents: true}, function() {
                    t.callback(null, server);
                });
            });
        },
        'exist': {
        topic: function(s) { return s;},
            'bind_events': function(s) {
                assert.equal(s.bind_events, true);
            }
        },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open', data.event.cmdReply('ok')),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        }
    }
}).export(module);

<commit_msg>update test<commit_after>var vows = require('vows'),
assert = require('assert'),
portfinder = require('portfinder'),

data = require('../test-utils/data'),
heads = JSON.parse(data.event.json),
macros = require('../test-utils/macros'),
cov = require('../test-utils/coverage'),

Server = cov.require('../../lib/esl/server').Server;

vows.describe('esl.Server').addBatch({
    'Should': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port }, function() {
                    t.callback(null, server);
                });
            });
        },
        'have the correct exports': function(s) {
            //is function
            assert.isFunction(Server);

            //is instance
            assert.isTrue(s instanceof Server);

            //private functions
            assert.isFunction(s._onConnection);
            assert.isFunction(s._onListening);
            assert.isFunction(s._generateId);

            //var defaults
            assert.isObject(s.connections);
            assert.isNumber(s.port);
            assert.strictEqual(s.host, '127.0.0.1');
        },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open'),
            'connection::ready': macros.testServerConnectionEvent('connection::ready', data.event.channelData),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        },
        'use': {
            topic: macros.getEchoServerSocket(function(o) {
                var t = this;

                o.eslServer = new Server({ server: o.server }, function() {
                    t.callback(null, o);
                });
            }),
            'custom server instance': function(o) {
                assert.equal(o.server, o.eslServer.server);
            }
        }
    },
    'Bind events': {
        topic: function() {
            var t = this;
            portfinder.getPort(function(err, port) {
                if(err) throw err;

                var server = new Server({ port: port , myevents: true}, function() {
                    t.callback(null, server);
                });
            });
        },
        'exist': {
        topic: function(s) { return s;},
            'bindEvents': function(s) {
                assert.equal(s.bindEvents, true);
            }
        },
        'emit': {
            topic: function(s) { return s; },
            'connection::open': macros.testServerConnectionEvent('connection::open', data.event.cmdReply('ok')),
            'connection::close': macros.testServerConnectionEvent('connection::close')
        }
    }
}).export(module);

<|endoftext|>


<commit_before>import $ from "jquery";
import tippy, {delegate} from "tippy.js";

import render_left_sidebar_stream_setting_popover from "../templates/left_sidebar_stream_setting_popover.hbs";

import * as popovers from "./popovers";
import * as reactions from "./reactions";
import * as rows from "./rows";
import * as settings_data from "./settings_data";

// We override the defaults set by tippy library here,
// so make sure to check this too after checking tippyjs
// documentation for default properties.
tippy.setDefaultProps({
    // We don't want tooltips
    // to take more space than
    // mobile widths ever.
    maxWidth: 300,

    // Some delay to showing / hiding the tooltip makes
    // it look less forced and more natural.
    delay: [100, 20],
    placement: "auto",

    // disable animations to make the
    // tooltips feel snappy
    animation: false,

    // Show tooltips on long press on touch based
    // devices.
    touch: ["hold", 750],

    // This has the side effect of some properties of parent applying to
    // tooltips.
    appendTo: "parent",

    // html content is not supported by default
    // enable it by passing data-tippy-allowHtml="true"
    // in the tag or a parameter.
});

export function initialize() {
    delegate("body", {
        // Add elements here which are not displayed on
        // initial load but are displayed later through
        // some means.
        //
        // Make all html elements having this class
        // show tippy styled tooltip on hover.
        target: ".tippy-zulip-tooltip",
    });

    // message reaction tooltip showing who reacted.
    let observer;
    delegate("body", {
        target: ".message_reaction, .message_reactions .reaction_button",
        placement: "bottom",
        onShow(instance) {
            const elem = $(instance.reference);
            if (!instance.reference.classList.contains("reaction_button")) {
                const local_id = elem.attr("data-reaction-id");
                const message_id = rows.get_message_id(instance.reference);
                const title = reactions.get_reaction_title_data(message_id, local_id);
                instance.setContent(title);
            }

            // Use MutationObserver to check for removal of nodes on which tooltips
            // are still active.
            // We target the message table and check for removal of it, it's children
            // and the reactions individually down in the subtree.
            const target_node = elem.parents(".message_table.focused_table").get(0);
            const nodes_to_check_for_removal = [
                elem.parents(".recipient_row").get(0),
                elem.parents(".message_reactions").get(0),
                elem.get(0),
            ];
            const config = {attributes: false, childList: true, subtree: true};

            const callback = function (mutationsList) {
                for (const mutation of mutationsList) {
                    for (const node of nodes_to_check_for_removal) {
                        // Hide instance if reference is in the removed node list.
                        if (Array.prototype.includes.call(mutation.removedNodes, node)) {
                            instance.hide();
                        }
                    }
                }
            };
            observer = new MutationObserver(callback);
            observer.observe(target_node, config);
        },
        onHidden(instance) {
            instance.destroy();
            observer.disconnect();
        },
        appendTo: () => document.body,
    });

    delegate("body", {
        target: ".compose_control_button",
        placement: "top",
        // Add some additional delay when they open
        // so that regular users don't have to see
        // them unless they want to.
        delay: [300, 20],
    });

    delegate("body", {
        target: ".message_control_button",
        placement: "top",
        // Add some additional delay when they open
        // so that regular users don't have to see
        // them unless they want to.
        delay: [300, 20],
        onShow(instance) {
            // Handle dynamic "starred messages" and "edit" widgets.
            const elem = $(instance.reference);
            let content = elem.attr("data-tippy-content");
            if (content === undefined) {
                // Tippy cannot get the content for message edit button
                // as it is dynamically inserted based on editability.
                // So, we have to manually get the i element to get the
                // content from it.
                //
                // TODO: Change the template structure so logic is unnecessary.
                const edit_button = elem.find("i.edit_content_button");
                content = edit_button.attr("data-tippy-content");
            }
            if (content === undefined) {
                // If content is still undefined it is because content
                // is specified on inner i tags and is handled by our
                // general tippy-zulip-tooltip class. So we return
                // false here to avoid showing an extra empty tooltip
                // for such cases.
                return false;
            }
            instance.setContent(content);
            return true;
        },
    });

    delegate("body", {
        delay: 0,
        target: "#streams_inline_cog",
        onShow(instance) {
            popovers.hide_all_except_sidebars();
            instance.setContent(
                render_left_sidebar_stream_setting_popover({
                    can_create_streams: settings_data.user_can_create_streams(),
                }),
            );
            $(instance.popper).on("click", instance.hide);
        },
        appendTo: () => document.body,
        trigger: "click",
        allowHTML: true,
        interactive: true,
        hideOnClick: true,
        theme: "light-border",
    });
}
<commit_msg>tippyjs: Show popovers on touch.<commit_after>import $ from "jquery";
import tippy, {delegate} from "tippy.js";

import render_left_sidebar_stream_setting_popover from "../templates/left_sidebar_stream_setting_popover.hbs";

import * as popovers from "./popovers";
import * as reactions from "./reactions";
import * as rows from "./rows";
import * as settings_data from "./settings_data";

// We override the defaults set by tippy library here,
// so make sure to check this too after checking tippyjs
// documentation for default properties.
tippy.setDefaultProps({
    // We don't want tooltips
    // to take more space than
    // mobile widths ever.
    maxWidth: 300,

    // Some delay to showing / hiding the tooltip makes
    // it look less forced and more natural.
    delay: [100, 20],
    placement: "auto",

    // disable animations to make the
    // tooltips feel snappy
    animation: false,

    // Show tooltips on long press on touch based
    // devices.
    touch: ["hold", 750],

    // This has the side effect of some properties of parent applying to
    // tooltips.
    appendTo: "parent",

    // html content is not supported by default
    // enable it by passing data-tippy-allowHtml="true"
    // in the tag or a parameter.
});

export function initialize() {
    delegate("body", {
        // Add elements here which are not displayed on
        // initial load but are displayed later through
        // some means.
        //
        // Make all html elements having this class
        // show tippy styled tooltip on hover.
        target: ".tippy-zulip-tooltip",
    });

    // message reaction tooltip showing who reacted.
    let observer;
    delegate("body", {
        target: ".message_reaction, .message_reactions .reaction_button",
        placement: "bottom",
        onShow(instance) {
            const elem = $(instance.reference);
            if (!instance.reference.classList.contains("reaction_button")) {
                const local_id = elem.attr("data-reaction-id");
                const message_id = rows.get_message_id(instance.reference);
                const title = reactions.get_reaction_title_data(message_id, local_id);
                instance.setContent(title);
            }

            // Use MutationObserver to check for removal of nodes on which tooltips
            // are still active.
            // We target the message table and check for removal of it, it's children
            // and the reactions individually down in the subtree.
            const target_node = elem.parents(".message_table.focused_table").get(0);
            const nodes_to_check_for_removal = [
                elem.parents(".recipient_row").get(0),
                elem.parents(".message_reactions").get(0),
                elem.get(0),
            ];
            const config = {attributes: false, childList: true, subtree: true};

            const callback = function (mutationsList) {
                for (const mutation of mutationsList) {
                    for (const node of nodes_to_check_for_removal) {
                        // Hide instance if reference is in the removed node list.
                        if (Array.prototype.includes.call(mutation.removedNodes, node)) {
                            instance.hide();
                        }
                    }
                }
            };
            observer = new MutationObserver(callback);
            observer.observe(target_node, config);
        },
        onHidden(instance) {
            instance.destroy();
            observer.disconnect();
        },
        appendTo: () => document.body,
    });

    delegate("body", {
        target: ".compose_control_button",
        placement: "top",
        // Add some additional delay when they open
        // so that regular users don't have to see
        // them unless they want to.
        delay: [300, 20],
    });

    delegate("body", {
        target: ".message_control_button",
        placement: "top",
        // Add some additional delay when they open
        // so that regular users don't have to see
        // them unless they want to.
        delay: [300, 20],
        onShow(instance) {
            // Handle dynamic "starred messages" and "edit" widgets.
            const elem = $(instance.reference);
            let content = elem.attr("data-tippy-content");
            if (content === undefined) {
                // Tippy cannot get the content for message edit button
                // as it is dynamically inserted based on editability.
                // So, we have to manually get the i element to get the
                // content from it.
                //
                // TODO: Change the template structure so logic is unnecessary.
                const edit_button = elem.find("i.edit_content_button");
                content = edit_button.attr("data-tippy-content");
            }
            if (content === undefined) {
                // If content is still undefined it is because content
                // is specified on inner i tags and is handled by our
                // general tippy-zulip-tooltip class. So we return
                // false here to avoid showing an extra empty tooltip
                // for such cases.
                return false;
            }
            instance.setContent(content);
            return true;
        },
    });

    delegate("body", {
        delay: 0,
        target: "#streams_inline_cog",
        onShow(instance) {
            popovers.hide_all_except_sidebars();
            instance.setContent(
                render_left_sidebar_stream_setting_popover({
                    can_create_streams: settings_data.user_can_create_streams(),
                }),
            );
            $(instance.popper).on("click", instance.hide);
        },
        appendTo: () => document.body,
        trigger: "click",
        allowHTML: true,
        interactive: true,
        hideOnClick: true,
        theme: "light-border",
        touch: true,
    });
}
<|endoftext|>