<commit_before>'use strict';

/* global mapboxgl */
/* eslint-disable no-loop-func */
mapboxgl.accessToken = process.env.MapboxAccessToken;

var fs = require('fs');
var path = require('path');

var template = require('lodash.template');
var groupBy = require('lodash.groupby');
var Circle = require('./circle');

// Set bounds to Philadelphia
var center = [-75.1759, 39.9361];
var bounds = [
  [-75.63195500381617, 39.76055866429846], // Southwest coordinates
  [-74.6075343956525, 40.122534817620846] // Northeast coordinates
];

// Templates
var listingTemplate = template(fs.readFileSync(path.join(__dirname, '/templates/listing.html'), 'utf8'));

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/dark-v8',
  center: center,
  maxBounds: bounds,
  minZoom: 13,
  maxZoom: 19,
  zoom: 15
});

var $radius = document.getElementById('radius');
var $radiusValue = document.getElementById('radius-value');
var $filterGroup = document.getElementById('filter-group');
var $listings = document.getElementById('listings');
var $listingsHeader = document.getElementById('listings-header');

var radius = 100;
var position = map.project(center);
var error;
var categories = [];

var circle = new Circle(map.getContainer(), {
  radius: radius,
  position: position,
  fill: '#3887be',
  fillRadius: 'rgba(82, 161, 216, 0.25)'
});

circle.draw().enable();

var popup = new mapboxgl.Popup({
  closeButton: false
});

var geojson = {
  type: 'FeatureCollection',
  features: []
};

var layers = [
  [0, '#27b691', 'Residential'],
  [1, '#ed5299', 'Commecial'],
  [2, '#484896', 'Hotels & Apartments'],
  [3, '#ec3649', 'Store with dwelling'],
  [4, '#f06f42', 'Vacant land'],
  [5, '#f6d845', 'Industrial']
];

function loading(state) {
  document.getElementById('sidebar').classList.toggle('loading', state);
}

function emitError(msg) {
  loading(false);
  window.clearTimeout(error);
  var $error = document.getElementById('error');

  $error.classList.add('pad1', 'active');
  $error.textContent = msg;

  // Emit error for 3 seconds.
  error = window.setTimeout(function() {
    $error.classList.remove('pad1', 'active');
    $error.textContent = '';
  }, 3000);
}

function initialize() {
  document.body.classList.remove('loading');

  map.addSource('philly', {
    type: 'vector',
    url: 'mapbox://tristen.2so304hr'
  });

  map.addLayer({
    id: 'philly',
    type: 'circle',
    source: 'philly',
    interactive: true,
    'source-layer': 'original',
    paint: {
      'circle-color': 'rgba(0,0,0,0)',
      'circle-radius': 0
    }
  });

  map.addSource('within', {
    type: 'geojson',
    data: geojson
  });

  layers.forEach(function(layer, i) {
    var layerID = 'poi-' + i;
    map.addLayer({
      id: layerID,
      interactive: true,
      type: 'circle',
      source: 'within',
      paint: {
        'circle-color': layer[1],
        'circle-radius': {
          base: 1,
          stops: [[13, 1], [15, 1.5], [17, 3]]
        }
      },
      filter: ['==', 'category', layer[0]]

    }, 'place_label_city_small_s');

    var input = document.createElement('input');
    input.type = 'checkbox';
    input.id = layerID;
    input.checked = true;
    $filterGroup.appendChild(input);

    var label = document.createElement('label');
    label.className = 'button col12';
    label.setAttribute('for', layerID);
    label.textContent = layer[2];

    var labelKey = document.createElement('span');
    labelKey.style.backgroundColor = layer[1];

    label.appendChild(labelKey);
    $filterGroup.appendChild(label);

    // When the checkbox changes, update the visibility of the layer.
    input.addEventListener('change', function(e) {
      if (e.target.checked && categories.indexOf(i) >= 0) {
        categories.splice(categories.indexOf(i), 1);
      } else {
        categories.push(i);
      }

      map.setLayoutProperty(layerID, 'visibility', e.target.checked ? 'visible' : 'none');
      buildListings(geojson.features);
    });
  });

  $radius.querySelector('input').value = radius;
  $radiusValue.textContent = radius;
}

map.on('source.load', function(e) {
  if (e.source.id === 'philly') window.setTimeout(redraw, 1000);
});

function buildListings(listings) {
  if (categories.length) {
    listings = listings.filter(function(d) {
      return categories.indexOf(d.properties.category) === -1;
    });
  }

  listings = groupBy(listings, function(d) {
    return d.properties.category;
  });

  for (var prop in listings) {

    var section = document.createElement('div');
    section.className = 'keyline-bottom listing-group';

    section.setAttribute('data-properties', listings[prop].length);
    layers.forEach(function(l) {
      if (l[0] === parseInt(prop, 10)) {
        section.setAttribute('data-fill', l[1]);
        section.setAttribute('data-category', l[2]);
      }
    });

    if (prop === Object.keys(listings)[0]) sectionHeading(section);

    listings[prop].forEach(function(feature) {
      layers.forEach(function(l) {
        if (l[0] === feature.properties.category) feature.fill = l[1];
      });

      var item = document.createElement('div');
      item.innerHTML = listingTemplate(feature);
      section.appendChild(item);

      /*
      item.querySelector('button').addEventListener('click', function(e) {
        var elements = $listings.querySelectorAll('button');

        Array.prototype.forEach.call(elements, function(el) {
          el.classList.remove('active');
        });

        e.target.classList.add('active');
        featureSelection(feature);
      });

      item.querySelector('button').addEventListener('mouseover', function() {
        featureHover(feature);
      });
      */

    });

    $listings.appendChild(section);
    loading(false);
  }
}

function redraw(e) {
  loading(true);
  $listings.innerHTML = '';
  map.dragPan.enable();
  if (e && e.end) position = e.end;
  map.featuresAt(position, {
    radius: radius,
    includeGeometry: true,
    layer: ['philly']
  }, function(err, features) {
    if (err) return emitError(err.message);
    if (!features.length) return emitError('No properties found');
    var listings = geojson.features = features;
    map.getSource('within').setData(geojson);
    buildListings(listings);
  });
}

circle.on('result', redraw);

/*
map.on('mousemove', function(e) {
  map.featuresAt(e.point, {
    radius: 2.5, // half the marker size (5px).
    includeGeometry: true,
    layer: layers.map(function(layer, i) {
      return 'poi-' + i;
    })
  }, function(err, features) {
    map.getCanvas().style.cursor = (!err && features.length) ? 'pointer' : '';

    if (err || !features.length) {
      popup.remove();
      return;
    }

    var feature = features[0];
    var p = feature.properties;
    var popupContainer = document.createElement('div');

    var items = [
      ['Address', p.address],
      ['Category', layers[p.category][2]],
      ['Price', p.price]
    ];

    if (p.stories) items.push(['Stories', p.stories]);
    if (p.rooms) items.push(['Rooms', p.rooms]);
    if (p.bedrooms) items.push(['Bedrooms', p.bedrooms]);
    if (p.bathrooms) items.push(['Bathrooms', p.bathrooms]);

    items.forEach(function(d) {
      var item = document.createElement('div');
      var label = document.createElement('strong');
      label.className = 'space-right0';
      label.textContent = d[0];

      var value = document.createElement('div');
      value.className = 'inline capitalize';
      value.textContent = d[1];

      item.appendChild(label);
      item.appendChild(value);
      popupContainer.appendChild(item);
    });

    // Initialize a popup and set its coordinates
    // based on the feature found.
    popup.setLngLat(feature.geometry.coordinates)
      .setHTML(popupContainer.innerHTML)
      .addTo(map);
  });
});
*/

// Radius changer
$radius.querySelector('input').addEventListener('input', function(e) {
  $radiusValue.textContent = e.target.value;
  radius = e.target.value;
  circle.setRadius(radius);
});

$radius.querySelector('input').addEventListener('change', redraw);

// Changing section header on scroll
// depending on section currently in view.
function offset(el) {
  var rect = el.getBoundingClientRect();
  return {
    top: rect.top + document.body.scrollTop,
    left: rect.left + document.body.scrollLeft
  };
}

function sectionHeading(section) {
  var properties = section.getAttribute('data-properties');
  var category = section.getAttribute('data-category');
  var fill = section.getAttribute('data-fill');

  var title = document.createElement('strong');
  title.className = 'small space-right0';
  title.textContent = category;

  var sub = document.createElement('span');
  sub.className = 'quiet small';
  sub.textContent = properties + ' properties';

  $listingsHeader.innerHTML = '';
  $listingsHeader.style.backgroundColor = fill;
  $listingsHeader.appendChild(title);
  $listingsHeader.appendChild(sub);
}

var sectionHeadingPosition = offset($listingsHeader);
var currentCategory;

$listings.addEventListener('scroll', function() {
  var sections = $listings.querySelectorAll('.listing-group');
  Array.prototype.forEach.call(sections, function(el, i, d) {
    var next = d[i + 1];
    if (next) {
      if (sectionHeadingPosition.top >= offset(el).top &&
         sectionHeadingPosition.top <= offset(next).top) {
        var category = el.getAttribute('data-category');
        if (category !== currentCategory) {
          sectionHeading(el);
          currentCategory = category;
        }
        return;
      }
    }
  });
});

map.on('load', initialize);
<commit_msg>Group headings too<commit_after>'use strict';

/* global mapboxgl */
/* eslint-disable no-loop-func */
mapboxgl.accessToken = process.env.MapboxAccessToken;

var fs = require('fs');
var path = require('path');

var template = require('lodash.template');
var groupBy = require('lodash.groupby');
var Circle = require('./circle');

// Set bounds to Philadelphia
var center = [-75.1759, 39.9361];
var bounds = [
  [-75.63195500381617, 39.76055866429846], // Southwest coordinates
  [-74.6075343956525, 40.122534817620846] // Northeast coordinates
];

// Templates
var listingTemplate = template(fs.readFileSync(path.join(__dirname, '/templates/listing.html'), 'utf8'));

var map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/dark-v8',
  center: center,
  maxBounds: bounds,
  minZoom: 13,
  maxZoom: 19,
  zoom: 15
});

var $radius = document.getElementById('radius');
var $radiusValue = document.getElementById('radius-value');
var $filterGroup = document.getElementById('filter-group');
var $listings = document.getElementById('listings');
var $listingsHeader = document.getElementById('listings-header');

var radius = 100;
var position = map.project(center);
var error;
var categories = [];

var circle = new Circle(map.getContainer(), {
  radius: radius,
  position: position,
  fill: '#3887be',
  fillRadius: 'rgba(82, 161, 216, 0.25)'
});

circle.draw().enable();

var popup = new mapboxgl.Popup({
  closeButton: false
});

var geojson = {
  type: 'FeatureCollection',
  features: []
};

var layers = [
  [0, '#27b691', 'Residential'],
  [1, '#ed5299', 'Commecial'],
  [2, '#484896', 'Hotels & Apartments'],
  [3, '#ec3649', 'Store with dwelling'],
  [4, '#f06f42', 'Vacant land'],
  [5, '#f6d845', 'Industrial']
];

function loading(state) {
  document.getElementById('sidebar').classList.toggle('loading', state);
}

function emitError(msg) {
  loading(false);
  window.clearTimeout(error);
  var $error = document.getElementById('error');

  $error.classList.add('pad1', 'active');
  $error.textContent = msg;

  // Emit error for 3 seconds.
  error = window.setTimeout(function() {
    $error.classList.remove('pad1', 'active');
    $error.textContent = '';
  }, 3000);
}

function initialize() {
  document.body.classList.remove('loading');

  map.addSource('philly', {
    type: 'vector',
    url: 'mapbox://tristen.2so304hr'
  });

  map.addLayer({
    id: 'philly',
    type: 'circle',
    source: 'philly',
    interactive: true,
    'source-layer': 'original',
    paint: {
      'circle-color': 'rgba(0,0,0,0)',
      'circle-radius': 0
    }
  });

  map.addSource('within', {
    type: 'geojson',
    data: geojson
  });

  layers.forEach(function(layer, i) {
    var layerID = 'poi-' + i;
    map.addLayer({
      id: layerID,
      interactive: true,
      type: 'circle',
      source: 'within',
      paint: {
        'circle-color': layer[1],
        'circle-radius': {
          base: 1,
          stops: [[13, 1], [15, 1.5], [17, 3]]
        }
      },
      filter: ['==', 'category', layer[0]]

    }, 'place_label_city_small_s');

    var input = document.createElement('input');
    input.type = 'checkbox';
    input.id = layerID;
    input.checked = true;
    $filterGroup.appendChild(input);

    var label = document.createElement('label');
    label.className = 'button col12';
    label.setAttribute('for', layerID);
    label.textContent = layer[2];

    var labelKey = document.createElement('span');
    labelKey.style.backgroundColor = layer[1];

    label.appendChild(labelKey);
    $filterGroup.appendChild(label);

    // When the checkbox changes, update the visibility of the layer.
    input.addEventListener('change', function(e) {
      if (e.target.checked && categories.indexOf(i) >= 0) {
        categories.splice(categories.indexOf(i), 1);
      } else {
        categories.push(i);
      }

      map.setLayoutProperty(layerID, 'visibility', e.target.checked ? 'visible' : 'none');
      buildListings(geojson.features);
    });
  });

  $radius.querySelector('input').value = radius;
  $radiusValue.textContent = radius;
}

map.on('source.load', function(e) {
  if (e.source.id === 'philly') window.setTimeout(redraw, 1000);
});

function buildListings(listings) {
  $listings.innerHTML = '';

  if (categories.length) {
    listings = listings.filter(function(d) {
      return categories.indexOf(d.properties.category) === -1;
    });
  }

  listings = groupBy(listings, function(d) {
    return d.properties.category;
  });

  for (var prop in listings) {

    var section = document.createElement('div');
    section.className = 'keyline-bottom listing-group';

    section.setAttribute('data-properties', listings[prop].length);
    layers.forEach(function(l) {
      if (l[0] === parseInt(prop, 10)) {
        section.setAttribute('data-fill', l[1]);
        section.setAttribute('data-category', l[2]);
      }
    });

    if (prop === Object.keys(listings)[0]) {
      buildHeader($listingsHeader, section);
    } else {
      var header = document.createElement('header');
      header.className = 'pad2x pad1y';
      buildHeader(header, section);
      section.appendChild(header);
    }

    listings[prop].forEach(function(feature) {
      layers.forEach(function(l) {
        if (l[0] === feature.properties.category) feature.fill = l[1];
      });

      var item = document.createElement('div');
      item.innerHTML = listingTemplate(feature);
      section.appendChild(item);

      /*
      item.querySelector('button').addEventListener('click', function(e) {
        var elements = $listings.querySelectorAll('button');

        Array.prototype.forEach.call(elements, function(el) {
          el.classList.remove('active');
        });

        e.target.classList.add('active');
        featureSelection(feature);
      });

      item.querySelector('button').addEventListener('mouseover', function() {
        featureHover(feature);
      });
      */

    });

    $listings.appendChild(section);
    loading(false);
  }
}

function buildHeader(container, section) {
  var properties = section.getAttribute('data-properties');
  var category = section.getAttribute('data-category');
  var fill = section.getAttribute('data-fill');

  var title = document.createElement('strong');
  title.className = 'small space-right0';
  title.textContent = category;

  var sub = document.createElement('span');
  sub.className = 'quiet small';
  sub.textContent = properties + ' properties';

  container.innerHTML = '';
  container.style.backgroundColor = fill;
  container.appendChild(title);
  container.appendChild(sub);
}

function redraw(e) {
  loading(true);
  $listings.innerHTML = '';
  map.dragPan.enable();
  if (e && e.end) position = e.end;
  map.featuresAt(position, {
    radius: radius,
    includeGeometry: true,
    layer: ['philly']
  }, function(err, features) {
    if (err) return emitError(err.message);
    if (!features.length) return emitError('No properties found');
    var listings = geojson.features = features;
    map.getSource('within').setData(geojson);
    buildListings(listings);
  });
}

circle.on('result', redraw);

/*
map.on('mousemove', function(e) {
  map.featuresAt(e.point, {
    radius: 2.5, // half the marker size (5px).
    includeGeometry: true,
    layer: layers.map(function(layer, i) {
      return 'poi-' + i;
    })
  }, function(err, features) {
    map.getCanvas().style.cursor = (!err && features.length) ? 'pointer' : '';

    if (err || !features.length) {
      popup.remove();
      return;
    }

    var feature = features[0];
    var p = feature.properties;
    var popupContainer = document.createElement('div');

    var items = [
      ['Address', p.address],
      ['Category', layers[p.category][2]],
      ['Price', p.price]
    ];

    if (p.stories) items.push(['Stories', p.stories]);
    if (p.rooms) items.push(['Rooms', p.rooms]);
    if (p.bedrooms) items.push(['Bedrooms', p.bedrooms]);
    if (p.bathrooms) items.push(['Bathrooms', p.bathrooms]);

    items.forEach(function(d) {
      var item = document.createElement('div');
      var label = document.createElement('strong');
      label.className = 'space-right0';
      label.textContent = d[0];

      var value = document.createElement('div');
      value.className = 'inline capitalize';
      value.textContent = d[1];

      item.appendChild(label);
      item.appendChild(value);
      popupContainer.appendChild(item);
    });

    // Initialize a popup and set its coordinates
    // based on the feature found.
    popup.setLngLat(feature.geometry.coordinates)
      .setHTML(popupContainer.innerHTML)
      .addTo(map);
  });
});
*/

// Radius changer
$radius.querySelector('input').addEventListener('input', function(e) {
  $radiusValue.textContent = e.target.value;
  radius = e.target.value;
  circle.setRadius(radius);
});

$radius.querySelector('input').addEventListener('change', redraw);

// Changing section header on scroll
// depending on section currently in view.
function offset(el) {
  var rect = el.getBoundingClientRect();
  return {
    top: rect.top + document.body.scrollTop,
    left: rect.left + document.body.scrollLeft
  };
}

var sectionHeadingPosition = offset($listingsHeader);
var currentCategory;

$listings.addEventListener('scroll', function() {
  var sections = $listings.querySelectorAll('.listing-group');
  Array.prototype.forEach.call(sections, function(el, i, d) {
    var next = d[i + 1];
    if (next) {
      if (sectionHeadingPosition.top >= offset(el).top &&
         sectionHeadingPosition.top <= offset(next).top) {
        var category = el.getAttribute('data-category');
        if (category !== currentCategory) {
          buildHeader($listingsHeader, el);
          currentCategory = category;
        }
        return;
      }
    }
  });
});

map.on('load', initialize);
<|endoftext|>


<commit_before>var db = require('../db');

console.log("Updating managers...");
db.dropManagers();

var callback = function(err, managerSaved){ if (err) { console.log("error occurred inserting manager");}};

//db.addManager(name, position, meetingTime, meetingPlace, email, showName, showTime, photo, callback)
db.addManager("Zach Seidl", "General Manager", "Mon 6-8PM, Wed 5-7PM", "The Station", "gm@uclaradio.com", "102.HEAVEN", "Mon 2-3PM", "/img/Managers/zachseidl.jpg", callback);
db.addManager("Tyler Wennstrom", "Asst. General Manager", "Tues 3:30PM-5:00PM", "The Station", "agm@media.ucla.edu", "N/A", "N/A", "/img/Managers/tylerwennstrom.JPG", callback);
db.addManager("Carla Rowley", "Intern Manager", "Wed 2-3PM", "The Station", "rowleycarla@ucla.edu", "show", "show time", "/img/Managers/carlarowley.JPG", callback);
db.addManager("Alex Torpey", "Intern Manager", "Wed 2-3PM", "The Station", "uclaradio.interns@gmail.com", "The Discourse", "Wed 1-2PM", "/img/Managers/alextorpey.jpg", callback);
db.addManager("Pamela Crick", "Promotions Manager", "Thurs 6-7PM", "The Station", "radio.promotions@media.ucla.edu", "Avocado Club", "Wed 8-9PM", "/img/Managers/pamelacrick.jpg", callback);
db.addManager("Taylor Whelchel", "Marketing Manager", "TBA", "TBA", "radio.marketing@media.ucla.edu", "N/A", "N/A", "/img/Managers/taylorwhelchel.jpg", callback);
db.addManager("Eva Maria Pino", "Music Manager", "Thurs 7-8 PM", "The Station", "radio.music@media.ucla.edu", "Who's That?", "Tues 2-3PM", "/img/Managers/evapino.jpg", callback);
db.addManager("Angela Nguyen", "Music Manager", "Thurs 7-8 PM", "The Station", "radio.music@media.ucla.edu", "The Conventional Unknown", "Thurs 10-11PM", "/img/Managers/angelanguyen.jpg", callback);
db.addManager("Matteo Vesprini-Heidrich", "Web Manager", "Wed 1-2PM", "The Station", "uclaradio.web@gmail.com", "Sleep Sounds", "Wed 10-11PM", "/img/Managers/matteo.jpg", callback);
db.addManager("Regan Hsu", "Web Manager", "Wed 1-2PM", "The Station", "uclaradio.web@gmail.com", "N/A", "N/A", "/img/Managers/reganhsu.jpg", callback);
db.addManager("Eddie Hernandez", "Digital Press Manager", "Tues 6-7PM", "The Station", "radio.digitalpress@media.ucla.edu", "Sleep Sounds", "Wed 10-11PM", "/img/Managers/eddiehernandez.JPG", callback);
db.addManager("Eric Aberbook", "Digital Press Manager", "Tues 6-7PM", "The Station", "radio.digitalpress@media.ucla.edu", "N/A", "N/A", "/img/Managers/ericaberbook.jpg", callback);
db.addManager("Gabe Brenner", "Art + Design Manager", "Thurs 5:30-6:30PM", "The Station", "radio.artanddesign@media.ucla.edu", "N/A", "N/A", "/img/Managers/gabebrenner.png", callback);
db.addManager("Gee Leonardo", "Photo / Video Manager", "Thurs 6:15-8PM", "The Station", "photoandvideo@uclaradio.com", "N/A", "N/A", "/img/Managers/gleonardo.png", callback);
db.addManager("Scott Gee", "Events Manager", "Tues 5-6PM", "The Station", "radio.events@media.ucla.edu", "Few Things Considered", "Fri 8-9PM",  "/img/Managers/scottgee.jpg", callback);
db.addManager("Casey John Leonard", "News Manager", "Wed 5-6PM", "The Station", "cj.leonard@hotmail.com", "News Hour; In Conversation; Weekend Edition", "Mon & Thurs 5-6PM; Tues 1-2 PM; Sun 4-5 PM",  "/img/Managers/caseyleonard.jpg", callback);
db.addManager("Willow Stowe", "Programming Manager", "Tues 5:30-6:30PM (week 3, 4 & 6)", "The Station", "radio.programming@media.ucla.edu", "Coffee Talk", "Sun 6-7 PM", "/img/Managers/willowstowe.jpg", callback);
db.addManager("Gracie Phillips", "Programming Manager", "Tues 5:30-6:30PM (week 3, 4 & 6)", "The Station", "radio.programming@media.ucla.edu", "The Mighty Schwa", "Sun 11AM-12PM", "/img/Managers/graciephillips.jpg", callback);
db.addManager("Kim Seltzer", "Comedy Manager", "Wed 2-2:30PM (even weeks)", "The Station", "uclaradio.comedy@media.ucla.edu", "Free Time", "Tues 6PM", "/img/Managers/kimseltzer.jpg", callback);
db.addManager("Aliya Kamalova", "Comedy Manager", "Wed 2-2:30PM (even weeks)", "The Station", "uclaradio.comedy@media.ucla.edu", "Free Time", "Tues 6PM", "/img/Managers/aliyakamalova.jpg", callback);
db.addManager("Nicolo Scolieri", "Productions Manager", "Thurs 6:15-6:45PM", "The Station", "radio.productions@media.ucla.edu", "Where In The World Is Carmen San Diego?", "Sat 11AM-12PM", "/img/Managers/nicoloscolieri.png", callback);
db.addManager("Darryn Albert", "Sports Manager", "Fri 3-4PM", "The Station", "dnalbert@ucla.edu", "N/A", "N/A", "/img/Managers/darrynalbert.JPG", callback);
db.addManager("Desiree Samler", "Fundraising Manager", "Wed 5-6PM", "The Station", "radio.fundraising@media.ucla.edu", "The Brunch Special", "Wed 2-3PM", "/img/Managers/desireesamler.png", callback);

console.log("Finished updating managers");<commit_msg>fix file type<commit_after>var db = require('../db');

console.log("Updating managers...");
db.dropManagers();

var callback = function(err, managerSaved){ if (err) { console.log("error occurred inserting manager");}};

//db.addManager(name, position, meetingTime, meetingPlace, email, showName, showTime, photo, callback)
db.addManager("Zach Seidl", "General Manager", "Mon 6-8PM, Wed 5-7PM", "The Station", "gm@uclaradio.com", "102.HEAVEN", "Mon 2-3PM", "/img/Managers/zachseidl.jpg", callback);
db.addManager("Tyler Wennstrom", "Asst. General Manager", "Tues 3:30PM-5:00PM", "The Station", "agm@media.ucla.edu", "N/A", "N/A", "/img/Managers/tylerwennstrom.JPG", callback);
db.addManager("Carla Rowley", "Intern Manager", "Wed 2-3PM", "The Station", "rowleycarla@ucla.edu", "show", "show time", "/img/Managers/carlarowley.JPG", callback);
db.addManager("Alex Torpey", "Intern Manager", "Wed 2-3PM", "The Station", "uclaradio.interns@gmail.com", "The Discourse", "Wed 1-2PM", "/img/Managers/alextorpey.jpg", callback);
db.addManager("Pamela Crick", "Promotions Manager", "Thurs 6-7PM", "The Station", "radio.promotions@media.ucla.edu", "Avocado Club", "Wed 8-9PM", "/img/Managers/pamelacrick.jpg", callback);
db.addManager("Taylor Whelchel", "Marketing Manager", "TBA", "TBA", "radio.marketing@media.ucla.edu", "N/A", "N/A", "/img/Managers/taylorwhelchel.jpg", callback);
db.addManager("Eva Maria Pino", "Music Manager", "Thurs 7-8 PM", "The Station", "radio.music@media.ucla.edu", "Who's That?", "Tues 2-3PM", "/img/Managers/evapino.jpg", callback);
db.addManager("Angela Nguyen", "Music Manager", "Thurs 7-8 PM", "The Station", "radio.music@media.ucla.edu", "The Conventional Unknown", "Thurs 10-11PM", "/img/Managers/angelanguyen.png", callback);
db.addManager("Matteo Vesprini-Heidrich", "Web Manager", "Wed 1-2PM", "The Station", "uclaradio.web@gmail.com", "Sleep Sounds", "Wed 10-11PM", "/img/Managers/matteo.jpg", callback);
db.addManager("Regan Hsu", "Web Manager", "Wed 1-2PM", "The Station", "uclaradio.web@gmail.com", "N/A", "N/A", "/img/Managers/reganhsu.jpg", callback);
db.addManager("Eddie Hernandez", "Digital Press Manager", "Tues 6-7PM", "The Station", "radio.digitalpress@media.ucla.edu", "Sleep Sounds", "Wed 10-11PM", "/img/Managers/eddiehernandez.JPG", callback);
db.addManager("Eric Aberbook", "Digital Press Manager", "Tues 6-7PM", "The Station", "radio.digitalpress@media.ucla.edu", "N/A", "N/A", "/img/Managers/ericaberbook.jpg", callback);
db.addManager("Gabe Brenner", "Art + Design Manager", "Thurs 5:30-6:30PM", "The Station", "radio.artanddesign@media.ucla.edu", "N/A", "N/A", "/img/Managers/gabebrenner.png", callback);
db.addManager("Gee Leonardo", "Photo / Video Manager", "Thurs 6:15-8PM", "The Station", "photoandvideo@uclaradio.com", "N/A", "N/A", "/img/Managers/gleonardo.png", callback);
db.addManager("Scott Gee", "Events Manager", "Tues 5-6PM", "The Station", "radio.events@media.ucla.edu", "Few Things Considered", "Fri 8-9PM",  "/img/Managers/scottgee.jpg", callback);
db.addManager("Casey John Leonard", "News Manager", "Wed 5-6PM", "The Station", "cj.leonard@hotmail.com", "News Hour; In Conversation; Weekend Edition", "Mon & Thurs 5-6PM; Tues 1-2 PM; Sun 4-5 PM",  "/img/Managers/caseyleonard.jpg", callback);
db.addManager("Willow Stowe", "Programming Manager", "Tues 5:30-6:30PM (week 3, 4 & 6)", "The Station", "radio.programming@media.ucla.edu", "Coffee Talk", "Sun 6-7 PM", "/img/Managers/willowstowe.jpg", callback);
db.addManager("Gracie Phillips", "Programming Manager", "Tues 5:30-6:30PM (week 3, 4 & 6)", "The Station", "radio.programming@media.ucla.edu", "The Mighty Schwa", "Sun 11AM-12PM", "/img/Managers/graciephillips.jpg", callback);
db.addManager("Kim Seltzer", "Comedy Manager", "Wed 2-2:30PM (even weeks)", "The Station", "uclaradio.comedy@media.ucla.edu", "Free Time", "Tues 6PM", "/img/Managers/kimseltzer.jpg", callback);
db.addManager("Aliya Kamalova", "Comedy Manager", "Wed 2-2:30PM (even weeks)", "The Station", "uclaradio.comedy@media.ucla.edu", "Free Time", "Tues 6PM", "/img/Managers/aliyakamalova.jpg", callback);
db.addManager("Nicolo Scolieri", "Productions Manager", "Thurs 6:15-6:45PM", "The Station", "radio.productions@media.ucla.edu", "Where In The World Is Carmen San Diego?", "Sat 11AM-12PM", "/img/Managers/nicoloscolieri.png", callback);
db.addManager("Darryn Albert", "Sports Manager", "Fri 3-4PM", "The Station", "dnalbert@ucla.edu", "N/A", "N/A", "/img/Managers/darrynalbert.JPG", callback);
db.addManager("Desiree Samler", "Fundraising Manager", "Wed 5-6PM", "The Station", "radio.fundraising@media.ucla.edu", "The Brunch Special", "Wed 2-3PM", "/img/Managers/desireesamler.png", callback);

console.log("Finished updating managers");<|endoftext|>


<commit_before>'use strict';

socket.on('connect', function() {
  console.log('Connected successfully!');
});

$(function() {
  $('#sortable').sortable();
  $('#sortable').disableSelection();

  socket.emit('task:get');

  $('#checklist-checkbox').change(function() {
    if(this.checked) {
      $('#description-container').hide();
    } else {
      $('#description-container').show();
    }
  });

  $('#new-task-form').submit(function(evt) {
    evt.preventDefault();
    var formInfo = {
      name: $('#task-name-input').val(),
    };
    // content: $('#task-description').val(),
    formInfo.isChecklist = $('#checklist-checkbox').is(':checked');
    if(formInfo.isChecklist) {
      formInfo.listItems = [];
    } else {
      formInfo.content = $('#task-description').val();
    }
    console.log('Submitting info: ', formInfo);
    socket.emit('task:new', formInfo);
  });

  $('#join-room-form').submit(function(evt) {
    evt.preventDefault();
    socket.emit('room:join', {
      roomId: $('#room-id-input').val()
    });
  });

  $('#create-room-form').submit(function(evt) {
    evt.preventDefault();
    socket.emit('room:create', {
      roomName: $('#room-name-input').val(),
    });
  });
});

socket.on('room:create:res', function(data) {
  console.log('Got data:', data);
  if(!data.success) return console.error('Failed to create room');
  console.log('Successfully created room');
  roomId = data.roomId;
  $('#room').text(data.name);
  $('#roomId').text('(' + data.roomId + ')');
});

socket.on('room:join:res', function(data) {
  console.log('Got response: ', data);
  if(!data.success) return console.error('Failed to join room');
  $('#room').text(data.name);
  $('#roomId').text('(' + data.roomId + ')');
});

socket.on('task:new:res', data => {
  if(!data.success) return console.error(data.message);
  console.log('Added new task successfully');
});

socket.on('task:get:res', function(tasks) {
  console.log('Got tasks:', tasks);
  clearTasks();

  for(var i = 0; i < tasks.length; ++i) {
    $('#tasks').append(tasks[i].isChecklist ?
      makeChecklistElement(tasks[i]) :
      makeTaskElement(tasks[i]));
  }
});

socket.on('update:task:new', function(task) {
  console.log('Got new task:', task);
  $('#tasks').append(task.isChecklist ?
      makeChecklistElement(task) :
      makeTaskElement(task));
});

function clearTasks() {
  $('#tasks').html('');
}

function makeTaskElement(task) {
  return '
\n' +
    '
' + escapeHtml(task.name) + '
\n' +
    '
' + escapeHtml(task.content || '') + '
\n' +
    '
';
}

function makeChecklistElement(task) {
  var el = '
\n' +
      '
' + escapeHtml(task.name) + '
\n' +
      '
';
  for(var i = 0; i < task.listItems; ++i) {
    el += makeListItem(task.listItems[i]);
  }
  el += '
\n' +
    '
';
  return el;
}

function makeListItem(item) {
  return '
\n' +
    '
' + escapeHtml(item.text) + '
\n' +
  '
';
}

var entityMap = {
  "&": "&",
  "<": "<",
  ">": ">",
  '"': '"',
  "'": ''',
  "/": '/'
};

function escapeHtml(string) {
  return String(string).replace(/[&<>"'\/]/g, function (s) {
    return entityMap[s];
  });
}<commit_msg>fix: show old tasks when joining room<commit_after>'use strict';

socket.on('connect', function() {
  console.log('Connected successfully!');
});

$(function() {
  $('#sortable').sortable();
  $('#sortable').disableSelection();

  socket.emit('task:get');

  $('#checklist-checkbox').change(function() {
    if(this.checked) {
      $('#description-container').hide();
    } else {
      $('#description-container').show();
    }
  });

  $('#new-task-form').submit(function(evt) {
    evt.preventDefault();
    var formInfo = {
      name: $('#task-name-input').val(),
    };
    // content: $('#task-description').val(),
    formInfo.isChecklist = $('#checklist-checkbox').is(':checked');
    if(formInfo.isChecklist) {
      formInfo.listItems = [];
    } else {
      formInfo.content = $('#task-description').val();
    }
    console.log('Submitting info: ', formInfo);
    socket.emit('task:new', formInfo);
  });

  $('#join-room-form').submit(function(evt) {
    evt.preventDefault();
    socket.emit('room:join', {
      roomId: $('#room-id-input').val()
    });
  });

  $('#create-room-form').submit(function(evt) {
    evt.preventDefault();
    socket.emit('room:create', {
      roomName: $('#room-name-input').val(),
    });
  });
});

socket.on('room:create:res', function(data) {
  console.log('Got data:', data);
  if(!data.success) return console.error('Failed to create room');
  console.log('Successfully created room');
  roomId = data.roomId;
  $('#room').text(data.name);
  $('#roomId').text('(' + data.roomId + ')');
  clearTasks();
  socket.emit('task:get');
});

socket.on('room:join:res', function(data) {
  console.log('Got response: ', data);
  if(!data.success) return console.error('Failed to join room');
  $('#room').text(data.name);
  $('#roomId').text('(' + data.roomId + ')');
  clearTasks();
  socket.emit('task:get');
});

socket.on('task:new:res', data => {
  if(!data.success) return console.error(data.message);
  console.log('Added new task successfully');
});

socket.on('task:get:res', function(tasks) {
  console.log('Got tasks:', tasks);
  clearTasks();

  for(var i = 0; i < tasks.length; ++i) {
    $('#tasks').append(tasks[i].isChecklist ?
      makeChecklistElement(tasks[i]) :
      makeTaskElement(tasks[i]));
  }
});

socket.on('update:task:new', function(task) {
  console.log('Got new task:', task);
  $('#tasks').append(task.isChecklist ?
      makeChecklistElement(task) :
      makeTaskElement(task));
});

function clearTasks() {
  $('#tasks').html('');
}

function makeTaskElement(task) {
  return '
\n' +
    '
' + escapeHtml(task.name) + '
\n' +
    '
' + escapeHtml(task.content || '') + '
\n' +
    '
';
}

function makeChecklistElement(task) {
  var el = '
\n' +
      '
' + escapeHtml(task.name) + '
\n' +
      '
';
  for(var i = 0; i < task.listItems; ++i) {
    el += makeListItem(task.listItems[i]);
  }
  el += '
\n' +
    '
';
  return el;
}

function makeListItem(item) {
  return '
\n' +
    '
' + escapeHtml(item.text) + '
\n' +
  '
';
}

var entityMap = {
  "&": "&",
  "<": "<",
  ">": ">",
  '"': '"',
  "'": ''',
  "/": '/'
};

function escapeHtml(string) {
  return String(string).replace(/[&<>"'\/]/g, function (s) {
    return entityMap[s];
  });
}<|endoftext|>


<commit_before>/**
 * SRT LYRIC PLAYER
 * based on jQuery v1.5.2 & jQuery UI 1.8.11
 * @name slp.js
 * @author XingxingWoo
 * @version v1.0
 * @date last modified on 2011-4-18
 * @comment
 * Released with the MIT License: http://www.opensource.org/licenses/mit-license.php
 */
var loadSrtLyric = function(){
	var SrtLyric = function($){
		if ($.browser.msie) {
			alert('Sorry! But this script is not for IE!!');
			return false;
		}
		if (!$('#srtDiv').length) {
			$(document.body).append('

');
		}
		if (!$('#srtContent').length) {
			$('#srtDiv').append('

');
		}
		if (!$('#srtDashboard').length) {
			$('#srtDiv').append('

');
			$('#srtDashboard').html('Play Stop Backward Forward <input id="srtNowTS" type="text" maxlength="12" title="[Lyric Timeline], \nchange to jump to any time" /> SRT!').hide();
		}
		if (!$('#srtText').length) {
			$('#srtDiv').append($('<textarea id="srtText" title="[Lyric Input Area], \nchange to load new Lyric via SRT source"></textarea>').hide());
		}
		this._debug = function(){
			window.SrtLyric && window.console && console.info.apply(console, arguments);
		};
		//
		this.lyric = {};
		this.lyricArr = [];
		this.timerSrtLyric = null;
		this.isPlaying = false;
		this.pointer = null;
		this.startTS = new Date();
		this.nowTS = new Date();
		this.updateCurTimeStamp = function(isNow){
			if (isNow) {
				o.nowTS = new Date();
			}
			var timeRun = this.nowTS.getTime() - this.startTS.getTime();
			return timeRun;
		};
		this.updateCurTime = function(timeRun){
			timeRun = timeRun || this.updateCurTimeStamp();
			var curTime = '';
			var dt = new Date(timeRun);
			curTime += '000'.concat(dt.getUTCHours()).substr(-2, 2) + ':';
			curTime += '000'.concat(dt.getUTCMinutes()).substr(-2, 2) + ':';
			curTime += '000'.concat(dt.getUTCSeconds()).substr(-2, 2) + ',';
			curTime += '000'.concat(dt.getUTCMilliseconds()).substr(-3, 3);
			$('#srtNowTS').val(curTime);
			return curTime;
		};
		//
		var o = this;
		//
		this.buildLyric = function(){
			var objSrt = {};
			var oriData = $('#srtText').val().replace(/^\s+|\s+$/gm, '\n').replace(/\n?$/, '\n');
			$('#srtText').val(oriData);
			o.lyricArr = oriData.match(/\d+\n\d{2}:\d{2}:\d{2},\d{3} \-\-> \d{2}:\d{2}:\d{2},\d{3}\n(.+\n)+/gm) || [];
			$.each(o.lyricArr, function(i, n){
				//objSrt[i] = /(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) \-\-> (\d{2}:\d{2}:\d{2},\d{3})\n((?:.+\n)+)/.exec(n)||[];
				var res = /(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) \-\-> (\d{2}:\d{2}:\d{2},\d{3})\n((?:.+\n)+)/.exec(n) || [];
				objSrt[i] = {
					'_id': res[1],
					'_begin': res[2],
					'_end': res[3],
					'_lyric': res[4]
				};
			});
			o._debug('SRT: %o', objSrt);
			o.lyric = objSrt;
		};
		this.srtFn = function(){
			var nowLyric = '';
			var tDiffer = o.updateCurTimeStamp(true);
			$.each(o.lyric, function(i, n){
				if (o.pointer && o.pointer > i) {
					o._debug('Jump from pointer at begin! p: %i', o.pointer);
					return true;
				}
				var _begin = n['_begin'].split(/[:,]/).map(function(m){
					return parseInt(m, 10);
				});
				var _end = n['_end'].split(/[:,]/).map(function(m){
					return parseInt(m, 10);
				});
				var beginTS = new Date(0);
				var endTS = new Date(0);
				beginTS.setUTCHours.apply(beginTS, _begin);
				endTS.setUTCHours.apply(endTS, _end);
				var btDiffer = beginTS.getTime();
				var etDiffer = endTS.getTime();
				//btDiffer = _begin[0] * 3600000 + _begin[1] * 60000 + _begin[2] * 1000 + _begin[3];
				//etDiffer = _end[0] * 3600000 + _end[1] * 60000 + _end[2] * 1000 + _end[3];
				if (btDiffer < tDiffer && tDiffer < etDiffer) {
					nowLyric = n['_lyric'].replace(/\n+/gm, '
');
					o.pointer = 1 * i;
					o._debug('i: ' + i + ', p: %i, time: %i, begin: %i, end: %i', o.pointer, tDiffer, btDiffer, etDiffer);
					return false;
				}
				if (tDiffer < btDiffer) {
					o.pointer = 0;
					o._debug('Nothing matched at end! p: %i', o.pointer);
					return false;
				}
			});
			o.updateCurTime();
			$('#srtContent').html(nowLyric);
			if (o.pointer === null || (o.pointer === o.lyricArr.length - 1 && !nowLyric)) {
				o.srtStop();
				o._debug('All played and finished.');
			}
		};
		this.srtPlay = function(){
			if (o.isPlaying) {
				clearInterval(o.timerSrtLyric);
				o.isPlaying = false;
				$('#srtPlay').html('Play');
			}
			else {
				var sNowTS = new Date();
				o.startTS.setTime(o.startTS.getTime() + sNowTS.getTime() - o.nowTS.getTime());
				o.timerSrtLyric = setInterval(o.srtFn, 100);
				o.isPlaying = true;
				$('#srtPlay').html('Pause');
			}
		};
		this.srtStop = function(){
			clearInterval(o.timerSrtLyric);
			o.startTS = new Date();
			o.nowTS = new Date();
			o.updateCurTime();
			o.pointer = null;
			o.isPlaying = false;
			$('#srtPlay').html('Play');
		};
		this.srtBackward = function(){
			var newTimeRun = o.startTS.getTime() + 1000;
			if (o.nowTS.getTime() > newTimeRun) {
				o.startTS.setTime(newTimeRun);
				o.updateCurTime();
				o._debug('Go backward time 1s.');
			}
		};
		this.srtForward = function(){
			var newTimeRun = o.startTS.getTime() - 1000;
			o.startTS.setTime(newTimeRun);
			o.updateCurTime();
			o._debug('Go forward time 1s.');
		};
		this.srtJump = function(){
			var newTS = new Date(0);
			newTS.setUTCHours.apply(newTS, $('#srtNowTS').val().split(/[:,]/).map(function(m){
				return parseInt(m, 10);
			}));
			var newTimeRun = newTS.getTime();
			o.startTS.setTime(o.nowTS.getTime() - newTimeRun);
			o._debug('Jump to time at %i.', newTimeRun);
		};
		this.srtReload = function(){
			o.buildLyric();
			o.srtStop();
			o._debug('Load succeed! total %i lines.', o.lyricArr.length);
		};
		this.srtHideText = function(){
			$('#srtText').hide();
		};
		this.srtShowText = function(){
			$('#srtText').toggle();
		};
		this.srtShowPanel = function(){
			$('#srtDashboard').fadeIn();
		};
		this.srtHidePanel = function(){
			$('#srtDashboard').fadeOut();
		};
		this.srtScrollObserver = function(event){
			var direct = (event.detail && -event.detail || event.wheelDelta) > 0 ? 1 : -1;
			if (!event.altKey && !event.ctrlKey && event.shiftKey) {
				o._srtScrollZoom(direct);
			}
			if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
				o._srtScrollOpacity(direct);
			}
			event.stopPropagation();
			event.preventDefault();
			return false;
		};
		this._srtScrollZoom = function(offset){
			var size = parseInt($('#srtContent').css('font-size')) + offset;
			if (size >= 12 && size <= 72) {
				o._debug('Font size is %ipx.', size);
				$('#srtContent').css('font-size', size + 'px');
			}
		};
		this._srtScrollOpacity = function(offset){
			var opa = ((parseFloat($('#srtContent').css('opacity')).toFixed(2) * 100 + offset) / 100).toFixed(2);
			if (opa >= 0 && opa <= 1) {
				o._debug('Opacity is %s.', opa);
				$('#srtContent').css('opacity', opa);
			}
		};
		//
		this.buildLyric();
		$('#srtContent').unbind('dblclick').dblclick(this.srtPlay).bind('DOMMouseScroll', this.srtScrollObserver).bind('mousewheel', this.srtScrollObserver);
		$('#srtPlay').unbind('click').click(this.srtPlay);
		$('#srtStop').unbind('click').click(this.srtStop);
		$('#srtBackward').unbind('click').click(this.srtBackward);
		$('#srtForward').unbind('click').click(this.srtForward);
		$('#srtNowTS').unbind('change').change(this.srtJump);
		$('#srtViewer').unbind('click').click(this.srtShowText);
		$('#srtText').unbind('change').change(this.srtReload).unbind('blur').blur(this.srtHideText);
		$('#srtDiv').hover(this.srtShowPanel, this.srtHidePanel).draggable({});
		this.srtStop();
		//get Theatre Mode
		var flashPlayer = $('embed[flashvars]');
		if(flashPlayer.length){
			flashPlayer.closest('div').parents(':not(body,html)').css({top:0,left:0,margin:0,padding:0,border:0,background:0}).siblings(':not("#srtDiv"):visible').hide();
		}
		//
		return this;
	};
	var srtLyric = new SrtLyric(window.jQuery);
};
(function(){
	var dlTmr = null;
	var dlMax = 1200;
	var dlCbk = function($){
		if (!$) {
			return false;
		}
		clearInterval(dlTmr);
		// callback of loadSrtLyric
		$.getScript('https://code.jquery.com/ui/1.8.24/jquery-ui.min.js', loadSrtLyric);
	};
	var dlTmrCbk = function(){
			dlCbk(window.jQuery);
	};
	var dlJS = function(d, l, c){
		var j = d.createElement('script');
		j.src = l || 'https://code.jquery.com/jquery-1.12.4.min.js';
		j.id = 'dlJS' + new Date().getTime();
		j.charset = 'utf-8';
		j.onload = c || dlTmrCbk;
		d.getElementsByTagName('head')[0].appendChild(j);
	};
	dlJS(document);
	dlTmr = setInterval(function(){
		dlTmrCbk();
		dlMax -= 50;
		if (dlMax < 0) {
			clearInterval(dlTmr)
		}
	}, 50);
})();
<commit_msg>fix: remove deprecated property in jquery<commit_after>/**
 * SRT LYRIC PLAYER
 * based on jQuery v1.12.4 & jQuery UI 1.8.24
 * @name slp.js
 * @author XingxingWoo
 * @version v1.0
 * @date last modified on 2017-8-27
 * @comment
 * Released with the MIT License: http://www.opensource.org/licenses/mit-license.php
 */
var loadSrtLyric = function(){
	var SrtLyric = function($){
// 		if ($.browser.msie) { // deprecated after jquery@1.9
// 			alert('Sorry! But this script is not for IE!!');
// 			return false;
// 		}
		if (!$('#srtDiv').length) {
			$(document.body).append('

');
		}
		if (!$('#srtContent').length) {
			$('#srtDiv').append('

');
		}
		if (!$('#srtDashboard').length) {
			$('#srtDiv').append('

');
			$('#srtDashboard').html('Play Stop Backward Forward <input id="srtNowTS" type="text" maxlength="12" title="[Lyric Timeline], \nchange to jump to any time" /> SRT!').hide();
		}
		if (!$('#srtText').length) {
			$('#srtDiv').append($('<textarea id="srtText" title="[Lyric Input Area], \nchange to load new Lyric via SRT source"></textarea>').hide());
		}
		this._debug = function(){
			window.SrtLyric && window.console && console.info.apply(console, arguments);
		};
		//
		this.lyric = {};
		this.lyricArr = [];
		this.timerSrtLyric = null;
		this.isPlaying = false;
		this.pointer = null;
		this.startTS = new Date();
		this.nowTS = new Date();
		this.updateCurTimeStamp = function(isNow){
			if (isNow) {
				o.nowTS = new Date();
			}
			var timeRun = this.nowTS.getTime() - this.startTS.getTime();
			return timeRun;
		};
		this.updateCurTime = function(timeRun){
			timeRun = timeRun || this.updateCurTimeStamp();
			var curTime = '';
			var dt = new Date(timeRun);
			curTime += '000'.concat(dt.getUTCHours()).substr(-2, 2) + ':';
			curTime += '000'.concat(dt.getUTCMinutes()).substr(-2, 2) + ':';
			curTime += '000'.concat(dt.getUTCSeconds()).substr(-2, 2) + ',';
			curTime += '000'.concat(dt.getUTCMilliseconds()).substr(-3, 3);
			$('#srtNowTS').val(curTime);
			return curTime;
		};
		//
		var o = this;
		//
		this.buildLyric = function(){
			var objSrt = {};
			var oriData = $('#srtText').val().replace(/^\s+|\s+$/gm, '\n').replace(/\n?$/, '\n');
			$('#srtText').val(oriData);
			o.lyricArr = oriData.match(/\d+\n\d{2}:\d{2}:\d{2},\d{3} \-\-> \d{2}:\d{2}:\d{2},\d{3}\n(.+\n)+/gm) || [];
			$.each(o.lyricArr, function(i, n){
				//objSrt[i] = /(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) \-\-> (\d{2}:\d{2}:\d{2},\d{3})\n((?:.+\n)+)/.exec(n)||[];
				var res = /(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) \-\-> (\d{2}:\d{2}:\d{2},\d{3})\n((?:.+\n)+)/.exec(n) || [];
				objSrt[i] = {
					'_id': res[1],
					'_begin': res[2],
					'_end': res[3],
					'_lyric': res[4]
				};
			});
			o._debug('SRT: %o', objSrt);
			o.lyric = objSrt;
		};
		this.srtFn = function(){
			var nowLyric = '';
			var tDiffer = o.updateCurTimeStamp(true);
			$.each(o.lyric, function(i, n){
				if (o.pointer && o.pointer > i) {
					o._debug('Jump from pointer at begin! p: %i', o.pointer);
					return true;
				}
				var _begin = n['_begin'].split(/[:,]/).map(function(m){
					return parseInt(m, 10);
				});
				var _end = n['_end'].split(/[:,]/).map(function(m){
					return parseInt(m, 10);
				});
				var beginTS = new Date(0);
				var endTS = new Date(0);
				beginTS.setUTCHours.apply(beginTS, _begin);
				endTS.setUTCHours.apply(endTS, _end);
				var btDiffer = beginTS.getTime();
				var etDiffer = endTS.getTime();
				//btDiffer = _begin[0] * 3600000 + _begin[1] * 60000 + _begin[2] * 1000 + _begin[3];
				//etDiffer = _end[0] * 3600000 + _end[1] * 60000 + _end[2] * 1000 + _end[3];
				if (btDiffer < tDiffer && tDiffer < etDiffer) {
					nowLyric = n['_lyric'].replace(/\n+/gm, '
');
					o.pointer = 1 * i;
					o._debug('i: ' + i + ', p: %i, time: %i, begin: %i, end: %i', o.pointer, tDiffer, btDiffer, etDiffer);
					return false;
				}
				if (tDiffer < btDiffer) {
					o.pointer = 0;
					o._debug('Nothing matched at end! p: %i', o.pointer);
					return false;
				}
			});
			o.updateCurTime();
			$('#srtContent').html(nowLyric);
			if (o.pointer === null || (o.pointer === o.lyricArr.length - 1 && !nowLyric)) {
				o.srtStop();
				o._debug('All played and finished.');
			}
		};
		this.srtPlay = function(){
			if (o.isPlaying) {
				clearInterval(o.timerSrtLyric);
				o.isPlaying = false;
				$('#srtPlay').html('Play');
			}
			else {
				var sNowTS = new Date();
				o.startTS.setTime(o.startTS.getTime() + sNowTS.getTime() - o.nowTS.getTime());
				o.timerSrtLyric = setInterval(o.srtFn, 100);
				o.isPlaying = true;
				$('#srtPlay').html('Pause');
			}
		};
		this.srtStop = function(){
			clearInterval(o.timerSrtLyric);
			o.startTS = new Date();
			o.nowTS = new Date();
			o.updateCurTime();
			o.pointer = null;
			o.isPlaying = false;
			$('#srtPlay').html('Play');
		};
		this.srtBackward = function(){
			var newTimeRun = o.startTS.getTime() + 1000;
			if (o.nowTS.getTime() > newTimeRun) {
				o.startTS.setTime(newTimeRun);
				o.updateCurTime();
				o._debug('Go backward time 1s.');
			}
		};
		this.srtForward = function(){
			var newTimeRun = o.startTS.getTime() - 1000;
			o.startTS.setTime(newTimeRun);
			o.updateCurTime();
			o._debug('Go forward time 1s.');
		};
		this.srtJump = function(){
			var newTS = new Date(0);
			newTS.setUTCHours.apply(newTS, $('#srtNowTS').val().split(/[:,]/).map(function(m){
				return parseInt(m, 10);
			}));
			var newTimeRun = newTS.getTime();
			o.startTS.setTime(o.nowTS.getTime() - newTimeRun);
			o._debug('Jump to time at %i.', newTimeRun);
		};
		this.srtReload = function(){
			o.buildLyric();
			o.srtStop();
			o._debug('Load succeed! total %i lines.', o.lyricArr.length);
		};
		this.srtHideText = function(){
			$('#srtText').hide();
		};
		this.srtShowText = function(){
			$('#srtText').toggle();
		};
		this.srtShowPanel = function(){
			$('#srtDashboard').fadeIn();
		};
		this.srtHidePanel = function(){
			$('#srtDashboard').fadeOut();
		};
		this.srtScrollObserver = function(event){
			var direct = (event.detail && -event.detail || event.wheelDelta) > 0 ? 1 : -1;
			if (!event.altKey && !event.ctrlKey && event.shiftKey) {
				o._srtScrollZoom(direct);
			}
			if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
				o._srtScrollOpacity(direct);
			}
			event.stopPropagation();
			event.preventDefault();
			return false;
		};
		this._srtScrollZoom = function(offset){
			var size = parseInt($('#srtContent').css('font-size')) + offset;
			if (size >= 12 && size <= 72) {
				o._debug('Font size is %ipx.', size);
				$('#srtContent').css('font-size', size + 'px');
			}
		};
		this._srtScrollOpacity = function(offset){
			var opa = ((parseFloat($('#srtContent').css('opacity')).toFixed(2) * 100 + offset) / 100).toFixed(2);
			if (opa >= 0 && opa <= 1) {
				o._debug('Opacity is %s.', opa);
				$('#srtContent').css('opacity', opa);
			}
		};
		//
		this.buildLyric();
		$('#srtContent').unbind('dblclick').dblclick(this.srtPlay).bind('DOMMouseScroll', this.srtScrollObserver).bind('mousewheel', this.srtScrollObserver);
		$('#srtPlay').unbind('click').click(this.srtPlay);
		$('#srtStop').unbind('click').click(this.srtStop);
		$('#srtBackward').unbind('click').click(this.srtBackward);
		$('#srtForward').unbind('click').click(this.srtForward);
		$('#srtNowTS').unbind('change').change(this.srtJump);
		$('#srtViewer').unbind('click').click(this.srtShowText);
		$('#srtText').unbind('change').change(this.srtReload).unbind('blur').blur(this.srtHideText);
		$('#srtDiv').hover(this.srtShowPanel, this.srtHidePanel).draggable({});
		this.srtStop();
		//get Theatre Mode
		var flashPlayer = $('embed[flashvars]');
		if(flashPlayer.length){
			flashPlayer.closest('div').parents(':not(body,html)').css({top:0,left:0,margin:0,padding:0,border:0,background:0}).siblings(':not("#srtDiv"):visible').hide();
		}
		//
		return this;
	};
	var srtLyric = new SrtLyric(window.jQuery);
};
(function(){
	var dlTmr = null;
	var dlMax = 1200;
	var dlCbk = function($){
		if (!$) {
			return false;
		}
		clearInterval(dlTmr);
		// callback of loadSrtLyric
		$.getScript('https://code.jquery.com/ui/1.8.24/jquery-ui.min.js', loadSrtLyric);
	};
	var dlTmrCbk = function(){
			dlCbk(window.jQuery);
	};
	var dlJS = function(d, l, c){
		var j = d.createElement('script');
		j.src = l || 'https://code.jquery.com/jquery-1.12.4.min.js';
		j.id = 'dlJS' + new Date().getTime();
		j.charset = 'utf-8';
		j.onload = c || dlTmrCbk;
		d.getElementsByTagName('head')[0].appendChild(j);
	};
	dlJS(document);
	dlTmr = setInterval(function(){
		dlTmrCbk();
		dlMax -= 50;
		if (dlMax < 0) {
			clearInterval(dlTmr)
		}
	}, 50);
})();
<|endoftext|>


<commit_before>var studentEditView = Backbone.View.extend({
  tagName: "div",

  events: {
    "submit #student-edit-form": "updateStudent",
    "click #close-edit": "showStudentDetail",
    "change #division": "loadTownships"
  },

  initialize: function() {
    //
  },

  api: function(path) {
    return app.host + path;
  },

  render: function() {
    this.$el.html( app.hookTemplate("student-edit", this.model.toJSON()) );
    return this;
  },

  loadTownships: function() {
    var that = this;
    var divisionId = $("#division").val();
    $.ajax({
      url: this.api("/students/townships/" + divisionId),
      success: function(data) {
        //console.log(data);
        var options = "";
        app.townships = data[0]["townshiplist"];
        for (var i = 0; i < app.townships.length; i++) {
              options += "<option value=" + i + ">" + app.townships[i] + "</option>";
            };
            $("#township").html(options);
      }
    });
  },

  updateStudent: function() {
    var studentNameInput = $("#studentName");
    if(!studentNameInput.val()) {
      studentNameInput.parent().addClass('has-error');
      studentNameInput.focus();
      return false;
    }

    var name = studentNameInput.val();
    var contact1 = $("#contact1").val();
    var contact2 = $("#contact2").val();
    var fbprofile = $("#fbprofile").val();
    var emailInput = $("#email").val();
    var addressInput = $("#address").val();
    var divisionId = $("#division").val();
    var townshipValue = $("#township").val();

    var that = this;
    this.model.save({
      "studentName" : name,
      "contact1": contact1,
      "contact2": contact2,
      "fbprofile": fbprofile,
      "email" : emailInput,
      "address" : addressInput,
      "divisionid": divisionId,
      "divisionName": app.divisions[divisionId],
      "townshipid": townshipValue,
      "townshipName": app.townships[townshipValue]
    }, {
      wait: true,
      success: function(res) {
        that.showStudentDetail();
        location.reload();
      }
    });

    return false;
  },

  showStudentDetail: function(data) {
    var detail = new studentDetailView({ model: this.model });
    $("#main").html( detail.render().el );
  }
});<commit_msg>Add comments<commit_after>var studentEditView = Backbone.View.extend({
  tagName: "div",

  events: {
    "submit #student-edit-form": "updateStudent",
    "click #close-edit": "showStudentDetail",
    "change #division": "loadTownships"
  },

  initialize: function() {
    //
  },

  api: function(path) {
    return app.host + path;
  },

  render: function() {
    this.$el.html( app.hookTemplate("student-edit", this.model.toJSON()) );
    return this;
  },

  loadTownships: function() {
    var that = this;
    var divisionId = $("#division").val();
    $.ajax({
      url: this.api("/students/townships/" + divisionId),
      success: function(data) {
        //console.log(data);
        var options = "";
        app.townships = data[0]["townshiplist"];
        for (var i = 0; i < app.townships.length; i++) {
              options += "<option value=" + i + ">" + app.townships[i] + "</option>";
            };
            $("#township").html(options);
      }
    });
  },

  updateStudent: function() {
    var studentNameInput = $("#studentName");
    if(!studentNameInput.val()) {
      studentNameInput.parent().addClass('has-error');
      studentNameInput.focus();
      return false;
    }

    var name = studentNameInput.val();
    var contact1 = $("#contact1").val();
    var contact2 = $("#contact2").val();
    var fbprofile = $("#fbprofile").val();
    var emailInput = $("#email").val();
    var addressInput = $("#address").val();
    var divisionId = $("#division").val();
    var townshipValue = $("#township").val();

    var that = this;
    this.model.save({
      "studentName" : name,
      "contact1": contact1,
      "contact2": contact2,
      "fbprofile": fbprofile,
      "email" : emailInput,
      "address" : addressInput,
      "divisionid": divisionId,
      "divisionName": app.divisions[divisionId],
      "townshipid": townshipValue,
      "townshipName": app.townships[townshipValue]
    }, {
      wait: true,
      success: function(res) {
        that.showStudentDetail();
        location.reload(); // Need to think!!
      }
    });

    return false;
  },

  showStudentDetail: function(data) {
    var detail = new studentDetailView({ model: this.model });
    $("#main").html( detail.render().el );
  }
});<|endoftext|>


<commit_before>var Zombie = require("zombie");

exports.crawl = function(url) {
  function extractOrigin(url) {
    return url.match(/https?:\/\/.*?\//);
  }
  Zombie.visit(url, function(e, zombie) {
    origin = extractOrigin(url);
    zombie.queryAll('a')
          .map(function(link) {
            return link.getAttribute('href'); })
          .map(function(url) {
            if (url.indexOf('/') === 0) {
              return origin + url.substring(1);
            }
            return url; })
          .forEach(function(url) {
            Zombie.visit(url, function(e, zombie) {
            }); });
  });
};
<commit_msg>Log errors on pages<commit_after>var Zombie = require("zombie");

exports.crawl = function(url) {
  function extractOrigin(url) {
    return url.match(/https?:\/\/.*?\//);
  }
  Zombie.visit(url, function(e, zombie) {
    zombie.on("error", function(error) {
      console.log("Error ", url, " ", error);
    });
    origin = extractOrigin(url);
    zombie.queryAll('a')
          .map(function(link) {
            return link.getAttribute('href'); })
          .map(function(url) {
            if (url.indexOf('/') === 0) {
              return origin + url.substring(1);
            }
            return url; })
          .forEach(function(url) {
            Zombie.visit(url, function(e, zombie) {
              zombie.on("error", function(error) {
                console.log("Error ", url, " ", error);
              });
            }); });
  });
};
<|endoftext|>


<commit_before>import url from 'url';
import traverson from 'traverson';
import pluralize from 'pluralize';
import hal_adapter from 'traverson-hal';
import debug_logger from 'debug';

let debug = debug_logger('rest-client-builder');

traverson.registerMediaType(hal_adapter.mediaType, hal_adapter);

function json(res) {
    try {
        return res && res.body ? JSON.parse(res.body) : {};
    }
    catch(e) {
        return {};
    }
}

function add_child_accessors(client, parent, children) {
    if (!children)
        return;
    children.forEach(x => {
        parent[x.name] = () => {
            let proxy = new resource_proxy(client, x.name, parent, x._actions, x.methods);
            add_child_accessors(client, proxy, x._children);
            return proxy;
        };
        parent[pluralize.singular(x.name)] = id => {
            if (!id)
                throw new Error("The 'id' parameter is required.");
            let proxy = new resource_proxy(client, x.name, parent, x._actions, x.methods, id);
            add_child_accessors(client, proxy, x._children);
            return proxy;
        };
    });
}

class hal_client {
    constructor() {
        this._uri = null;
        this._api = null;
    }

    from(uri) {
        this._uri = uri;
        this._api = traverson
            .from(uri)
            .jsonHal()
            .withRequestOptions({
                headers: {
                    'Accept': 'application/hal+json',
                    'Content-Type': 'application/json'
                }
            });
         return this;
    }

    get uri() {
        return this._uri;
    }

    get api() {
        return this._api;
    }

    root() {
        return new Promise((resolve, reject) => {
            this.api
                .newRequest()
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    resource_at(href, params) {
        return new Promise((resolve, reject) => {
            this.api
                .newRequest()
                .from(url.resolve(this.api.getFrom(), href))
                .withTemplateParameters(params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }
}

class resource_proxy {
    constructor(client, name, parent, actions, methods, parent_id) {
        this._name = name;
        this._children = [];
        this._actions = actions || {
            find: true,
            create: true,
            update: true,
            patch: true,
            delete: true,
            find_by_id: true,
            delete_by_id: true,
            find_by_named_query: true
        };
        this._client = client;
        this._follow_names = [];
        this._template_params = {};
        this._parent = parent || null;
        this._parent_id = parent_id || null;
        this._singular_name = pluralize.singular(name);
        this._id_name = `${this._singular_name}_id`;

        let current = this;
        while (true) {
            this._follow_names.unshift(current.name);
            if (current.parent_id)
                this._template_params[current.id_name] = current.parent_id;
            current = current._parent;
            if (!current || !current.name)
                break;
        }

        if (methods) {
            methods.forEach(x => {
                this[x.name] = x.func;
            });
        }
    }

    get name() {
        return this._name;
    }

    get client() {
        return this._client;
    }

    get parent() {
        return this._parent;
    }

    get id_name() {
        return this._id_name;
    }

    get parent_id() {
        return this._parent_id;
    }

    get follow_names() {
        return this._follow_names;
    }

    get singular_name() {
        return this._singular_name;
    }

    get template_params() {
        return this._template_params;
    }

    _throw_if_disabled(action) {
        if (!this._actions[action])
            throw new Error(`This resource does not permit '${action}'.`);
    }

    find(params, options) {
        this._throw_if_disabled('find');
        for (let x in params) {
            if (Array.isArray(params[x]))
                params[x] = params[x].join(',');
        }
        let opts = Object.assign({}, { qs: params || {} }, options);
        return new Promise((resolve, reject) => {
            this.client
                .api
                .newRequest()
                .withRequestOptions(opts)
                .follow(this.follow_names)
                .withTemplateParameters(this.template_params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    create(data, options) {
        this._throw_if_disabled('create');
        if (!data)
            throw new Error("The 'data' parameter is required.");
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(this.template_params)
                .post(data, (error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    find_by_id(id, options) {
        this._throw_if_disabled('find_by_id');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    patch(id, data, options) {
        this._throw_if_disabled('patch');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        if (!data)
            throw new Error("The 'data' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .patch(data, (error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    delete(filters, options) {
        this._throw_if_disabled('delete');
        let params = this.template_params;
        let opts = Object.assign({}, { qs: filters || {} }, options);
        return new Promise((resolve, reject) => {
            this.client
                .api
                .newRequest()
                .withRequestOptions(opts)
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .del((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    delete_by_id(id, options) {
        this._throw_if_disabled('delete_by_id');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .del((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    update(id, data, options) {
        this._throw_if_disabled('update');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        if (!data)
            throw new Error("The 'data' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .put(data, (error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    find_by_named_query(name, options) {
        this._throw_if_disabled('find_by_named_query');
        if (!name)
            throw new Error("The 'name' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = name;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }
}

class resource_builder {
    constructor(name, parent) {
        this._name = name;
        this._actions = {
            find: true,
            create: true,
            update: true,
            patch: true,
            delete: true,
            find_by_id: true,
            delete_by_id: true,
            find_by_named_query: true
        };
        this._methods = [];
        this._children = [];
        this._description = null;
        this._parent = parent || null;
    }

    get name() {
        return this._name;
    }

    get parent() {
        return this._parent;
    }

    get methods() {
        return this._methods;
    }

    method(name, func) {
        this._methods.push({ name, func });
        return this;
    }

    resource(name) {
        let b = new resource_builder(name, this);
        this._children.push(b);
        return b;
    }

    description(desc) {
        this._description = desc;
        return this;
    }

    disable_all() {
        this._actions = {
            find: false,
            create: false,
            update: false,
            patch: false,
            delete: false,
            find_by_id: false,
            delete_by_id: false,
            find_by_named_query: false
        };
        return this;
    }

    disable_find() {
        this._actions.find = false;
        return this;
    }

    disable_create() {
        this._actions.create = false;
        return this;
    }

    disable_update() {
        this._actions.update = false;
        return this;
    }

    disable_patch() {
        this._actions.patch = false;
        return this;
    }

    disable_delete() {
        this._actions.delete = false;
        return this;
    }

    disable_find_by_id() {
        this._actions.find_by_id = false;
        return this;
    }

    disable_delete_by_id() {
        this._actions.delete_by_id = false;
        return this;
    }

    disable_find_by_named_query() {
        this._actions.find_by_named_query = false;
        return this;
    }
}

class root_resource_builder {
    constructor() {
        this._children = [];
    }

    hal() {
        let client = new hal_client();
        add_child_accessors(client, client, this._children);
        return client;
    }

    resource(name) {
        let b = new resource_builder(name, this);
        this._children.push(b);
        return b;
    }
}

export class rest_client_builder {
    constructor() {
    }

    root() {
        return new root_resource_builder();
    }
}
<commit_msg>fix binding of custom client functions.<commit_after>import url from 'url';
import traverson from 'traverson';
import pluralize from 'pluralize';
import hal_adapter from 'traverson-hal';
import debug_logger from 'debug';

let debug = debug_logger('rest-client-builder');

traverson.registerMediaType(hal_adapter.mediaType, hal_adapter);

function json(res) {
    try {
        return res && res.body ? JSON.parse(res.body) : {};
    }
    catch(e) {
        return {};
    }
}

function add_child_accessors(client, parent, children) {
    if (!children)
        return;
    children.forEach(x => {
        parent[x.name] = () => {
            let proxy = new resource_proxy(client, x.name, parent, x._actions, x.methods);
            add_child_accessors(client, proxy, x._children);
            return proxy;
        };
        parent[pluralize.singular(x.name)] = id => {
            if (!id)
                throw new Error("The 'id' parameter is required.");
            let proxy = new resource_proxy(client, x.name, parent, x._actions, x.methods, id);
            add_child_accessors(client, proxy, x._children);
            return proxy;
        };
    });
}

class hal_client {
    constructor() {
        this._uri = null;
        this._api = null;
    }

    from(uri) {
        this._uri = uri;
        this._api = traverson
            .from(uri)
            .jsonHal()
            .withRequestOptions({
                headers: {
                    'Accept': 'application/hal+json',
                    'Content-Type': 'application/json'
                }
            });
         return this;
    }

    get uri() {
        return this._uri;
    }

    get api() {
        return this._api;
    }

    root() {
        return new Promise((resolve, reject) => {
            this.api
                .newRequest()
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    resource_at(href, params) {
        return new Promise((resolve, reject) => {
            this.api
                .newRequest()
                .from(url.resolve(this.api.getFrom(), href))
                .withTemplateParameters(params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }
}

class resource_proxy {
    constructor(client, name, parent, actions, methods, parent_id) {
        this._name = name;
        this._children = [];
        this._actions = actions || {
            find: true,
            create: true,
            update: true,
            patch: true,
            delete: true,
            find_by_id: true,
            delete_by_id: true,
            find_by_named_query: true
        };
        this._client = client;
        this._follow_names = [];
        this._template_params = {};
        this._parent = parent || null;
        this._parent_id = parent_id || null;
        this._singular_name = pluralize.singular(name);
        this._id_name = `${this._singular_name}_id`;

        let current = this;
        while (true) {
            this._follow_names.unshift(current.name);
            if (current.parent_id)
                this._template_params[current.id_name] = current.parent_id;
            current = current._parent;
            if (!current || !current.name)
                break;
        }

        if (methods) {
            methods.forEach(x => {
                if (x.func)
                    this[x.name] = x.func.bind(this);
            });
        }
    }

    get name() {
        return this._name;
    }

    get client() {
        return this._client;
    }

    get parent() {
        return this._parent;
    }

    get id_name() {
        return this._id_name;
    }

    get parent_id() {
        return this._parent_id;
    }

    get follow_names() {
        return this._follow_names;
    }

    get singular_name() {
        return this._singular_name;
    }

    get template_params() {
        return this._template_params;
    }

    _json(res) {
        return json(res);
    }

    _throw_if_disabled(action) {
        if (!this._actions[action])
            throw new Error(`This resource does not permit '${action}'.`);
    }

    find(params, options) {
        this._throw_if_disabled('find');
        for (let x in params) {
            if (Array.isArray(params[x]))
                params[x] = params[x].join(',');
        }
        let opts = Object.assign({}, { qs: params || {} }, options);
        return new Promise((resolve, reject) => {
            this.client
                .api
                .newRequest()
                .withRequestOptions(opts)
                .follow(this.follow_names)
                .withTemplateParameters(this.template_params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    create(data, options) {
        this._throw_if_disabled('create');
        if (!data)
            throw new Error("The 'data' parameter is required.");
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(this.template_params)
                .post(data, (error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    find_by_id(id, options) {
        this._throw_if_disabled('find_by_id');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    patch(id, data, options) {
        this._throw_if_disabled('patch');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        if (!data)
            throw new Error("The 'data' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .patch(data, (error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    delete(filters, options) {
        this._throw_if_disabled('delete');
        let params = this.template_params;
        let opts = Object.assign({}, { qs: filters || {} }, options);
        return new Promise((resolve, reject) => {
            this.client
                .api
                .newRequest()
                .withRequestOptions(opts)
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .del((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    delete_by_id(id, options) {
        this._throw_if_disabled('delete_by_id');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .del((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    update(id, data, options) {
        this._throw_if_disabled('update');
        if (!id)
            throw new Error("The 'id' parameter is required.");
        if (!data)
            throw new Error("The 'data' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = id;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .put(data, (error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }

    find_by_named_query(name, options) {
        this._throw_if_disabled('find_by_named_query');
        if (!name)
            throw new Error("The 'name' parameter is required.");
        let params = this.template_params;
        params[this.id_name] = name;
        return new Promise((resolve, reject) => {
            let request = this.client.api.newRequest();
            if (options)
                request = request.withRequestOptions(options);
            request
                .follow(this.follow_names)
                .withTemplateParameters(params)
                .get((error, response) => error ? reject(error) : resolve({ response, resource: json(response) }));
        });
    }
}

class resource_builder {
    constructor(name, parent) {
        this._name = name;
        this._actions = {
            find: true,
            create: true,
            update: true,
            patch: true,
            delete: true,
            find_by_id: true,
            delete_by_id: true,
            find_by_named_query: true
        };
        this._methods = [];
        this._children = [];
        this._description = null;
        this._parent = parent || null;
    }

    get name() {
        return this._name;
    }

    get parent() {
        return this._parent;
    }

    get methods() {
        return this._methods;
    }

    method(name, func) {
        this._methods.push({ name, func });
        return this;
    }

    resource(name) {
        let b = new resource_builder(name, this);
        this._children.push(b);
        return b;
    }

    description(desc) {
        this._description = desc;
        return this;
    }

    disable_all() {
        this._actions = {
            find: false,
            create: false,
            update: false,
            patch: false,
            delete: false,
            find_by_id: false,
            delete_by_id: false,
            find_by_named_query: false
        };
        return this;
    }

    disable_find() {
        this._actions.find = false;
        return this;
    }

    disable_create() {
        this._actions.create = false;
        return this;
    }

    disable_update() {
        this._actions.update = false;
        return this;
    }

    disable_patch() {
        this._actions.patch = false;
        return this;
    }

    disable_delete() {
        this._actions.delete = false;
        return this;
    }

    disable_find_by_id() {
        this._actions.find_by_id = false;
        return this;
    }

    disable_delete_by_id() {
        this._actions.delete_by_id = false;
        return this;
    }

    disable_find_by_named_query() {
        this._actions.find_by_named_query = false;
        return this;
    }
}

class root_resource_builder {
    constructor() {
        this._children = [];
    }

    hal() {
        let client = new hal_client();
        add_child_accessors(client, client, this._children);
        return client;
    }

    resource(name) {
        let b = new resource_builder(name, this);
        this._children.push(b);
        return b;
    }
}

export class rest_client_builder {
    constructor() {
    }

    root() {
        return new root_resource_builder();
    }
}
<|endoftext|>


<commit_before>
(function () {
    'use strict';

    var React = require('react')
      , Router = require('react-router')
      , DefaultRoute = Router.DefaultRoute
      , Route = Router.Route;

    var App = require('./components/App.react.jsx')
      , BeaconsList = require('./components/BeaconsList.react.jsx')
      , BeaconsMap = require('./components/BeaconsMap.react.jsx')
      , BeaconsSection = require('./components/BeaconsSection.react.jsx')
      , BuddiesList = require('./components/BuddiesList.react.jsx')
      , ChallengesList = require('./components/ChallengesList.react.jsx')
      , CreateBeacon = require('./components/CreateBeacon.react.jsx')
      , EventsList = require('./components/EventsList.react.jsx')
      , Settings = require('./components/Settings.react.jsx');

    // Set up routes
    var routes = (
        <Route handler={ App }>
            <Route name="beacons" path="beacons" handler={ BeaconsSection }>
                <DefaultRoute name="beacons-list" handler={ BeaconsList } />
                <Route name="beacons-map" path="map" handler={ BeaconsMap } />
            </Route>
            <Route name="events" path="events" handler={ EventsList } />
            <Route name="buddies" path="buddies" handler={ BuddiesList } />
            <Route name="challenges" path="challenges" handler={ ChallengesList } />
            <Route name="create-beacon" path="create-beacon" handler={ CreateBeacon } />
            <Route name="settings" path="settings" handler={ Settings } />
        </Route>
    );

    Router.run(routes, function (Root) {
        React.render(<Root />, document.getElementById('smatchups'));
    });

})();
<commit_msg>Fixed stupid bug where deleted routes and components were included<commit_after>
(function () {
    'use strict';

    var React = require('react')
      , Router = require('react-router')
      , DefaultRoute = Router.DefaultRoute
      , Route = Router.Route;

    var App = require('./components/App.react.jsx')
      , BeaconsSection = require('./components/BeaconsSection.react.jsx')
      , BuddiesList = require('./components/BuddiesList.react.jsx')
      , ChallengesList = require('./components/ChallengesList.react.jsx')
      , CreateBeacon = require('./components/CreateBeacon.react.jsx')
      , EventsList = require('./components/EventsList.react.jsx')
      , Settings = require('./components/Settings.react.jsx');

    // Set up routes
    var routes = (
        <Route handler={ App }>
            <Route name="beacons" path="beacons" handler={ BeaconsSection } />
            <Route name="events" path="events" handler={ EventsList } />
            <Route name="buddies" path="buddies" handler={ BuddiesList } />
            <Route name="challenges" path="challenges" handler={ ChallengesList } />
            <Route name="create-beacon" path="create-beacon" handler={ CreateBeacon } />
            <Route name="settings" path="settings" handler={ Settings } />
        </Route>
    );

    Router.run(routes, function (Root) {
        React.render(<Root />, document.getElementById('smatchups'));
    });

})();
<|endoftext|>