<commit_before>$.extend(view, {
  getListeningHistory: function (type) {
    if (type == '%w') {
      var where = 'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') IS NOT NULL AND DATE_FORMAT(<?=TBL_listening?>.`date`, \'%d\') != \'00\'';
    }
    else if (type == '%Y%m') {
      var where = 'DATE_FORMAT(<?=TBL_listening?>.`date`, \'%m\') != \'00\'';
    }
    else {
      var where = 'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') != \'00\'';
    }
    $.ajax({
      data:{
        group_by:'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\')',
        limit:200,
        lower_limit:'1970-00-00',
        order_by:'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') ASC',
        select:'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') as `bar_date`',
        tag_id:'<?=$tag_id?>',
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>',
        where:where
      },
      dataType:'json',
      statusCode:{
        200: function (data) { // 200 OK
          $.ajax({
            data:{
              json_data:data,
              type:type
            },
            success: function (data) {
              $('#historyLoader').hide();
              $('#history').html(data).hide();
              app.chart.xAxis[0].setCategories(view.categories, false);
              app.chart.series[0].setData(view.chart_data, true);
            },
            type:'POST',
            url:'/ajax/musicBar'
          });
        },
        204: function () { // 204 No Content
          $('#historyLoader').hide();
          $('#history').html('<?=ERR_NO_RESULTS?>');
          $('.music_bar').hide();
        },
        400: function () { // 400 Bad request
          $('#historyLoader').hide();
          alert('<?=ERR_BAD_REQUEST?>');
          $('.music_bar').hide();
        }
      },
      type:'GET',
      url:'/api/tag/get/<?=strtolower($tag_type)?>/listenings'
    });
  },
  // Get top albums.
  getTopAlbums: function () {
    $.ajax({
      data:{
        limit:13,
        lower_limit:'1970-00-00',
        tag_id:'<?=$tag_id?>',
        tag_type:'<?=$tag_type?>',
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>'
      },
      dataType:'json',
      statusCode:{
        200: function (data) {
          $.ajax({
            data:{
              json_data:data,
              type:'album'
            },
            success: function (data) {
              $('#topAlbumLoader').hide();
              $('#topAlbum').html(data);
            },
            type:'POST',
            url:'/ajax/musicWall'
          });
        },
        204: function () { // 204 No Content
          $('#topAlbumLoader').hide();
          $('#topAlbum').html('<?=ERR_NO_RESULTS?>');
        }
      },
      type:'GET',
      url:'/api/tag/get'
    });
  },
  // Get top artists.
  getTopArtists: function () {
    $.ajax({
      data:{
        group_by:'`artist_id`',
        limit:13,
        lower_limit:'1970-00-00',
        order_by:'`count` DESC, <?=TBL_artist?>.`artist_name` ASC',
        tag_id:'<?=$tag_id?>',
        tag_type:'<?=$tag_type?>',
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>'
      },
      dataType:'json',
      statusCode:{
        200: function (data) {
          $.ajax({
            data:{
              json_data:data,
              type:'artist'
            },
            success: function (data) {
              $('#topArtistLoader').hide();
              $('#topArtist').html(data);
            },
            type:'POST',
            url:'/ajax/musicWall'
          });
        },
        204: function () { // 204 No Content
          $('#topArtistLoader').hide();
          $('#topArtist').html('<?=ERR_NO_RESULTS?>');
        }
      },
      type:'GET',
      url:'/api/tag/get'
    });
  },
  // Get tag listeners.
  getUsers: function (from, where) {
    $.ajax({
      data:{
        from:from,
        limit:10,
        where:where
      },
      dataType:'json',
      statusCode:{
        200: function(data) { // 200 OK
          $.ajax({
            data:{
              hide:{
                calendar:true,
                date:true
              },
              json_data:data,
              size:32
            },
            success: function(data) {
              $('#topListenerLoader').hide();
              $('#topListener').html(data);
            },
            type:'POST',
            url:'/ajax/userTable'
          });
        },
        204: function () { // 204 No Content
          $('#topListenerLoader').hide();
          $('#topListener').html('<?=ERR_NO_RESULTS?>');
        },
        400: function () { // 400 Bad request
          $('#topListenerLoader').hide();
          $('#topListener').html('<?=ERR_BAD_REQUEST?>');
        }
      },
      type:'GET',
      url:'/api/listener/get'
    });
  },
  // Get tag listenings.
  getListenings: function (from, where) {
    $.ajax({
      data:{
        from:from,
        limit:10,
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>',
        where:where
      },
      dataType:'json',
      statusCode:{
        200: function (data) { // 200 OK
          $.ajax({
            data:{
              hide:{
                artist:true,
                count:true,
                rank:true,
                spotify:true
              },
              json_data:data,
              size:32
            },
            success: function (data) {
              $('#recentlyListenedLoader').hide();
              $('#recentlyListened').html(data);
            },
            type:'POST',
            url:'/ajax/sideTable'
          });
        },
        204: function () { // 204 No Content
          $('#recentlyListenedLoader').hide();
          $('#recentlyListened').html('<?=ERR_NO_RESULTS?>');
        },
        400: function (data) {
          alert('400 Bad Request')
        }
      },
      type:'GET',
      url:'/api/listening/get'
    });
  },
  updateGenreBio: function () {
    $.ajax({
      data:{
        tag_id:'<?=$tag_id?>',
        tag_name:'<?=$tag_name?>'
      },
      dataType:'json',
      type:'GET',
      url:'/api/genre/update/biography'
    });
  },
  initTagEvents: function () {
    $('#biographyMore').click(function (event) {
      $('#biographyMore').hide();
      $('.summary').hide();
      $('#biographyLess').show();
      $('.content').show();
      event.preventDefault();
    });
    $('#biographyLess').click(function (event) {
      $('#biographyLess').hide();
      $('.content').hide();
      $('#biographyMore').show();
      $('.summary').show();
      event.preventDefault();
    });
  }
});

$(document).ready(function () {
  view.initChart();
  view.getListeningHistory('%Y');
  view.getTopAlbums();
  view.getTopArtists();
  switch ('<?=$tag_type?>') {
    case 'genre':
      var from = '(SELECT <?=TBL_genres?>.`genre_id`, <?=TBL_genres?>.`album_id` FROM <?=TBL_genres?> GROUP BY <?=TBL_genres?>.`genre_id`, <?=TBL_genres?>.`album_id`) as <?=TBL_genres?>';
      var where = '<?=TBL_genres?>.`album_id` = <?=TBL_album?>.`id` AND <?=TBL_genres?>.`genre_id` = <?=$tag_id?>';
      break;
    case 'keyword':
      var from = '(SELECT <?=TBL_keywords?>.`keyword_id`, <?=TBL_keywords?>.`album_id` FROM <?=TBL_keywords?> GROUP BY <?=TBL_keywords?>.`keyword_id`, <?=TBL_keywords?>.`album_id`) as <?=TBL_keywords?>';
      var where = '<?=TBL_keywords?>.`album_id` = <?=TBL_album?>.`id` AND <?=TBL_keywords?>.`keyword_id` = <?=$tag_id?>';
      break;
    case 'nationality':
      var from = '(SELECT <?=TBL_nationalities?>.`nationality_id`, <?=TBL_nationalities?>.`album_id` FROM <?=TBL_nationalities?> GROUP BY <?=TBL_nationalities?>.`nationality_id`, <?=TBL_nationalities?>.`album_id`) as <?=TBL_nationalities?>';
      var where = '<?=TBL_nationalities?>.`album_id` = <?=TBL_album?>.`id` AND <?=TBL_nationalities?>.`nationality_id` = <?=$tag_id?>';
      break;
    case 'year':
      var from = '';
      var where = '<?=TBL_album?>.`year` = <?=$tag_id?>';
      break;
    default:
      var from = '';
      var where = '';
      break;
  }
  view.getUsers(from, where);
  view.getListenings(from, where);
  view.initTagEvents();

  var update_bio = <?=($update_bio === true) ? 1 : 0?>;
  if (update_bio === 1) {
    view.updateGenreBio();
  }
});<commit_msg>Fixed tag biography.<commit_after>$.extend(view, {
  getListeningHistory: function (type) {
    if (type == '%w') {
      var where = 'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') IS NOT NULL AND DATE_FORMAT(<?=TBL_listening?>.`date`, \'%d\') != \'00\'';
    }
    else if (type == '%Y%m') {
      var where = 'DATE_FORMAT(<?=TBL_listening?>.`date`, \'%m\') != \'00\'';
    }
    else {
      var where = 'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') != \'00\'';
    }
    $.ajax({
      data:{
        group_by:'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\')',
        limit:200,
        lower_limit:'1970-00-00',
        order_by:'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') ASC',
        select:'DATE_FORMAT(<?=TBL_listening?>.`date`, \'' + type + '\') as `bar_date`',
        tag_id:'<?=$tag_id?>',
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>',
        where:where
      },
      dataType:'json',
      statusCode:{
        200: function (data) { // 200 OK
          $.ajax({
            data:{
              json_data:data,
              type:type
            },
            success: function (data) {
              $('#historyLoader').hide();
              $('#history').html(data).hide();
              app.chart.xAxis[0].setCategories(view.categories, false);
              app.chart.series[0].setData(view.chart_data, true);
            },
            type:'POST',
            url:'/ajax/musicBar'
          });
        },
        204: function () { // 204 No Content
          $('#historyLoader').hide();
          $('#history').html('<?=ERR_NO_RESULTS?>');
          $('.music_bar').hide();
        },
        400: function () { // 400 Bad request
          $('#historyLoader').hide();
          alert('<?=ERR_BAD_REQUEST?>');
          $('.music_bar').hide();
        }
      },
      type:'GET',
      url:'/api/tag/get/<?=strtolower($tag_type)?>/listenings'
    });
  },
  // Get top albums.
  getTopAlbums: function () {
    $.ajax({
      data:{
        limit:13,
        lower_limit:'1970-00-00',
        tag_id:'<?=$tag_id?>',
        tag_type:'<?=$tag_type?>',
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>'
      },
      dataType:'json',
      statusCode:{
        200: function (data) {
          $.ajax({
            data:{
              json_data:data,
              type:'album'
            },
            success: function (data) {
              $('#topAlbumLoader').hide();
              $('#topAlbum').html(data);
            },
            type:'POST',
            url:'/ajax/musicWall'
          });
        },
        204: function () { // 204 No Content
          $('#topAlbumLoader').hide();
          $('#topAlbum').html('<?=ERR_NO_RESULTS?>');
        }
      },
      type:'GET',
      url:'/api/tag/get'
    });
  },
  // Get top artists.
  getTopArtists: function () {
    $.ajax({
      data:{
        group_by:'`artist_id`',
        limit:13,
        lower_limit:'1970-00-00',
        order_by:'`count` DESC, <?=TBL_artist?>.`artist_name` ASC',
        tag_id:'<?=$tag_id?>',
        tag_type:'<?=$tag_type?>',
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>'
      },
      dataType:'json',
      statusCode:{
        200: function (data) {
          $.ajax({
            data:{
              json_data:data,
              type:'artist'
            },
            success: function (data) {
              $('#topArtistLoader').hide();
              $('#topArtist').html(data);
            },
            type:'POST',
            url:'/ajax/musicWall'
          });
        },
        204: function () { // 204 No Content
          $('#topArtistLoader').hide();
          $('#topArtist').html('<?=ERR_NO_RESULTS?>');
        }
      },
      type:'GET',
      url:'/api/tag/get'
    });
  },
  // Get tag listeners.
  getUsers: function (from, where) {
    $.ajax({
      data:{
        from:from,
        limit:10,
        where:where
      },
      dataType:'json',
      statusCode:{
        200: function(data) { // 200 OK
          $.ajax({
            data:{
              hide:{
                calendar:true,
                date:true
              },
              json_data:data,
              size:32
            },
            success: function(data) {
              $('#topListenerLoader').hide();
              $('#topListener').html(data);
            },
            type:'POST',
            url:'/ajax/userTable'
          });
        },
        204: function () { // 204 No Content
          $('#topListenerLoader').hide();
          $('#topListener').html('<?=ERR_NO_RESULTS?>');
        },
        400: function () { // 400 Bad request
          $('#topListenerLoader').hide();
          $('#topListener').html('<?=ERR_BAD_REQUEST?>');
        }
      },
      type:'GET',
      url:'/api/listener/get'
    });
  },
  // Get tag listenings.
  getListenings: function (from, where) {
    $.ajax({
      data:{
        from:from,
        limit:10,
        username:'<?=(!empty($_GET['u'])) ? $_GET['u'] : ''?>',
        where:where
      },
      dataType:'json',
      statusCode:{
        200: function (data) { // 200 OK
          $.ajax({
            data:{
              hide:{
                artist:true,
                count:true,
                rank:true,
                spotify:true
              },
              json_data:data,
              size:32
            },
            success: function (data) {
              $('#recentlyListenedLoader').hide();
              $('#recentlyListened').html(data);
            },
            type:'POST',
            url:'/ajax/sideTable'
          });
        },
        204: function () { // 204 No Content
          $('#recentlyListenedLoader').hide();
          $('#recentlyListened').html('<?=ERR_NO_RESULTS?>');
        },
        400: function (data) {
          alert('400 Bad Request')
        }
      },
      type:'GET',
      url:'/api/listening/get'
    });
  },
  updateBio: function () {
    $.ajax({
      data:{
        tag_id:'<?=$tag_id?>',
        tag_name:'<?=$tag_name?>'
      },
      dataType:'json',
      type:'GET',
      url:'/api/<?=strtolower($tag_type)?>/update/biography'
    });
  },
  initTagEvents: function () {
    $('#biographyMore').click(function (event) {
      $('#biographyMore').hide();
      $('.summary').hide();
      $('#biographyLess').show();
      $('.content').show();
      event.preventDefault();
    });
    $('#biographyLess').click(function (event) {
      $('#biographyLess').hide();
      $('.content').hide();
      $('#biographyMore').show();
      $('.summary').show();
      event.preventDefault();
    });
  }
});

$(document).ready(function () {
  view.initChart();
  view.getListeningHistory('%Y');
  view.getTopAlbums();
  view.getTopArtists();
  switch ('<?=$tag_type?>') {
    case 'genre':
      var from = '(SELECT <?=TBL_genres?>.`genre_id`, <?=TBL_genres?>.`album_id` FROM <?=TBL_genres?> GROUP BY <?=TBL_genres?>.`genre_id`, <?=TBL_genres?>.`album_id`) as <?=TBL_genres?>';
      var where = '<?=TBL_genres?>.`album_id` = <?=TBL_album?>.`id` AND <?=TBL_genres?>.`genre_id` = <?=$tag_id?>';
      break;
    case 'keyword':
      var from = '(SELECT <?=TBL_keywords?>.`keyword_id`, <?=TBL_keywords?>.`album_id` FROM <?=TBL_keywords?> GROUP BY <?=TBL_keywords?>.`keyword_id`, <?=TBL_keywords?>.`album_id`) as <?=TBL_keywords?>';
      var where = '<?=TBL_keywords?>.`album_id` = <?=TBL_album?>.`id` AND <?=TBL_keywords?>.`keyword_id` = <?=$tag_id?>';
      break;
    case 'nationality':
      var from = '(SELECT <?=TBL_nationalities?>.`nationality_id`, <?=TBL_nationalities?>.`album_id` FROM <?=TBL_nationalities?> GROUP BY <?=TBL_nationalities?>.`nationality_id`, <?=TBL_nationalities?>.`album_id`) as <?=TBL_nationalities?>';
      var where = '<?=TBL_nationalities?>.`album_id` = <?=TBL_album?>.`id` AND <?=TBL_nationalities?>.`nationality_id` = <?=$tag_id?>';
      break;
    case 'year':
      var from = '';
      var where = '<?=TBL_album?>.`year` = <?=$tag_id?>';
      break;
    default:
      var from = '';
      var where = '';
      break;
  }
  view.getUsers(from, where);
  view.getListenings(from, where);
  view.initTagEvents();

  var update_bio = <?=($update_bio === true) ? 1 : 0?>;
  if (update_bio === 1) {
    view.updateBio();
  }
});<|endoftext|>


<commit_before>var isect = require('ray-aabb-slab');

module.exports = rayQuadtree;
rayQuadtree.rayAtTime = rayAtTime;

var scratch = [null, null];
var min = Math.min;
var max = Math.max;

function rayAtTime(o, d, t) {
  return [
    o[0] + d[0] * t,
    o[1] + d[1] * t
  ];
}

var exitLookup = [
  // [x, y]
  [1, 2],
  [4, 3],
  [3, 4],
  [4, 4]
];

function next(quad, x, y) {
  var i = x < y ? 0 : 1
  return exitLookup[quad][i];
}

/*
        o-------o-------o
        |       |       |
        |       |       |
        |       |       |
  my -- o-------o-------o
        |       |       |
        |       |       |
        |       |       |
  y0 -- o-------o-------o
        |       |
        x0      mx
*/

function first(x, y, mx, my) {
  // x entry plane
  if (x > y) {
    if (x < my) {
      return 0;
    } else {
      return 2;
    }
  // y entry plane
  } else {
    if (y < mx) {
      return 0;
    } else {
      return 1;
    }
  }
}

function processSubtree(mask, tx0, ty0, tx1, ty1, node, visit, depth, path) {
  path = path || []
  var mx = (tx0 + tx1) * 0.5;
  var my = (ty0 + ty1) * 0.5;

  // if (tx1 < 0 && ty1 < 0) {
  //   return false;
  // }
  var quad = first(tx0, ty0, mx, my);

  if (visit(node, tx0, ty0, depth, path)) {
    return true;
  }

  while (quad < 4) {
    var masked = quad ^ mask;
    var child = node.children[masked];
    if (!child) {
      console.warn('skip:', path.concat(masked).join(', '));
    }
    switch (quad) {
      case 0:
        if (child && processSubtree(mask, tx0, ty0, mx, my, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = next(quad, mx, my);
      break;

      case 1:
        if (child && processSubtree(mask, mx, ty0, tx1, my, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = next(quad, tx1, my);
      break;

      case 2:
        if (child && processSubtree(mask, tx0, my, mx, ty1, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = next(quad, mx, ty1);
      break;

      case 3:
        if (child && processSubtree(mask, mx, my, tx1, ty1, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = 4;
      break;
    }
  }
}

function processSubtreeHorizontal(ro, tx0, ty0, tx1, ty1, node, visit, depth) {
  if (visit(node, tx0, ty0, depth, quad)) {
    return true
  }

  var txm = (tx0 + tx1) * 0.5;
  var quad = (txm >= 0 ? 0 : 1) | (ro[1] >= node.center[1] ? 2 : 0);
  var child = node.children[quad];

  if (child && processSubtreeHorizontal(ro, txm, ty0, tx1, ty1, child, visit, depth+1)) {
    return true;
  }

  if (!(quad & 1)) {
    child = node.children[quad + 1];
    if (child && processSubtreeHorizontal(ro, txm, ty0, tx1, ty1, child, visit, depth+1)) {
      return true;
    }
  }
}

function processSubtreeVertical(ro, tx0, ty0, tx1, ty1, node, visit, depth) {
  if (!node.occupied) {
    return false;
  }

  if (visit(node, tx0, ty0, depth, quad)) {
    return true
  }

  var tym = (ty0 + ty1) * 0.5;
  var quad = (ro[0] >= node.center[0] ? 1 : 0) | (tym >= 0 ? 0 : 2);
  console.log(depth, quad)
  var child = node.children[quad];

  // TODO: test for occupancy
  if (child && processSubtreeVertical(ro, tx0, tym, tx1, ty1, child, visit, depth+1)) {
    return true;
  }

  if (quad < 2) {
    child = node.children[quad + 2];
    return child && processSubtreeVertical(ro, tx0, tym, tx1, ty1, child, visit, depth+1);
  }
}

function rayQuadtree(ctx, origin, dir, quadtree, out, visit) {
  var dx = dir[0];
  var dy = dir[1];
  var rox = origin[0];
  var roy = origin[1];
  var mask = 0;
  var root = quadtree.root;
  var bounds = root.bounds;

  if (dx < 0) {
    dx = -dx;
    mask += 1;
    rox = bounds[0][0] + (bounds[1][0] - rox);
  }

  if (dy < 0) {
    mask += 2;
    dy = -dy;
    roy = bounds[0][1] + (bounds[1][1] - roy);
  }

ctx.beginPath()
  ctx.arc(rox, roy, 2, 0, Math.PI*2, false)
  var far = rayAtTime([rox, roy], [dx, dy], 10000);
  ctx.moveTo(rox, roy);
  ctx.lineTo(far[0], far[1])
  ctx.fillStyle = ctx.strokeStyle = 'yellow'
  ctx.fill()
  ctx.stroke()

  var idir = [1/dx, 1/dy];

  var tx0 = (bounds[0][0] - rox) * idir[0];
  var ty0 = (bounds[0][1] - roy) * idir[1];
  var tx1 = (bounds[1][0] - rox) * idir[0];
  var ty1 = (bounds[1][1] - roy) * idir[1];
  if (max(tx0,ty0) < min(tx1,ty1)) {
    if (!isFinite(ty0)) {
      return processSubtreeHorizontal(origin, tx0, ty0, tx1, ty1, root, visit, 0);
    } else if (!isFinite(tx0)) {
      return processSubtreeVertical(origin, tx0, ty0, tx1, ty1, root, visit, 0);
    } else {
      return processSubtree(mask, tx0, ty0, tx1, ty1, root, visit, 0);
    }
  } else {
    console.log('no isect')
  }

  return null;
}
<commit_msg>round to nearest integer for next node calculation<commit_after>var isect = require('ray-aabb-slab');

module.exports = rayQuadtree;
rayQuadtree.rayAtTime = rayAtTime;

var scratch = [null, null];
var min = Math.min;
var max = Math.max;

function rayAtTime(o, d, t) {
  return [
    o[0] + d[0] * t,
    o[1] + d[1] * t
  ];
}

var exitLookup = [
  // [x, y]
  [1, 2],
  [4, 3],
  [3, 4],
  [4, 4]
];

function next(quad, x, y) {

  var i = Math.round(x) < Math.round(y) ? 0 : 1
  return exitLookup[quad][i];
}

/*
        o-------o-------o
        |       |       |
        |       |       |
        |       |       |
  my -- o-------o-------o
        |       |       |
        |       |       |
        |       |       |
  y0 -- o-------o-------o
        |       |
        x0      mx
*/

function first(x, y, mx, my) {
  // x entry plane
  if (x > y) {
    if (x < my) {
      return 0;
    } else {
      return 2;
    }
  // y entry plane
  } else {
    if (y < mx) {
      return 0;
    } else {
      return 1;
    }
  }
}

function processSubtree(mask, tx0, ty0, tx1, ty1, node, visit, depth, path) {
  path = path || []
  var mx = (tx0 + tx1) * 0.5;
  var my = (ty0 + ty1) * 0.5;

  // if (tx1 < 0 && ty1 < 0) {
  //   return false;
  // }
  var quad = first(tx0, ty0, mx, my);

  if (visit(node, tx0, ty0, depth, path)) {
    return true;
  }

  while (quad < 4) {
    var masked = quad ^ mask;
    var child = node.children[masked];
    if (!child) {
      console.warn('skip:', path.concat(masked).join(', '));
    }
    switch (quad) {
      case 0:
        if (child && processSubtree(mask, tx0, ty0, mx, my, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = next(quad, mx, my);
      break;

      case 1:
        if (child && processSubtree(mask, mx, ty0, tx1, my, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = next(quad, tx1, my);
      break;

      case 2:
        if (child && processSubtree(mask, tx0, my, mx, ty1, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = next(quad, mx, ty1);
      break;

      case 3:
        if (child && processSubtree(mask, mx, my, tx1, ty1, child, visit, depth+1, path.concat(masked))) {
          return true;
        }
        quad = 4;
      break;
    }
  }
}

function processSubtreeHorizontal(ro, tx0, ty0, tx1, ty1, node, visit, depth) {
  if (visit(node, tx0, ty0, depth, quad)) {
    return true
  }

  var txm = (tx0 + tx1) * 0.5;
  var quad = (txm >= 0 ? 0 : 1) | (ro[1] >= node.center[1] ? 2 : 0);
  var child = node.children[quad];

  if (child && processSubtreeHorizontal(ro, txm, ty0, tx1, ty1, child, visit, depth+1)) {
    return true;
  }

  if (!(quad & 1)) {
    child = node.children[quad + 1];
    if (child && processSubtreeHorizontal(ro, txm, ty0, tx1, ty1, child, visit, depth+1)) {
      return true;
    }
  }
}

function processSubtreeVertical(ro, tx0, ty0, tx1, ty1, node, visit, depth) {
  if (!node.occupied) {
    return false;
  }

  if (visit(node, tx0, ty0, depth, quad)) {
    return true
  }

  var tym = (ty0 + ty1) * 0.5;
  var quad = (ro[0] >= node.center[0] ? 1 : 0) | (tym >= 0 ? 0 : 2);
  console.log(depth, quad)
  var child = node.children[quad];

  // TODO: test for occupancy
  if (child && processSubtreeVertical(ro, tx0, tym, tx1, ty1, child, visit, depth+1)) {
    return true;
  }

  if (quad < 2) {
    child = node.children[quad + 2];
    return child && processSubtreeVertical(ro, tx0, tym, tx1, ty1, child, visit, depth+1);
  }
}

function rayQuadtree(ctx, origin, dir, quadtree, out, visit) {
  var dx = dir[0];
  var dy = dir[1];
  var rox = origin[0];
  var roy = origin[1];
  var mask = 0;
  var root = quadtree.root;
  var bounds = root.bounds;

  if (dx < 0) {
    dx = -dx;
    mask += 1;
    rox = bounds[0][0] + (bounds[1][0] - rox);
  }

  if (dy < 0) {
    mask += 2;
    dy = -dy;
    roy = bounds[0][1] + (bounds[1][1] - roy);
  }

ctx.beginPath()
  ctx.arc(rox, roy, 2, 0, Math.PI*2, false)
  var far = rayAtTime([rox, roy], [dx, dy], 10000);
  ctx.moveTo(rox, roy);
  ctx.lineTo(far[0], far[1])
  ctx.fillStyle = ctx.strokeStyle = 'yellow'
  ctx.fill()
  ctx.stroke()

  var idir = [1/dx, 1/dy];

  var tx0 = (bounds[0][0] - rox) * idir[0];
  var ty0 = (bounds[0][1] - roy) * idir[1];
  var tx1 = (bounds[1][0] - rox) * idir[0];
  var ty1 = (bounds[1][1] - roy) * idir[1];
  if (max(tx0,ty0) < min(tx1,ty1)) {
    if (!isFinite(ty0)) {
      return processSubtreeHorizontal(origin, tx0, ty0, tx1, ty1, root, visit, 0);
    } else if (!isFinite(tx0)) {
      return processSubtreeVertical(origin, tx0, ty0, tx1, ty1, root, visit, 0);
    } else {
      return processSubtree(mask, tx0, ty0, tx1, ty1, root, visit, 0);
    }
  } else {
    console.log('no isect')
  }

  return null;
}
<|endoftext|>


<commit_before>DIRECT_PROPERTIES = ["name", "length", "digits", "dashes"];
SCORE_PROPERTIES = ["english", "spanish", "french", "german",
					"prefix", "suffix"];
TLD_PROPERTIES = ["com", "net", "org", "biz", "info"];
SEARCH_LENGTHS = [7, 8, 6, 9, 5, 10, 4, 11, 3, 12]

function form_weights() {
	return {"length": $("input#id_len").val(),
			"digits": $("input#id_digits").val(),
			"dashes": $("input#id_dashes").val(),
			"english": $("input#id_english").val() / 1000000,
			"spanish": $("input#id_spanish").val() / 1000000,
			"french": $("input#id_french").val() / 1000000,
			"german": $("input#id_german").val() / 1000000,
			"prefix": $("input#id_prefix").val() / 1000000,
			"suffix": $("input#id_suffix").val() / 1000000,
			"com": $("input#id_com").val(),
			"net": $("input#id_net").val(),
			"org": $("input#id_org").val(),
			"biz": $("input#id_biz").val(),
			"info": $("input#id_info").val()}
}

function domain_score(domain, weights) {
	var score = 0.0;
	for (attr in weights)
		score += domain[attr] * weights[attr];
	return score;
}

function table_row(domain, row) {
	var html = '
';
	var index;
	for (index in DIRECT_PROPERTIES) {
		html += '' + domain[DIRECT_PROPERTIES[index]] + '	';
	}
	for (index in SCORE_PROPERTIES) {
		var score = domain[SCORE_PROPERTIES[index]] / 1000000;
		html += '' + score.toFixed(3) + '	';
	}
	for (index in TLD_PROPERTIES) {
		if (domain[TLD_PROPERTIES[index]])
			html += 'free	';
		else
			html += 'taken	';
	}
	html += '' + domain.score.toFixed(1) + '	';
	html += '
';
	return html;
}

function update_html() {
	var html = '';
	var row = 1;
	var names = [];
	for (name in $.domains) names.push(name);
	names.sort(function(a,b) {
		return $.domains[b].score - $.domains[a].score });
	names.length = 100;
	for (index in names) {
		domain = $.domains[names[index]];
		html += table_row(domain, row);
		row = (row % 2) + 1;
	}
	$("tbody#results").html(html);
	$("tbody tr").hover(
		function() { $(this).addClass("hover"); },
		function() { $(this).removeClass("hover"); });
}

function keyword_match(left, right, name) {
	if (left && name.substr(0, left.length) != left) return false;
	if (right && name.substr(-right.length) != right) return false;
	return true;
}

function ajax_result(json, status) {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var weights = form_weights();
	var length = 0;
	for (name in json) {
		domain = json[name];
		domain.name = name;
		domain.length = name.length;
		domain.score = domain_score(domain, weights);
		if (keyword_match(left, right, name))
			$.domains[name] = domain;
		length = name.length;
	}
	$.ajax_search.xhr[length] = false;
	update_html();
}

function ajax_search(left, right) {
	if ($.ajax_search.left == left && $.ajax_search.right == right) return;
	$.ajax_search.left = left;
	$.ajax_search.right = right;
	for (var index in SEARCH_LENGTHS) {
		var length = SEARCH_LENGTHS[index];
		var data = {"left": left, "right": right, "length": length};
		if ($.ajax_search.xhr[length])
			$.ajax_search.xhr[length].abort();
		$.ajax_search.xhr[length] =
			$.getJSON("/search/json/", data, ajax_result);
	}
}

function keyword_keypress(e) {
	if ((e.which != 45) &&
		(e.which < 48 || e.which > 57) &&
		(e.which < 97 || e.which > 122)) return;
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var updated =
		this.value.substr(0, this.selectionStart) +
		String.fromCharCode(e.which) +
		this.value.substr(this.selectionEnd);
	if (this.name == 'left') left = updated;
	else if (this.name == 'right') right = updated;
	for (name in $.domains)
		if (!keyword_match(left, right, name))
			delete $.domains[name];
	update_html();
	ajax_search(left, right);
}

function keyword_keyup() {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	ajax_search(left, right);
}

function document_ready() {
	$.domains = {};
	$.ajax_search = {};
	$.ajax_search.xhr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
	$.ajax_search.left = $("input#id_left").val();
	$.ajax_search.right = $("input#id_right").val();
	$("input.keyword").keypress(keyword_keypress);
	$("input.keyword").keyup(keyword_keyup);
}

$(document).ready(document_ready);
<commit_msg>Enabled browser caching for JSON results.<commit_after>DIRECT_PROPERTIES = ["name", "length", "digits", "dashes"];
SCORE_PROPERTIES = ["english", "spanish", "french", "german",
					"prefix", "suffix"];
TLD_PROPERTIES = ["com", "net", "org", "biz", "info"];
SEARCH_LENGTHS = [7, 8, 6, 9, 5, 10, 4, 11, 3, 12]

function form_weights() {
	return {"length": $("input#id_len").val(),
			"digits": $("input#id_digits").val(),
			"dashes": $("input#id_dashes").val(),
			"english": $("input#id_english").val() / 1000000,
			"spanish": $("input#id_spanish").val() / 1000000,
			"french": $("input#id_french").val() / 1000000,
			"german": $("input#id_german").val() / 1000000,
			"prefix": $("input#id_prefix").val() / 1000000,
			"suffix": $("input#id_suffix").val() / 1000000,
			"com": $("input#id_com").val(),
			"net": $("input#id_net").val(),
			"org": $("input#id_org").val(),
			"biz": $("input#id_biz").val(),
			"info": $("input#id_info").val()}
}

function domain_score(domain, weights) {
	var score = 0.0;
	for (attr in weights)
		score += domain[attr] * weights[attr];
	return score;
}

function table_row(domain, row) {
	var html = '
';
	var index;
	for (index in DIRECT_PROPERTIES) {
		html += '' + domain[DIRECT_PROPERTIES[index]] + '	';
	}
	for (index in SCORE_PROPERTIES) {
		var score = domain[SCORE_PROPERTIES[index]] / 1000000;
		html += '' + score.toFixed(3) + '	';
	}
	for (index in TLD_PROPERTIES) {
		if (domain[TLD_PROPERTIES[index]])
			html += 'free	';
		else
			html += 'taken	';
	}
	html += '' + domain.score.toFixed(1) + '	';
	html += '
';
	return html;
}

function update_html() {
	var html = '';
	var row = 1;
	var names = [];
	for (name in $.domains) names.push(name);
	names.sort(function(a,b) {
		return $.domains[b].score - $.domains[a].score });
	names.length = 100;
	for (index in names) {
		domain = $.domains[names[index]];
		html += table_row(domain, row);
		row = (row % 2) + 1;
	}
	$("tbody#results").html(html);
	$("tbody tr").hover(
		function() { $(this).addClass("hover"); },
		function() { $(this).removeClass("hover"); });
}

function keyword_match(left, right, name) {
	if (left && name.substr(0, left.length) != left) return false;
	if (right && name.substr(-right.length) != right) return false;
	return true;
}

function ajax_result(json, status) {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var weights = form_weights();
	var length = 0;
	for (name in json) {
		domain = json[name];
		domain.name = name;
		domain.length = name.length;
		domain.score = domain_score(domain, weights);
		if (keyword_match(left, right, name))
			$.domains[name] = domain;
		length = name.length;
	}
	$.ajax_search.xhr[length] = false;
	update_html();
}

function ajax_search(left, right) {
	if ($.ajax_search.left == left && $.ajax_search.right == right) return;
	$.ajax_search.left = left;
	$.ajax_search.right = right;
	for (var index in SEARCH_LENGTHS) {
		var length = SEARCH_LENGTHS[index];
		if ($.ajax_search.xhr[length])
			$.ajax_search.xhr[length].abort();
		$.ajax_search.xhr[length] = $.ajax({
				type: "GET",
				url: "/search/json/",
				data: {left: left, right: right, length: length},
				dataType: "json",
				cache: true,
				success: ajax_result,
			});
	}
}

function keyword_keypress(e) {
	if ((e.which != 45) &&
		(e.which < 48 || e.which > 57) &&
		(e.which < 97 || e.which > 122)) return;
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	var updated =
		this.value.substr(0, this.selectionStart) +
		String.fromCharCode(e.which) +
		this.value.substr(this.selectionEnd);
	if (this.name == 'left') left = updated;
	else if (this.name == 'right') right = updated;
	for (name in $.domains)
		if (!keyword_match(left, right, name))
			delete $.domains[name];
	update_html();
	ajax_search(left, right);
}

function keyword_keyup() {
	var left = $("input#id_left").val();
	var right = $("input#id_right").val();
	ajax_search(left, right);
}

function document_ready() {
	$.domains = {};
	$.ajax_search = {};
	$.ajax_search.xhr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
	$.ajax_search.left = $("input#id_left").val();
	$.ajax_search.right = $("input#id_right").val();
	$("input.keyword").keypress(keyword_keypress);
	$("input.keyword").keyup(keyword_keyup);
}

$(document).ready(document_ready);
<|endoftext|>


<commit_before>"use strict";
var createFutureApi = module.exports = function(query){
    return {
        userInfo : function(){
            return query('future_userinfo.do', {})
        },
    }
}
<commit_msg>add future api<commit_after>"use strict";
var createFutureApi = module.exports = function(query){
    return {
        userInfo : function(){
            return query('future_userinfo.do', {})
        },
        position : function(symbol, contract_type){
            return query('future_position.do', {
                symbol : symbol,
                contract_type : contract_type,
            })
        },
        trade : function(symbol, contract_type, price, amount, type, lever_rate){
            lever_rate = lever_rate || 10;
            return query('future_trade.do', {
                symbol : symbol,
                contract_type : contract_type,
                price : price,
                amount : amount,
                type : type,
                match_price : 0,
                lever_rate : lever_rate,
            })
        },
        tradesHistory : function(symbol, date, since){
            return query('future_trades_history.do', {
                symbol : symbol,
                date : date,
                since : since,
            })
        },
        batchTrade : function(symbol, contract_type, orders_data, lever_rate){
            lever_rate = lever_rate || 10;
            return query('future_batch_trade.do', {
                symbol : symbol,
                contract_type : contract_type,
                orders_data : orders_data,
                lever_rate : lever_rate,
            })
        },
        cancel : function(symbol, contract_type, order_id){
            return query('future_cancel.do', {
                symbol : symbol,
                contract_type : contract_type,
                order_id : order_id,
            })
        },
        orderInfo : function(symbol, contract_type, status, order_id, current_page, page_length){
            page_length = page_length || 50;
            return query('future_order_info.do', {
                symbol : symbol,
                contract_type : contract_type,
                status : status,
                order_id : order_id,
                current_page : current_page,
                page_length : page_length,
            })
        },
        ordersInfo : function(symbol, contract_type, order_id){
            return query('future_orders_info.do', {
                symbol : symbol,
                contract_type : contract_type,
                order_id : order_id,
            })
        },
        userinfo4fix : function(){
            return query('future_userinfo_4fix.do', {})
        },
        position4fix : function(symbol, contract_type, type){
            return query('future_position_4fix.do', {
                symbol : symbol,
                contract_type : contract_type,
                type : type,
            })
        },
        explosive : function(symbol, contract_type, status, current_page, page_length){
            page_length = page_length || 50;
            return query('future_explosive.do', {
                symbol : symbol,
                contract_type : contract_type,
                status : status,
                current_page : current_page,
                page_length : page_length,
            })
        },

    }
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var assert = require('assert');
var PluginError = require('gulp-util').PluginError;
var normalize = require('json-normalizer').sync;
var regulate = require('json-regulator');
var globsJoin = require('../helpers/globs').join;
var from = require('../helpers/dataflow');

var INTERPOLATE = /{{([\s\S]+?)}}/g;

/*
 * NOTE:
 * According to [gulp API](https://github.com/gulpjs/gulp/blob/master/docs/API.md)
 * and [gulp 4.0 API](https://github.com/gulpjs/gulp/blob/4.0/docs/API.md):
 * gulp supports all options supported by node-glob and glob-stream except ignore and adds the following options.
 *
 * @see
 * [node-glob](https://github.com/isaacs/node-glob)
 * [glob-stream](https://github.com/gulpjs/glob-stream)
 *
 */
var SCHEMA_SRC = require('../schema/src.json');
var SCHEMA_DEST = require('../schema/dest.json');

var SCHEMA_DEFAULTS = {
	type: 'object',
	properties: {
		src: SCHEMA_SRC,
		dest: SCHEMA_DEST,
		configs: {
			description: 'Any property insides "configs" property considered a configuration property.',
			type: 'object',
			additionalProperties: true
		},
		options: {
			type: 'object',
			additionalProperties: true
		}
	},
	patternProperties: {
		'^\\$.+$': {
			description: 'Any property prefix with $ considered a configuration property and can be accessed both with or without $ prefix.'
		}
	},
	additionalProperties: false
};

var PATTERN_PROPERTY_REGEX = /^\$(.+)$/;

var SCHEMA_TASK = require('../schema/task.json');
var TASK_SCHEMA_MAPPINGS = {
	title: 'name',
	description: 'description'
};
var TASK_METADATAS = Object.keys(SCHEMA_TASK.properties);

var REGEX_RUNTIME_OPTIONS = /^([.#]?)([_\w][-_:\s\w]*)([!?]?)$/;

var CONSTANT = {
	VISIBILITY: {
		/** hidden configurable task can't be run from cli, but still functional */
		HIDDEN: '.',
		/** disabled configurable task is not processed and not functional, including all it's descendants */
		DISABLED: '#',
		/** normal configurable task can be run from cli */
		NORMAL: ''
	},
	RUNTIME: {
		/** configurable task can only run in production mode */
		PRODUCTION: '!',
		/** configurable task can only run in development mode */
		DEVELOPMENT: '?',
		/** configurable task can run in both production and development mode */
		ALL: ''
	}
};

// TODO: remove temp hack for _.defaultsDeep() when bug fix public available:
// defaultsDeep() try to mix string characters into array
// https://github.com/lodash/lodash/issues/1560
_.defaultsDeep = defaultsDeep;

function defaultsDeep(object) {
	var sources = Array.prototype.splice.call(arguments, 1);

	sources.forEach(function (source) {
		_defaults(object, source);
	});
	return object;

	function _defaults(target, source) {
		_.forIn(source, function (value, key) {
			if (_.isPlainObject(target[key]) && _.isPlainObject(value)) {
				_defaults(target[key], value);
			} else if (!(key in target)) {
				target[key] = typeof value === 'function' ? value : _.cloneDeep(value);
			}
		});
	}
}

function getTaskRuntimeInfo(rawConfig) {
	var match, name, taskInfo;

	taskInfo = from(rawConfig).to({}).move(TASK_METADATAS);

	if (taskInfo.name) {
		name = _.trim(taskInfo.name);
		match = REGEX_RUNTIME_OPTIONS.exec(name);
		if (!match) {
			throw new PluginError(__filename, 'invalid task name: ' + name);
		}

		taskInfo.name = match[2] || name;

		if (match[1]) {
			taskInfo.visibility = match[1];
		}
		if (match[3]) {
			taskInfo.runtime = match[3];
		}
	}

	return taskInfo;
}

function realize(original, additional) {
	var values;

	values = _.defaultsDeep({}, original, additional);
	return realizeAll({}, values);

	function realizeAll(target, source) {
		_.each(source, function (value, name) {
			target[name] = _realize(value);
		});
		return target;
	}

	function _realize(source) {
		if (typeof source === 'string') {
			return source.replace(INTERPOLATE, function (match, path) {
				var value;

				value = _.get(values, path) || path;
				if (typeof value === 'function') {
					value = value(values);
				}
				return value;
			});
		}
		if (typeof source === 'function') {
			return source(values);
		}
		if (_.isArray(source)) {
			return realizeAll([], source);
		}
		if (_.isPlainObject(source)) {
			return realizeAll({}, source);
		}
		return source;
	}
}

function src(values) {
	return normalize(SCHEMA_SRC, values);
}

function dest(values) {
	return normalize(SCHEMA_DEST, values);
}

// TODO: make sure path separator works in all operating systems (especially windows that use "\\").
function resolveSrc(child, parent) {
	var value;

	if (child.src) {
		value = src(child.src);
		if (parent.src && !(value.options && value.options.override)) {
			value.globs = globsJoin(parent.src.globs, value.globs);
		}
		return value;
	}
	return parent.src;
}

function resolveDest(child, parent) {
	var value;

	if (child.dest) {
		value = dest(child.dest);
		if (parent.dest && !(value.options && value.options.override)) {
			value.path = globsJoin(parent.dest.path, value.path);
		}
		return value;
	}
	return parent.dest;
}

/**
 * If both parentConfig and taskConfig specified src property
 * then try to join paths.
 */
function sort(taskInfo, rawConfig, parentConfig, optionalSchema) {
	var inheritedConfig, schema, subTaskConfigs, taskConfig, value;

	assert(_.isPlainObject(rawConfig));

	schema = optionalSchema || {};
	from(schema).to(taskInfo).imply(TASK_SCHEMA_MAPPINGS);
	schema = _.defaultsDeep({}, schema, SCHEMA_DEFAULTS);

	taskConfig = {};

	if (parentConfig.src && !Array.isArray(parentConfig.src.globs)) {
		throw new TypeError('parentConfig.src not normalized');
	}

	value = resolveSrc(rawConfig, parentConfig);
	if (value) {
		taskConfig.src = value;
	}

	if (parentConfig.dest && typeof parentConfig.dest.path !== 'string') {
		throw new TypeError('parentConfig.dest not normalized');
	}

	value = resolveDest(rawConfig, parentConfig);
	if (value) {
		taskConfig.dest = value;
	}

	inheritedConfig = _.defaultsDeep(taskConfig, rawConfig, parentConfig);

	taskConfig = normalize(schema, inheritedConfig);
	taskConfig = addPatternProperties(taskConfig);
	taskConfig = regulate(taskConfig, ['configs']);
	assert(_.isPlainObject(taskConfig));

	subTaskConfigs = _.omit(inheritedConfig, Object.keys(taskConfig));

	return {
		taskInfo: taskInfo,
		taskConfig: taskConfig,
		subTaskConfigs: subTaskConfigs
	};
}

function addPatternProperties(target) {
	Object.keys(target).forEach(function (key) {
		var match;

		match = PATTERN_PROPERTY_REGEX.exec(key);
		if (match) {
			target[match[1]] = target[key];
		}
	});
	return target;
}

module.exports = {
	CONSTANT: CONSTANT,
	getTaskRuntimeInfo: getTaskRuntimeInfo,
	dest: dest,
	normalize: normalize,
	realize: realize,
	resolveSrc: resolveSrc,
	resolveDest: resolveDest,
	sort: sort,
	src: src
};
<commit_msg>Configuration: add notes about "configs" property<commit_after>'use strict';

var _ = require('lodash');
var assert = require('assert');
var PluginError = require('gulp-util').PluginError;
var normalize = require('json-normalizer').sync;
var regulate = require('json-regulator');
var globsJoin = require('../helpers/globs').join;
var from = require('../helpers/dataflow');

var INTERPOLATE = /{{([\s\S]+?)}}/g;

/*
 * NOTE:
 * According to [gulp API](https://github.com/gulpjs/gulp/blob/master/docs/API.md)
 * and [gulp 4.0 API](https://github.com/gulpjs/gulp/blob/4.0/docs/API.md):
 * gulp supports all options supported by node-glob and glob-stream except ignore and adds the following options.
 *
 * @see
 * [node-glob](https://github.com/isaacs/node-glob)
 * [glob-stream](https://github.com/gulpjs/glob-stream)
 *
 */
var SCHEMA_SRC = require('../schema/src.json');
var SCHEMA_DEST = require('../schema/dest.json');

var SCHEMA_DEFAULTS = {
	type: 'object',
	properties: {
		src: SCHEMA_SRC,
		dest: SCHEMA_DEST,
		configs: {
			description: 'Any property insides "configs" property considered a configuration property.',
			type: 'object',
			additionalProperties: true
		},
		options: {
			type: 'object',
			additionalProperties: true
		}
	},
	patternProperties: {
		'^\\$.+$': {
			description: 'Any property prefix with $ considered a configuration property and can be accessed both with or without $ prefix.'
		}
	},
	additionalProperties: false
};

var PATTERN_PROPERTY_REGEX = /^\$(.+)$/;

var SCHEMA_TASK = require('../schema/task.json');
var TASK_SCHEMA_MAPPINGS = {
	title: 'name',
	description: 'description'
};
var TASK_METADATAS = Object.keys(SCHEMA_TASK.properties);

var REGEX_RUNTIME_OPTIONS = /^([.#]?)([_\w][-_:\s\w]*)([!?]?)$/;

var CONSTANT = {
	VISIBILITY: {
		/** hidden configurable task can't be run from cli, but still functional */
		HIDDEN: '.',
		/** disabled configurable task is not processed and not functional, including all it's descendants */
		DISABLED: '#',
		/** normal configurable task can be run from cli */
		NORMAL: ''
	},
	RUNTIME: {
		/** configurable task can only run in production mode */
		PRODUCTION: '!',
		/** configurable task can only run in development mode */
		DEVELOPMENT: '?',
		/** configurable task can run in both production and development mode */
		ALL: ''
	}
};

// TODO: remove temp hack for _.defaultsDeep() when bug fix public available:
// defaultsDeep() try to mix string characters into array
// https://github.com/lodash/lodash/issues/1560
_.defaultsDeep = defaultsDeep;

function defaultsDeep(object) {
	var sources = Array.prototype.splice.call(arguments, 1);

	sources.forEach(function (source) {
		_defaults(object, source);
	});
	return object;

	function _defaults(target, source) {
		_.forIn(source, function (value, key) {
			if (_.isPlainObject(target[key]) && _.isPlainObject(value)) {
				_defaults(target[key], value);
			} else if (!(key in target)) {
				target[key] = typeof value === 'function' ? value : _.cloneDeep(value);
			}
		});
	}
}

function getTaskRuntimeInfo(rawConfig) {
	var match, name, taskInfo;

	taskInfo = from(rawConfig).to({}).move(TASK_METADATAS);

	if (taskInfo.name) {
		name = _.trim(taskInfo.name);
		match = REGEX_RUNTIME_OPTIONS.exec(name);
		if (!match) {
			throw new PluginError(__filename, 'invalid task name: ' + name);
		}

		taskInfo.name = match[2] || name;

		if (match[1]) {
			taskInfo.visibility = match[1];
		}
		if (match[3]) {
			taskInfo.runtime = match[3];
		}
	}

	return taskInfo;
}

function realize(original, additional) {
	var values;

	values = _.defaultsDeep({}, original, additional);
	return realizeAll({}, values);

	function realizeAll(target, source) {
		_.each(source, function (value, name) {
			target[name] = _realize(value);
		});
		return target;
	}

	function _realize(source) {
		if (typeof source === 'string') {
			return source.replace(INTERPOLATE, function (match, path) {
				var value;

				value = _.get(values, path) || path;
				if (typeof value === 'function') {
					value = value(values);
				}
				return value;
			});
		}
		if (typeof source === 'function') {
			return source(values);
		}
		if (_.isArray(source)) {
			return realizeAll([], source);
		}
		if (_.isPlainObject(source)) {
			return realizeAll({}, source);
		}
		return source;
	}
}

function src(values) {
	return normalize(SCHEMA_SRC, values);
}

function dest(values) {
	return normalize(SCHEMA_DEST, values);
}

// TODO: make sure path separator works in all operating systems (especially windows that use "\\").
function resolveSrc(child, parent) {
	var value;

	if (child.src) {
		value = src(child.src);
		if (parent.src && !(value.options && value.options.override)) {
			value.globs = globsJoin(parent.src.globs, value.globs);
		}
		return value;
	}
	return parent.src;
}

function resolveDest(child, parent) {
	var value;

	if (child.dest) {
		value = dest(child.dest);
		if (parent.dest && !(value.options && value.options.override)) {
			value.path = globsJoin(parent.dest.path, value.path);
		}
		return value;
	}
	return parent.dest;
}

/**
 * If both parentConfig and taskConfig specified src property
 * then try to join paths.
 */
function sort(taskInfo, rawConfig, parentConfig, optionalSchema) {
	var inheritedConfig, schema, subTaskConfigs, taskConfig, value;

	assert(_.isPlainObject(rawConfig));

	schema = optionalSchema || {};
	from(schema).to(taskInfo).imply(TASK_SCHEMA_MAPPINGS);
	schema = _.defaultsDeep({}, schema, SCHEMA_DEFAULTS);

	taskConfig = {};

	if (parentConfig.src && !Array.isArray(parentConfig.src.globs)) {
		throw new TypeError('parentConfig.src not normalized');
	}

	value = resolveSrc(rawConfig, parentConfig);
	if (value) {
		taskConfig.src = value;
	}

	if (parentConfig.dest && typeof parentConfig.dest.path !== 'string') {
		throw new TypeError('parentConfig.dest not normalized');
	}

	value = resolveDest(rawConfig, parentConfig);
	if (value) {
		taskConfig.dest = value;
	}

	inheritedConfig = _.defaultsDeep(taskConfig, rawConfig, parentConfig);

	taskConfig = normalize(schema, inheritedConfig);
	taskConfig = addPatternProperties(taskConfig);
	// NOTE: A thought about that "configs" should be "normalized".
	// But remember that the "configs" and "$" property prefix are designed for tasks that have no schemas.
	// It just won't do anything try to normalize it without schema.
	taskConfig = regulate(taskConfig, ['configs']);
	assert(_.isPlainObject(taskConfig));

	subTaskConfigs = _.omit(inheritedConfig, Object.keys(taskConfig));

	return {
		taskInfo: taskInfo,
		taskConfig: taskConfig,
		subTaskConfigs: subTaskConfigs
	};
}

function addPatternProperties(target) {
	Object.keys(target).forEach(function (key) {
		var match;

		match = PATTERN_PROPERTY_REGEX.exec(key);
		if (match) {
			target[match[1]] = target[key];
		}
	});
	return target;
}

module.exports = {
	CONSTANT: CONSTANT,
	getTaskRuntimeInfo: getTaskRuntimeInfo,
	dest: dest,
	normalize: normalize,
	realize: realize,
	resolveSrc: resolveSrc,
	resolveDest: resolveDest,
	sort: sort,
	src: src
};
<|endoftext|>


<commit_before>var dutils = require('./deck.js');

var Deck = dutils.Deck;
var dealerAction = dutils.dealerAction;
var totalValue = dutils.totalValue;

function CurrentGame(type, bet, payout, gd) {
  this.type = type;
  this.bet = bet;
  this.scoredata = {};
  this.person = payout;
  this.gd = gd;
}

CurrentGame.prototype.start = function(cb) {
  if (this.type == "blackjack") {
    this.scoredata.deck = new Deck();
    this.scoredata.dealer_hand = [this.scoredata.deck.top(), this.scoredata.deck.top()];
    this.scoredata.player_hand = [this.scoredata.deck.top(), this.scoredata.deck.top()];
    cb("Dealer Hand: " + this.scoredata.dealer_hand[0] + ",??\nYour Hand: " + this.scoredata.player_hand.join(","));
  }
  return this.scoredata;
};

CurrentGame.prototype.run = function(params, cb) {
  if (this.type == "blackjack") {
    if (params[0] == "hit") {
      this.scoredata.player_hand.push(this.scoredata.deck.top());
      if (totalValue(this.scoredata.player_hand, false) >= 21) { //this calculation is false somehow
        this.finish(cb);
      } else {
        cb("Your hand is " + this.scoredata.player_hand.join(",") + ".");
      }
    } else if (params[0] == "stand") {
      this.finish(cb);
    }
  }
};

function betterNonBust(hand) {
  let x = totalValue(hand, true);
  let y = totalValue(hand, false);
  if (x > 21) return y;
  else return x;
}

CurrentGame.prototype.finish = function(cb) {
  if (this.type == "blackjack") {
    let dealer_going = dealerAction(this.scoredata.dealer_hand);
    while (dealer_going) {
      this.scoredata.dealer_hand.push(this.scoredata.deck.top());
      dealer_going = dealerAction(this.scoredata.dealer_hand);
    }
    let dbj = totalValue(this.scoredata.dealer_hand, true) == 21 || totalValue(this.scoredata.dealer_hand, false) === 21;
    let pbj = totalValue(this.scoredata.player_hand, true) == 21 || totalValue(this.scoredata.player_hand, false) === 21; //lol pbj
    if (dbj && pbj) {
      cb("It's a tie! Both blackjack.\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet);
      return;
    }
    if (pbj) {
      cb("Blackjack!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, parseInt(this.bet * 2.5));
      return;
    }
    if (dbj) {
      cb("You lose!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      return;
    }
    if (totalValue(this.scoredata.player_hand, false) > 21) {
      cb("You busted! Idiot!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      return;
    }
    if (totalValue(this.scoredata.dealer_hand, false) > 21) {
      cb("Dealer busted, you win!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet * 2);
      return;
    }
    if (betterNonBust(this.scoredata.dealer_hand) == betterNonBust(this.scoredata.player_hand)) {
      cb("It's a tie!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet);
      return;
    }
    if (betterNonBust(this.scoredata.dealer_hand) > betterNonBust(this.scoredata.player_hand)) {
      cb("Dealer wins!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      return;
    } else {
      cb("You win!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet * 2);
    }
  }
};

function GameData(gamedata) {
  this.data = gamedata;
}

GameData.prototype.newPlayer = function(id, name) {
  let player = {
    id,
    credits: 100,
    last: Date.now(),
    name,
    currgame: null
  };
  this.data.players.push(player);
};

GameData.prototype.getBalOf = function(id) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      return this.data.players[i].credits;
    }
  }
  return "Not Found";
};

GameData.prototype.setBalOf = function(id, credits) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      this.data.players[i].credits = parseInt(credits);
    }
  }
};

GameData.prototype.pay = function(id, credits) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      this.data.players[i].credits += parseInt(credits);
    }
  }
};

GameData.prototype.playerExists = function(id) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      return true;
    }
  }
  return false;
};

GameData.prototype.getLeaderboard = function(leaderlength) {
  let ret = [this.data.players[0]];
  //I know this will fail if there is nothing in this.data.players but I don't care.
  for (let i = 1; i < this.data.players.length; i++) {
    for (let j = 0; j < ret.length; j++) {
      if (this.data.players[i].credits > ret[j].credits) {
        ret.splice(j, 0, this.data.players[i]);
        break;
      }
    }
  }
  let retar = "Leaderboard: \n";
  for (let i = 0; i < leaderlength; i++) {
    if (i >= ret.length) {
      break;
    }
    retar = retar + (i + 1) + ") " + ret[i].name + " " + ret[i].credits + " points" + "\n";
  }
  return retar;
};

GameData.prototype.dataToSave = function() {
  let tdata = {
    players: []
  };
  for (let i = 0; i < this.data.players.length; i++) {
    tdata.players.push({
      id: this.data.players[i].id,
      credits: this.data.players[i].credits,
      last: this.data.players[i].last,
      name: this.data.players[i].name
    })
  }
  return JSON.stringify(tdata);
};

GameData.prototype.startGame = function(id, type, bet, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id && this.data.players[i].credits > bet) {
      this.data.players[i].credits -= parseInt(bet + 0.9);
      this.data.players[i].currgame = new CurrentGame(type, bet, this.data.players[i].id, this);
      this.data.players[i].currgame.start((x) => {
        cb(this.data.players[i].name + "'s Game:\n" + x)
      });
    }
  }
};

GameData.prototype.moveGame = function(id, params, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id && this.data.players[i].currgame) {
      this.data.players[i].currgame.run(params, (x) => {
        cb(this.data.players[i].name + "'s Game:\n" + x)
      });
    }
  }
}

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

function getRandomFromList(list) {
  return list[getRandomInt(0, list.length)];
}

function millisToMinutes(t) {
  return parseInt(t/1000/60);
}

GameData.prototype.refill = function(id, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      if (this.data.players[i].last + (1000 * 60 * 60 * 4) > Date.now()) {
        cb("Cannot refill now, try again later. You need to wait 4 hours between refills.\nYou last got free coins " + millisToMinutes(Date.now() - this.data.players[i].last));
      } else {
        if (this.data.players[i].credits > 500) {
          cb("You don't need a refill now. Go coinflip it all away.");
        } else {
          let x = getRandomFromList([10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 40, 40, 80, 160]);
          cb("You just got a refill of " + x + "credits");
          this.data.players[i].credits += x;
          this.data.players[i].last = Date.now();
        }
      }
    }
  }
};

GameData.prototype.freefill = function(id, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      this.data.players[i].last = 0;
    }
  }
};

module.exports = {
  GameData
};<commit_msg>finish another sentence<commit_after>var dutils = require('./deck.js');

var Deck = dutils.Deck;
var dealerAction = dutils.dealerAction;
var totalValue = dutils.totalValue;

function CurrentGame(type, bet, payout, gd) {
  this.type = type;
  this.bet = bet;
  this.scoredata = {};
  this.person = payout;
  this.gd = gd;
}

CurrentGame.prototype.start = function(cb) {
  if (this.type == "blackjack") {
    this.scoredata.deck = new Deck();
    this.scoredata.dealer_hand = [this.scoredata.deck.top(), this.scoredata.deck.top()];
    this.scoredata.player_hand = [this.scoredata.deck.top(), this.scoredata.deck.top()];
    cb("Dealer Hand: " + this.scoredata.dealer_hand[0] + ",??\nYour Hand: " + this.scoredata.player_hand.join(","));
  }
  return this.scoredata;
};

CurrentGame.prototype.run = function(params, cb) {
  if (this.type == "blackjack") {
    if (params[0] == "hit") {
      this.scoredata.player_hand.push(this.scoredata.deck.top());
      if (totalValue(this.scoredata.player_hand, false) >= 21) { //this calculation is false somehow
        this.finish(cb);
      } else {
        cb("Your hand is " + this.scoredata.player_hand.join(",") + ".");
      }
    } else if (params[0] == "stand") {
      this.finish(cb);
    }
  }
};

function betterNonBust(hand) {
  let x = totalValue(hand, true);
  let y = totalValue(hand, false);
  if (x > 21) return y;
  else return x;
}

CurrentGame.prototype.finish = function(cb) {
  if (this.type == "blackjack") {
    let dealer_going = dealerAction(this.scoredata.dealer_hand);
    while (dealer_going) {
      this.scoredata.dealer_hand.push(this.scoredata.deck.top());
      dealer_going = dealerAction(this.scoredata.dealer_hand);
    }
    let dbj = totalValue(this.scoredata.dealer_hand, true) == 21 || totalValue(this.scoredata.dealer_hand, false) === 21;
    let pbj = totalValue(this.scoredata.player_hand, true) == 21 || totalValue(this.scoredata.player_hand, false) === 21; //lol pbj
    if (dbj && pbj) {
      cb("It's a tie! Both blackjack.\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet);
      return;
    }
    if (pbj) {
      cb("Blackjack!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, parseInt(this.bet * 2.5));
      return;
    }
    if (dbj) {
      cb("You lose!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      return;
    }
    if (totalValue(this.scoredata.player_hand, false) > 21) {
      cb("You busted! Idiot!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      return;
    }
    if (totalValue(this.scoredata.dealer_hand, false) > 21) {
      cb("Dealer busted, you win!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet * 2);
      return;
    }
    if (betterNonBust(this.scoredata.dealer_hand) == betterNonBust(this.scoredata.player_hand)) {
      cb("It's a tie!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet);
      return;
    }
    if (betterNonBust(this.scoredata.dealer_hand) > betterNonBust(this.scoredata.player_hand)) {
      cb("Dealer wins!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      return;
    } else {
      cb("You win!\nDealer Hand: " + this.scoredata.dealer_hand.join(",") + "\nYour Hand: " + this.scoredata.player_hand.join(","));
      this.gd.pay(this.person, this.bet * 2);
    }
  }
};

function GameData(gamedata) {
  this.data = gamedata;
}

GameData.prototype.newPlayer = function(id, name) {
  let player = {
    id,
    credits: 100,
    last: Date.now(),
    name,
    currgame: null
  };
  this.data.players.push(player);
};

GameData.prototype.getBalOf = function(id) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      return this.data.players[i].credits;
    }
  }
  return "Not Found";
};

GameData.prototype.setBalOf = function(id, credits) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      this.data.players[i].credits = parseInt(credits);
    }
  }
};

GameData.prototype.pay = function(id, credits) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      this.data.players[i].credits += parseInt(credits);
    }
  }
};

GameData.prototype.playerExists = function(id) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      return true;
    }
  }
  return false;
};

GameData.prototype.getLeaderboard = function(leaderlength) {
  let ret = [this.data.players[0]];
  //I know this will fail if there is nothing in this.data.players but I don't care.
  for (let i = 1; i < this.data.players.length; i++) {
    for (let j = 0; j < ret.length; j++) {
      if (this.data.players[i].credits > ret[j].credits) {
        ret.splice(j, 0, this.data.players[i]);
        break;
      }
    }
  }
  let retar = "Leaderboard: \n";
  for (let i = 0; i < leaderlength; i++) {
    if (i >= ret.length) {
      break;
    }
    retar = retar + (i + 1) + ") " + ret[i].name + " " + ret[i].credits + " points" + "\n";
  }
  return retar;
};

GameData.prototype.dataToSave = function() {
  let tdata = {
    players: []
  };
  for (let i = 0; i < this.data.players.length; i++) {
    tdata.players.push({
      id: this.data.players[i].id,
      credits: this.data.players[i].credits,
      last: this.data.players[i].last,
      name: this.data.players[i].name
    })
  }
  return JSON.stringify(tdata);
};

GameData.prototype.startGame = function(id, type, bet, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id && this.data.players[i].credits > bet) {
      this.data.players[i].credits -= parseInt(bet + 0.9);
      this.data.players[i].currgame = new CurrentGame(type, bet, this.data.players[i].id, this);
      this.data.players[i].currgame.start((x) => {
        cb(this.data.players[i].name + "'s Game:\n" + x)
      });
    }
  }
};

GameData.prototype.moveGame = function(id, params, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id && this.data.players[i].currgame) {
      this.data.players[i].currgame.run(params, (x) => {
        cb(this.data.players[i].name + "'s Game:\n" + x)
      });
    }
  }
}

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

function getRandomFromList(list) {
  return list[getRandomInt(0, list.length)];
}

function millisToMinutes(t) {
  return parseInt(t/1000/60);
}

GameData.prototype.refill = function(id, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      if (this.data.players[i].last + (1000 * 60 * 60 * 4) > Date.now()) {
        cb("Cannot refill now, try again later. You need to wait 4 hours between refills.\nYou last got free coins " + millisToMinutes(Date.now() - this.data.players[i].last) + " minutes ago");
      } else {
        if (this.data.players[i].credits > 500) {
          cb("You don't need a refill now. Go coinflip it all away.");
        } else {
          let x = getRandomFromList([10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 40, 40, 80, 160]);
          cb("You just got a refill of " + x + "credits");
          this.data.players[i].credits += x;
          this.data.players[i].last = Date.now();
        }
      }
    }
  }
};

GameData.prototype.freefill = function(id, cb) {
  for (let i = 0; i < this.data.players.length; i++) {
    if (this.data.players[i].id == id) {
      this.data.players[i].last = 0;
    }
  }
};

module.exports = {
  GameData
};<|endoftext|>


<commit_before>var myLab = myLab || {};

(function (ns) {

  var stage;
  var canvas;

  var godzilla;

  var moveSpeedX;
  var minPosX;
  var maxPosX;

  // Init the stage
  var initStage = function (canvasId) {
    canvas = document.getElementById(canvasId);
    if (canvas) {
      stage = new createjs.Stage(canvas);
    }
  };

  // init  the application
  ns.init = function () {
    initStage('canvas-main');

    // create bg box
    var bg = new createjs.Bitmap('assets/TheLight-raw/background.png');
    stage.addChild(bg);

    // create sprite sheet
    var frameFrequency = 1;  // the bigger the 'slower'
    var baseUrl = 'assets/spaceGodzilla/';
    var spriteSheet = new createjs.SpriteSheet({
      images: [ baseUrl + 'walk_sprites.png' ],
      frames: [
        [ 137, 62, 59, 62, 0, 29, 62 ],
        [ 74, 65, 61, 58, 0, 30, 58 ],
        [ 71, 126, 66, 59, 0, 33, 59 ],
        [ 0, 126, 69, 61, 0, 34, 61 ],
        [ 0, 0, 74, 63, 0, 37, 63 ],
        [ 0, 65, 72, 59, 0, 36, 59 ],
        [ 76, 0, 62, 60, 0, 31, 60 ],
        [ 139, 126, 57, 62, 0, 28, 62 ]
      ],
      animations: {
        walk: [ 0, 7, true, frameFrequency ]
      }
    });

    godzilla = new createjs.BitmapAnimation(spriteSheet);
    godzilla.x = 120;
    godzilla.y = 100;

    minPosX = 30;
    maxPosX = canvas.width - 30;

    stage.addChild(godzilla);

    moveSpeedX = 50;  // pixel per second
    godzilla.gotoAndPlay('walk');

    // start the animation
    createjs.Ticker.setFPS(15);
    createjs.Ticker.addEventListener('tick', this.animate);
    createjs.Ticker.useRAF = true;
  };

  // handle the animation
  ns.animate = function (event) {
    // update position
    var newPos = godzilla.x + (moveSpeedX * event.delta * 0.001);

    // check new position
    if ((newPos >= maxPosX) || (newPos <=  minPosX)) {
      // change direction
      moveSpeedX *= -1;
    }
    godzilla.x = newPos;

    // draw stage
    stage.update();
  };

})(myLab);
<commit_msg>Flip the sprite using scaleX<commit_after>var myLab = myLab || {};

(function (ns) {

  var stage;
  var canvas;

  var godzilla;

  var moveSpeedX;
  var minPosX;
  var maxPosX;

  // Init the stage
  var initStage = function (canvasId) {
    canvas = document.getElementById(canvasId);
    if (canvas) {
      stage = new createjs.Stage(canvas);
    }
  };

  // init  the application
  ns.init = function () {
    initStage('canvas-main');

    // create bg box
    var bg = new createjs.Bitmap('assets/TheLight-raw/background.png');
    stage.addChild(bg);

    // create sprite sheet
    var frameFrequency = 1;  // the bigger the 'slower'
    var baseUrl = 'assets/spaceGodzilla/';
    var spriteSheet = new createjs.SpriteSheet({
      images: [ baseUrl + 'walk_sprites.png' ],
      frames: [
        [ 137, 62, 59, 62, 0, 29, 62 ],
        [ 74, 65, 61, 58, 0, 30, 58 ],
        [ 71, 126, 66, 59, 0, 33, 59 ],
        [ 0, 126, 69, 61, 0, 34, 61 ],
        [ 0, 0, 74, 63, 0, 37, 63 ],
        [ 0, 65, 72, 59, 0, 36, 59 ],
        [ 76, 0, 62, 60, 0, 31, 60 ],
        [ 139, 126, 57, 62, 0, 28, 62 ]
      ],
      animations: {
        walk: [ 0, 7, true, frameFrequency ]
      }
    });

    godzilla = new createjs.BitmapAnimation(spriteSheet);
    godzilla.x = 120;
    godzilla.y = 100;

    minPosX = 30;
    maxPosX = canvas.width - 30;

    stage.addChild(godzilla);

    moveSpeedX = 50;  // pixel per second
    godzilla.gotoAndPlay('walk');
    updateAnimation();

    // start the animation
    createjs.Ticker.setFPS(15);
    createjs.Ticker.addEventListener('tick', onTick);
    createjs.Ticker.useRAF = true;
  };

  // change the animation based on moving direction
  var updateAnimation = function () {
    if (moveSpeedX < 0) {
      // flip horizontal
      godzilla.scaleX = -1;
    } else {
      godzilla.scaleX = 1;
    }
  };

  // handle the animation
  var onTick = function (event) {
    // update position
    var newPos = godzilla.x + (moveSpeedX * event.delta * 0.001);

    // check new position
    if ((newPos >= maxPosX) || (newPos <=  minPosX)) {
      // change direction
      moveSpeedX *= -1;
      updateAnimation();
    }
    godzilla.x = newPos;

    // draw stage
    stage.update();
  };

})(myLab);
<|endoftext|>


<commit_before>import {ref, keyFieldRef} from '../util';
import {Collect, Aggregate, MultiExtent, Values} from '../transforms';
import {error, isArray, isObject, isString, toSet} from 'vega-util';

export var scaleTypes = toSet([
  'identity', 'ordinal', 'band', 'point', 'index',
  'linear', 'log', 'pow', 'sqrt', 'sequential', 'time', 'utc',
  'quantize', 'quantile', 'threshold'
]);

export function isOrdinal(type) {
  return type === 'ordinal'
    || type === 'band'
    || type === 'point'
    || type === 'index';
}

export default function(spec, scope) {
  var type = spec.type || 'linear',
      params, key;

  if (!scaleTypes.hasOwnProperty(type)) {
    error('Unrecognized scale type: ' + type);
  }

  params = {
    type:   type,
    domain: parseScaleDomain(spec, scope)
  };

  if (spec.range != null) {
    if (spec.bandSize != null) {
      error('Scale range and bandSize are mutually exclusive.');
    }
    params.range = parseScaleRange(spec, scope);
  }

  for (key in spec) {
    if (params[key] || key === 'name') continue;
    params[key] = parseLiteral(spec[key], scope);
  }

  scope.addScale(spec.name, params);
}

function parseLiteral(v, scope) {
  return !isObject(v) ? v
    : v.signal ? scope.signalRef(v.signal)
    : error('Unsupported object: ' + v);
}

// -- SCALE DOMAIN ----

function parseScaleDomain(spec, scope) {
  var domain = spec.domain;
  if (!domain) error('Missing scale domain');

  if (domain.signal) {
    return scope.signalRef(domain.signal);
  }

  return (isArray(domain) ? explicitDomain
    : domain.fields ? multipleDomain
    : singularDomain)(spec, scope);
}

function explicitDomain(spec, scope) {
  return spec.domain.map(function(v) {
    return parseLiteral(v, scope);
  });
}

function singularDomain(spec, scope) {
  var domain = spec.domain,
      data = scope.getData(domain.data);
  if (!data) error('Can not find data set: ' + domain.data);
  return isOrdinal(spec.type)
    ? data.valuesRef(domain.field, parseSort(domain.sort, false))
    : data.extentRef(domain.field);
}

function multipleDomain(spec, scope) {
  var method = isOrdinal(spec.type) ? oMultipleDomain : qMultipleDomain,
      data   = spec.domain.data,
      fields = spec.domain.fields.reduce(function(dom, d) {
        return dom.push(isString(d) ? {data: data, field:d} : d), dom;
      }, []);
  return method(spec, scope, fields);
}

function oMultipleDomain(spec, scope, fields) {
  var counts, a, c, v;

  // get value counts for each domain field
  counts = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) error('Can not find data set: ' + f.data);
    return data.countsRef(f.field);
  });

  // sum counts from all fields
  a = scope.add(Aggregate({
    groupby: keyFieldRef,
    ops:['sum'], fields: [scope.fieldRef('count')], as:['count'],
    pulse: counts
  }));

  // collect aggregate output
  c = scope.add(Collect({pulse: ref(a)}));

  // extract values for combined domain
  v = scope.add(Values({
    field: keyFieldRef,
    sort:  scope.sortRef(parseSort(spec.domain.sort, true)),
    pulse: ref(c)
  }));

  return ref(v);
}

function parseSort(sort, multidomain) {
  if (sort) {
    if (!sort.field && !sort.op) {
      if (isObject(sort)) sort.field = 'key';
      else sort = {field: 'key'};
    } else if (!sort.field && sort.op !== 'count') {
      error('No field provided for sort aggregate op: ' + sort.op);
    } else if (multidomain && sort.field) {
      error('Multiple domain scales can not sort by field.');
    } else if (multidomain && sort.op && sort.op !== 'count') {
      error('Multiple domain scales support op count only.');
    }
  }
  return sort;
}

function qMultipleDomain(spec, scope, fields) {
  // get extents for each domain field
  var extents = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) error('Can not find data set: ' + f.data);
    return data.extentRef(f.field);
  });

  // combine extents
  return ref(scope.add(MultiExtent({extents: extents})));
}

// -- SCALE RANGE -----

function parseScaleRange(spec, scope) {
  var range = spec.range,
      config = scope.config.range;

  if (range.signal) {
    return scope.signalRef(range.signal);
  } else if (isString(range)) {
    if (config && config.hasOwnProperty(range)) {
      range = config[range];
    } else {
      error('Unrecognized scale range value: ' + range);
    }
  } else if (!isArray(range)) {
    error('Unsupported range type: ' + range);
  }

  return range.map(function(v) {
    return parseLiteral(v, scope);
  });
}
<commit_msg>Update permissible scale domain.<commit_after>import {ref, keyFieldRef} from '../util';
import {Collect, Aggregate, MultiExtent, Values} from '../transforms';
import {error, isArray, isObject, isString, toSet} from 'vega-util';

export var scaleTypes = toSet([
  'identity', 'ordinal', 'band', 'point', 'index',
  'linear', 'log', 'pow', 'sqrt', 'sequential', 'time', 'utc',
  'quantize', 'quantile', 'threshold'
]);

export function isOrdinal(type) {
  return type === 'ordinal'
    || type === 'band'
    || type === 'point'
    || type === 'index';
}

export default function(spec, scope) {
  var type = spec.type || 'linear',
      params, key;

  if (!scaleTypes.hasOwnProperty(type)) {
    error('Unrecognized scale type: ' + type);
  }

  params = {
    type:   type,
    domain: parseScaleDomain(spec, scope)
  };

  if (spec.range != null) {
    if (spec.bandSize != null) {
      error('Scale range and bandSize are mutually exclusive.');
    }
    params.range = parseScaleRange(spec, scope);
  }

  for (key in spec) {
    if (params[key] || key === 'name') continue;
    params[key] = parseLiteral(spec[key], scope);
  }

  scope.addScale(spec.name, params);
}

function parseLiteral(v, scope) {
  return !isObject(v) ? v
    : v.signal ? scope.signalRef(v.signal)
    : error('Unsupported object: ' + v);
}

// -- SCALE DOMAIN ----

function parseScaleDomain(spec, scope) {
  var domain = spec.domain;
  if (!domain) return; // default domain

  if (domain.signal) {
    return scope.signalRef(domain.signal);
  }

  return (isArray(domain) ? explicitDomain
    : domain.fields ? multipleDomain
    : singularDomain)(spec, scope);
}

function explicitDomain(spec, scope) {
  return spec.domain.map(function(v) {
    return parseLiteral(v, scope);
  });
}

function singularDomain(spec, scope) {
  var domain = spec.domain,
      data = scope.getData(domain.data);
  if (!data) error('Can not find data set: ' + domain.data);
  return isOrdinal(spec.type)
    ? data.valuesRef(domain.field, parseSort(domain.sort, false))
    : data.extentRef(domain.field);
}

function multipleDomain(spec, scope) {
  var method = isOrdinal(spec.type) ? oMultipleDomain : qMultipleDomain,
      data   = spec.domain.data,
      fields = spec.domain.fields.reduce(function(dom, d) {
        return dom.push(isString(d) ? {data: data, field:d} : d), dom;
      }, []);
  return method(spec, scope, fields);
}

function oMultipleDomain(spec, scope, fields) {
  var counts, a, c, v;

  // get value counts for each domain field
  counts = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) error('Can not find data set: ' + f.data);
    return data.countsRef(f.field);
  });

  // sum counts from all fields
  a = scope.add(Aggregate({
    groupby: keyFieldRef,
    ops:['sum'], fields: [scope.fieldRef('count')], as:['count'],
    pulse: counts
  }));

  // collect aggregate output
  c = scope.add(Collect({pulse: ref(a)}));

  // extract values for combined domain
  v = scope.add(Values({
    field: keyFieldRef,
    sort:  scope.sortRef(parseSort(spec.domain.sort, true)),
    pulse: ref(c)
  }));

  return ref(v);
}

function parseSort(sort, multidomain) {
  if (sort) {
    if (!sort.field && !sort.op) {
      if (isObject(sort)) sort.field = 'key';
      else sort = {field: 'key'};
    } else if (!sort.field && sort.op !== 'count') {
      error('No field provided for sort aggregate op: ' + sort.op);
    } else if (multidomain && sort.field) {
      error('Multiple domain scales can not sort by field.');
    } else if (multidomain && sort.op && sort.op !== 'count') {
      error('Multiple domain scales support op count only.');
    }
  }
  return sort;
}

function qMultipleDomain(spec, scope, fields) {
  // get extents for each domain field
  var extents = fields.map(function(f) {
    var data = scope.getData(f.data);
    if (!data) error('Can not find data set: ' + f.data);
    return data.extentRef(f.field);
  });

  // combine extents
  return ref(scope.add(MultiExtent({extents: extents})));
}

// -- SCALE RANGE -----

function parseScaleRange(spec, scope) {
  var range = spec.range,
      config = scope.config.range;

  if (range.signal) {
    return scope.signalRef(range.signal);
  } else if (isString(range)) {
    if (config && config.hasOwnProperty(range)) {
      range = config[range];
    } else {
      error('Unrecognized scale range value: ' + range);
    }
  } else if (!isArray(range)) {
    error('Unsupported range type: ' + range);
  }

  return range.map(function(v) {
    return parseLiteral(v, scope);
  });
}
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var util = require('../util');
var Survey = require('../models/Survey');
var Response = require('../models/Response');
var __ = require('lodash');

exports.list = function list(req, res) {
  var query;
  if(req.user) {
    query = {
      users: req.user._id
    };
  }else {
    res.send(401);
    return;
  }

  Survey.find(query)
  .lean()
  .exec(function (error, surveys) {
    if (util.handleError(error, res)) { return; }
    res.send({ surveys: surveys });
  });
};

exports.get = function get(req, res) {
  var surveyId = req.params.surveyId;

  Survey.findOne({
    id: surveyId
  })
  .lean()
  .exec(function (error, survey) {
    if (util.handleError(error, res)) { return; }
    if (survey === null) {
      res.send(404);
    } else {
      Response.count({ survey: surveyId }).exec(function (error, count) {
        if (util.handleError(error, res)) { return; }
        survey.responseCount = count;
        Response.getBounds(surveyId, function (error, bounds) {
          if (util.handleError(error, res)) { return; }

          survey.responseBounds = bounds;
          res.send({ survey: survey });
        });
      });
    }
  });
};

exports.stats = function stats(req, res) {
  var surveyId = req.params.surveyId;

  Survey.findOne({
    id: surveyId
  })
  .lean()
  .exec(function (error, survey) {
    if (util.handleError(error, res)) { return; }
    if (survey === null) {
      res.send(404);
    } else {

      Response.find({ survey: surveyId }, function(error, responses){
        var stats = {};
        var i,
            key;

        for (i = 0; i < responses.length; i++) {
          var r = responses[i].responses;
          for (key in r) {
            if (__.has(r, key)) {
              var val = r[key];

              if(__.has(stats, key)) {
                if(__.has(stats[key], r[key])){
                  stats[key][val] += 1;
                }else {
                  stats[key][val] = 1;
                }
              }else {
                stats[key] = {};
                stats[key][val] = 1;
              }
            }
          }
        }

        // Calculate "no answer" responses
        var summer = function(memo, num) {
          return memo + num;
        };

        for (key in stats) {
          if(__.has(stats, key)) {
            var sum = __.reduce(stats[key], summer, 0);
            var remainder = responses.length - sum;

            stats[key]['no response'] = remainder;
          }
        }

        res.send({
          stats: stats
        });

      });
    }
  });
};

exports.post = function post(req, response) {
  var data = req.body.surveys;
  var output = [];
  var count = data.length;
  var itemError = null;

  for (var i = 0; i < data.length; i++) {
    data[i].users = [req.user._id];
  }

  Survey.create(data, function (error) {
    if (error) {
      itemError = error;
      if (error.name === 'ValidationError') {
        console.log(error);
        response.send(400, error);
      } else {
        response.send(500);
      }
      return;
    }

    var output = Array.prototype.slice.call(arguments, 1).map(function (doc) {
      return doc.toObject();
    });
    response.send(201, { surveys: output });
  });
};

exports.put = function put(req, response) {
  var surveyId = req.params.surveyId;
  var survey = req.body.survey;

  // Retrieve the valid users, which are not selected by default.
  Survey.findOne({ id: surveyId }, 'users', function (error, doc) {
    if (error) {
      console.log(error);
      response.send(500);
      return;
    }

    // No such survey found.
    if (doc === null) {
      response.send(404);
      return;
    }

    // If the current user doesn't own the survey, we can't save it.
    if (doc.users.indexOf(req.user._id) === -1) {
      response.send(403);
      return;
    }

    // Update the survey, asking MongoDB to return the updated document.
    Survey.findOneAndUpdate({ id: surveyId }, survey, function (error, updated) {
      if (error) {
        console.log(error);
        response.send(500);
        return;
      }

      response.send({ survey: updated.toObject() });
    });
  });
};

// Get the survey ID associated with a slug
// Not authenticated.
exports.getSlug = function getSlug(req, res) {
  Survey.findOne({
    slug: req.params.slug
  })
  .lean()
  .exec(function (error, survey) {
    if (util.handleError(error, res)) { return; }
    if (survey === null) {
      res.send(404);
    } else {
      res.send({ survey: survey.id });
    }
  });
};
<commit_msg>Add info log for survey creation<commit_after>/*jslint node: true */
'use strict';

var util = require('../util');
var Survey = require('../models/Survey');
var Response = require('../models/Response');
var __ = require('lodash');

exports.list = function list(req, res) {
  var query;
  if(req.user) {
    query = {
      users: req.user._id
    };
  }else {
    res.send(401);
    return;
  }

  Survey.find(query)
  .lean()
  .exec(function (error, surveys) {
    if (util.handleError(error, res)) { return; }
    res.send({ surveys: surveys });
  });
};

exports.get = function get(req, res) {
  var surveyId = req.params.surveyId;

  Survey.findOne({
    id: surveyId
  })
  .lean()
  .exec(function (error, survey) {
    if (util.handleError(error, res)) { return; }
    if (survey === null) {
      res.send(404);
    } else {
      Response.count({ survey: surveyId }).exec(function (error, count) {
        if (util.handleError(error, res)) { return; }
        survey.responseCount = count;
        Response.getBounds(surveyId, function (error, bounds) {
          if (util.handleError(error, res)) { return; }

          survey.responseBounds = bounds;
          res.send({ survey: survey });
        });
      });
    }
  });
};

exports.stats = function stats(req, res) {
  var surveyId = req.params.surveyId;

  Survey.findOne({
    id: surveyId
  })
  .lean()
  .exec(function (error, survey) {
    if (util.handleError(error, res)) { return; }
    if (survey === null) {
      res.send(404);
    } else {

      Response.find({ survey: surveyId }, function(error, responses){
        var stats = {};
        var i,
            key;

        for (i = 0; i < responses.length; i++) {
          var r = responses[i].responses;
          for (key in r) {
            if (__.has(r, key)) {
              var val = r[key];

              if(__.has(stats, key)) {
                if(__.has(stats[key], r[key])){
                  stats[key][val] += 1;
                }else {
                  stats[key][val] = 1;
                }
              }else {
                stats[key] = {};
                stats[key][val] = 1;
              }
            }
          }
        }

        // Calculate "no answer" responses
        var summer = function(memo, num) {
          return memo + num;
        };

        for (key in stats) {
          if(__.has(stats, key)) {
            var sum = __.reduce(stats[key], summer, 0);
            var remainder = responses.length - sum;

            stats[key]['no response'] = remainder;
          }
        }

        res.send({
          stats: stats
        });

      });
    }
  });
};

exports.post = function post(req, response) {
  var data = req.body.surveys;
  var output = [];
  var count = data.length;
  var itemError = null;

  for (var i = 0; i < data.length; i++) {
    data[i].users = [req.user._id];
  }

  Survey.create(data, function (error) {
    if (error) {
      itemError = error;
      if (error.name === 'ValidationError') {
        console.log(error);
        response.send(400, error);
      } else {
        response.send(500);
      }
      return;
    }

    var output = Array.prototype.slice.call(arguments, 1).map(function (doc) {
      return doc.toObject();
    });

    var name = req.user.name;
    var link =  'https://' + req.headers.host + '/#surveys/' + output[0].slug;
    console.info('INFO: Survey created. User: ' + name + '; Link: ' + link);
    response.send(201, { surveys: output });
  });
};

exports.put = function put(req, response) {
  var surveyId = req.params.surveyId;
  var survey = req.body.survey;

  // Retrieve the valid users, which are not selected by default.
  Survey.findOne({ id: surveyId }, 'users', function (error, doc) {
    if (error) {
      console.log(error);
      response.send(500);
      return;
    }

    // No such survey found.
    if (doc === null) {
      response.send(404);
      return;
    }

    // If the current user doesn't own the survey, we can't save it.
    if (doc.users.indexOf(req.user._id) === -1) {
      response.send(403);
      return;
    }

    // Update the survey, asking MongoDB to return the updated document.
    Survey.findOneAndUpdate({ id: surveyId }, survey, function (error, updated) {
      if (error) {
        console.log(error);
        response.send(500);
        return;
      }

      response.send({ survey: updated.toObject() });
    });
  });
};

// Get the survey ID associated with a slug
// Not authenticated.
exports.getSlug = function getSlug(req, res) {
  Survey.findOne({
    slug: req.params.slug
  })
  .lean()
  .exec(function (error, survey) {
    if (util.handleError(error, res)) { return; }
    if (survey === null) {
      res.send(404);
    } else {
      res.send({ survey: survey.id });
    }
  });
};
<|endoftext|>


<commit_before>    /**
 * Created by OscarEvertsson on 01/06/15.
 */
$(document).ready(function(){
    var KEYCODE_ESC = 27;

    //If someone presses escape closeModalPanel.
    $(document).on('keyup',function(e){
        if (e.keyCode === KEYCODE_ESC) {
            closeModalPanel();
        }
    });

    //Update
    window.showCalendarModalPanel = function(calendarEvent){
        $('#cover-screen-container').fadeIn(); //Fades in the background cover
        $('.calendar-modal-panel').fadeIn(); //Fades in the window
        $('#calendar-modal-panel-title').text(calendarEvent.title); //Sets the title of the event

        //Sets the location if there is one.
        if (typeof calendarEvent.location === "undefined") {
            $('#where-when-how-list').find('#where').text("Var? " + "...NollKIT har inte fyllt i något");
        } else {
            $('#where-when-how-list').find('#where').text("Var? " + calendarEvent.location);
        }

        //Sets the description if there is one.
        if (typeof calendarEvent.description === "undefined") {
            $('#where-when-how-list').find('#what').text("Vad? " + "...NollKIT har inte fyllt i något");
        } else {
            $('#where-when-how-list').find('#what').text("Vad? " + calendarEvent.description);
        }

        //Sets the time for the event.
        $('#where-when-how-list').find('#when').text(
            "När? " + calendarEvent.start.format("H:mm") + " - " + calendarEvent.end.format("Hit:mm"));

        //Sets the url
        $('#where-when-how-list').find('#event-url').attr('href',calendarEvent.url);
        changeModalPanelAccordingToSize();
    };

    //If for instance you want to change the model panel size to 40% width and 60% height call setCalendarModalPanelSize(40,60)
    setCalendarModalPanelSize = function(width,height){
        var windowWidth = $(window).width();
        var windowHeight = $(window).height();
        //Changes the width and the height of the modal panel to the given percent.
        var widthInPercent = (windowWidth * width)/windowWidth;
        var heightInPercent = (windowHeight * height)/windowHeight;

        var howMuchFromLeft = (100 - widthInPercent)/2;
        var howMuchFromTop = (100 - heightInPercent)/2;

        //Sets the calculated values and ads the % to it
        $('.calendar-modal-panel').css({'width':widthInPercent + '%','height':heightInPercent + '%',
        'top':howMuchFromTop + '%','left':howMuchFromLeft + '%'});
    }

    //Closes the modal panel and removes the background dimmer.
    var closeModalPanel = function(){
        $('#cover-screen-container').fadeOut();
        $('.calendar-modal-panel').fadeOut();
    }

    //Close modal panel
    $('#calendar-close-modal-panel').on("click",function(){
        closeModalPanel();
    });

    var changeModalPanelAccordingToSize = function(){
        if ($(window).width() <= 660) {
            setCalendarModalPanelSize(95,70);
        } else if ($(window).width() <= 960) {
            setCalendarModalPanelSize(60,40);
        } else {
            setCalendarModalPanelSize(40,60);
        }
    }

    $(window).resize(function(){
        changeModalPanelAccordingToSize();
    });

    //On startup
    changeModalPanelAccordingToSize();

});<commit_msg>Fixed typo<commit_after>    /**
 * Created by OscarEvertsson on 01/06/15.
 */
$(document).ready(function(){
    var KEYCODE_ESC = 27;

    //If someone presses escape closeModalPanel.
    $(document).on('keyup',function(e){
        if (e.keyCode === KEYCODE_ESC) {
            closeModalPanel();
        }
    });

    //Update
    window.showCalendarModalPanel = function(calendarEvent){
        $('#cover-screen-container').fadeIn(); //Fades in the background cover
        $('.calendar-modal-panel').fadeIn(); //Fades in the window
        $('#calendar-modal-panel-title').text(calendarEvent.title); //Sets the title of the event

        //Sets the location if there is one.
        if (typeof calendarEvent.location === "undefined") {
            $('#where-when-how-list').find('#where').text("Var? " + "...NollKIT har inte fyllt i något");
        } else {
            $('#where-when-how-list').find('#where').text("Var? " + calendarEvent.location);
        }

        //Sets the description if there is one.
        if (typeof calendarEvent.description === "undefined") {
            $('#where-when-how-list').find('#what').text("Vad? " + "...NollKIT har inte fyllt i något");
        } else {
            $('#where-when-how-list').find('#what').text("Vad? " + calendarEvent.description);
        }

        //Sets the time for the event.
        $('#where-when-how-list').find('#when').text(
            "När? " + calendarEvent.start.format("H:mm") + " - " + calendarEvent.end.format("H:mm"));

        //Sets the url
        $('#where-when-how-list').find('#event-url').attr('href',calendarEvent.url);
        changeModalPanelAccordingToSize();
    };

    //If for instance you want to change the model panel size to 40% width and 60% height call setCalendarModalPanelSize(40,60)
    setCalendarModalPanelSize = function(width,height){
        var windowWidth = $(window).width();
        var windowHeight = $(window).height();
        //Changes the width and the height of the modal panel to the given percent.
        var widthInPercent = (windowWidth * width)/windowWidth;
        var heightInPercent = (windowHeight * height)/windowHeight;

        var howMuchFromLeft = (100 - widthInPercent)/2;
        var howMuchFromTop = (100 - heightInPercent)/2;

        //Sets the calculated values and ads the % to it
        $('.calendar-modal-panel').css({'width':widthInPercent + '%','height':heightInPercent + '%',
        'top':howMuchFromTop + '%','left':howMuchFromLeft + '%'});
    }

    //Closes the modal panel and removes the background dimmer.
    var closeModalPanel = function(){
        $('#cover-screen-container').fadeOut();
        $('.calendar-modal-panel').fadeOut();
    }

    //Close modal panel
    $('#calendar-close-modal-panel').on("click",function(){
        closeModalPanel();
    });

    var changeModalPanelAccordingToSize = function(){
        if ($(window).width() <= 660) {
            setCalendarModalPanelSize(95,70);
        } else if ($(window).width() <= 960) {
            setCalendarModalPanelSize(60,40);
        } else {
            setCalendarModalPanelSize(40,60);
        }
    }

    $(window).resize(function(){
        changeModalPanelAccordingToSize();
    });

    //On startup
    changeModalPanelAccordingToSize();

});<|endoftext|>