<commit_before>$("#customer_call").on ("click", function () {
	$("#pageContent").load("pages/customer-view.html", function () {
		$(this).enhanceWithin(); /* apply styles */
	});
});
$("#doc_call").on ("click", function () {
	$("#pageContent").load("pages/supporting-docs-view.html", function () {
		$(this).enhanceWithin(); /* apply styles */
	});
});
$("#cancel").on ("click", function () {
	$("#pageContent").load("pages/customer-entry-view.html", function () {
		$(this).enhanceWithin(); /* apply styles */
	});
});

$(".current-title").text ("Property details");
$(".left").on ("click", function () {
	loadPage ("pages/property-view.html");
});

data = {
        "AlreadyOwn": "N",
        "isExisting": "E",
        "propAddress": "Casa Nearshore, Shore 19, Sidi Maârouf, Casablanca",
        "propType": "villa",
        "rooms" : ">4",
        "usage" : "rent",
        "liveableArea" : "210 sqm",
        "builtArea"	: "250 sqm",
        "isEvaluated" : "Y",
        "evaluationSum" : "430,000"
};

$.each(data, function (name, val) {
    var $el = $('[name="' + name + '"]'),
        type = $el.attr('type');

    switch (type) {
        case 'checkbox':
            $el.attr('checked', 'checked');
            break;
        case 'radio':
            $el.filter('[value="' + val + '"]').attr('checked', 'checked');
            break;
        default:
            $el.val(val);
    }
});

<commit_msg>Property-view.js update<commit_after>$("#customer_call").on ("click", function () {
	$("#pageContent").load("pages/customer-view.html", function () {
		$(this).enhanceWithin(); /* apply styles */
	});
});
$("#doc_call").on ("click", function () {
	$("#pageContent").load("pages/supporting-docs-view.html", function () {
		$(this).enhanceWithin(); /* apply styles */
	});
});
$("#cancel").on ("click", function () {
	$("#pageContent").load("pages/customer-view.html", function () {
		$(this).enhanceWithin(); /* apply styles */
	});
});

$(".current-title").text ("Property details");
$(".left").on ("click", function () {
	loadPage ("pages/property-view.html");
});

data = {
        "AlreadyOwn": "N",
        "isExisting": "E",
        "propAddress": "Casa Nearshore, Shore 19, Sidi Maârouf, Casablanca",
        "propType": "villa",
        "rooms" : ">4",
        "usage" : "rent",
        "liveableArea" : "210 sqm",
        "builtArea"	: "250 sqm",
        "isEvaluated" : "Y",
        "evaluationSum" : "430,000"
};

$.each(data, function (name, val) {
    var $el = $('[name="' + name + '"]'),
        type = $el.attr('type');

    switch (type) {
        case 'checkbox':
            $el.attr('checked', 'checked');
            break;
        case 'radio':
            $el.filter('[value="' + val + '"]').attr('checked', 'checked');
            break;
        default:
            $el.val(val);
    }
});

<|endoftext|>


<commit_before>/**
 * Small Group Controller
 */

'use strict';

var SmallGroup = require('./smallgroup.model');
var ClassYear = require('../classyear/classyear.model');
var User = require('../user/user.model');
var Project = require('../project/project.model');

// Get current class year
exports.index = function(req, res) {
    SmallGroup.find({}, function(err, smallgroups){
        if (err) { return handleError(res, err); }
        return res.json(200, smallgroups);
    });
};

exports.create = function(req, res){
    var user = req.user;
    ClassYear.getCurrent(function(err, currentClassYear){
        if (err) return handleError(res, err);
        var smallgroup = new SmallGroup({
            "name": "New Small Group",
            "semester": currentClassYear.semester,
            "enabled": true,
            "students": [user._id],
            "dayCodes": []
        });
        smallgroup.save();
        user.smallgroup = smallgroup._id;
        user.save();
        res.send(200);
    });
};

exports.modify = function(req, res){
    var id = req.params.id;
    SmallGroup.update({"_id": id}, req.body.smallgroup, function(err){
        if (err) return handleError(res, err);
        res.send(200);
    });
};

exports.delete = function(req, res){
    var id = req.params.id;
    SmallGroup.findById(id, function(err, smallgroup){
        if (err) return handleError(res, err);
        smallgroup.remove();
        res.send(200);
    });
};

exports.getSmallGroup = function(req, res){
    var id = req.params.id;
    SmallGroup.findById(id, function(err, smallgroup){
        if (err) return handleError(res, err);
        console.log(req.user);
        if (!req.user || !req.user.isMentor){
            smallgroup.dayCodes = null;
        }else{
            // This has to be called because "dayCode" is a virtual
            smallgroup.dayCode = smallgroup.dayCode;
        }
        res.json(200, smallgroup);
    });
};

function getFullMember(memberId, callback){
    User.findById(memberId, function(err, member){
        if (err) return callback("Could not find user", null);
        member.getFullProfile(function(fullProfile){
            // Add the user's attendance
            fullProfile.presense = member.presence;
            callback(null, fullProfile);
        });
    });
}

exports.getSmallGroupMembers = function(req, res){
    var id = req.params.id;
    SmallGroup.findById(id, function(err, smallgroup){
        if (err) return handleError(res, err);
        var members = [];
        var loadedMembers = 0;

        // Load each group member's full profile
        smallgroup.students.forEach(function(studentId){
            getFullMember(studentId, function(err, member){
                loadedMembers ++;
                if (member){
                    members.push(member);
                }

                // Check if we're done loading members
                if (loadedMembers == smallgroup.students.length){
                    res.json(200, members);
                }
            })
        });
    });
};

function handleError(res, err) {
  return res.send(500, err);
}

function validationError(res, err) {
  return res.json(422, err);
};
<commit_msg>removed logging<commit_after>/**
 * Small Group Controller
 */

'use strict';

var SmallGroup = require('./smallgroup.model');
var ClassYear = require('../classyear/classyear.model');
var User = require('../user/user.model');
var Project = require('../project/project.model');

// Get current class year
exports.index = function(req, res) {
    SmallGroup.find({}, function(err, smallgroups){
        if (err) { return handleError(res, err); }
        return res.json(200, smallgroups);
    });
};

exports.create = function(req, res){
    var user = req.user;
    ClassYear.getCurrent(function(err, currentClassYear){
        if (err) return handleError(res, err);
        var smallgroup = new SmallGroup({
            "name": "New Small Group",
            "semester": currentClassYear.semester,
            "enabled": true,
            "students": [user._id],
            "dayCodes": []
        });
        smallgroup.save();
        user.smallgroup = smallgroup._id;
        user.save();
        res.send(200);
    });
};

exports.modify = function(req, res){
    var id = req.params.id;
    SmallGroup.update({"_id": id}, req.body.smallgroup, function(err){
        if (err) return handleError(res, err);
        res.send(200);
    });
};

exports.delete = function(req, res){
    var id = req.params.id;
    SmallGroup.findById(id, function(err, smallgroup){
        if (err) return handleError(res, err);
        smallgroup.remove();
        res.send(200);
    });
};

exports.getSmallGroup = function(req, res){
    var id = req.params.id;
    SmallGroup.findById(id, function(err, smallgroup){
        if (err) return handleError(res, err);
        if (!req.user || !req.user.isMentor){
            smallgroup.dayCodes = null;
        }else{
            // This has to be called because "dayCode" is a virtual
            smallgroup.dayCode = smallgroup.dayCode;
        }
        res.json(200, smallgroup);
    });
};

function getFullMember(memberId, callback){
    User.findById(memberId, function(err, member){
        if (err) return callback("Could not find user", null);
        member.getFullProfile(function(fullProfile){
            // Add the user's attendance
            fullProfile.presense = member.presence;
            callback(null, fullProfile);
        });
    });
}

exports.getSmallGroupMembers = function(req, res){
    var id = req.params.id;
    SmallGroup.findById(id, function(err, smallgroup){
        if (err) return handleError(res, err);
        var members = [];
        var loadedMembers = 0;

        // Load each group member's full profile
        smallgroup.students.forEach(function(studentId){
            getFullMember(studentId, function(err, member){
                loadedMembers ++;
                if (member){
                    members.push(member);
                }

                // Check if we're done loading members
                if (loadedMembers == smallgroup.students.length){
                    res.json(200, members);
                }
            })
        });
    });
};

function handleError(res, err) {
  return res.send(500, err);
}

function validationError(res, err) {
  return res.json(422, err);
};
<|endoftext|>


<commit_before>// @flow

const Excel = require('exceljs');
const db = require('../../../models');

import type { Response } from '../../lib/typed-express';
import type { UserRequest, AdminRole } from '../../lib/auth';

function headersForExcelFile(name: string): * {
  return {
    'Content-type': 'application/vnd.ms-excel',
    'Content-Disposition': `attachment; filename="${name}.xlsx"`,
    'Cache-Control': 'max-age=0'
  };
}

function flatten(field: string, object: Object): Object {
  const ret = Object.assign({}, object);
  for (const k in object[field]) {
    ret[`${field}_${k}`] = object[field][k];
  }
  return ret;
}

async function export_data_excel(req: UserRequest<AdminRole>, res: Response): Promise<void> {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectDump_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  const columnSpecs = {
    household: {},
    child: {},
    household_address: {},
    household_phone: {},
    user: { id: { width: 3 } }
  };

  for (const table in columnSpecs) {
    const data = await db[table].findAll();
    const worksheet = workbook.addWorksheet(table);
    const cols = [];
    for (const col of Object.getOwnPropertyNames(columnSpecs[table])) {
      if (columnSpecs[table][col] !== false) {
        cols.push(Object.assign({}, { key: col, header: col, width: 10 }, columnSpecs[table][col]));
      }
    }
    if (data[0]) {
      for (const col in data[0].toJSON()) {
        if (!(col in columnSpecs[table])) {
          cols.push({ key: col, header: col, width: 10 });
        }
      }
    }
    worksheet.columns = cols;
    data.forEach(row => {
      if (row.vault !== undefined) {
        row = Object.assign(row, row.vault);
        delete row.vault;
      }
      worksheet.addRow(row).commit();
    });
    worksheet.commit();
  }
  await workbook.commit();
}

async function link_report(req: UserRequest<AdminRole>, res: Response) {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectTheLinkReport_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  let worksheet = workbook.addWorksheet('Household Report');
  worksheet.columns = [
    { key: 'id', header: 'familyId', width: 10 },
    { key: 'name_last', header: 'familyHeadFirst', width: 15 },
    { key: 'name_first', header: 'familyHeadLast', width: 15 },
    { key: 'approved', header: 'familyApproved', width: 15 },
    { key: 'blocked', header: 'familyBlocked', width: 15 },
  ];

  const households = await db.household.findAll();
  // const households = await db.household.findAll({ where: { approved: true } });
  households.forEach(household => {
    // See GIFT-260
    household.approved = (household.approved) ? 1 : 0;
    household.blocked = (household.deleted) ? 1 : 0;
    worksheet.addRow(household).commit();
  });
  worksheet.commit();

  worksheet = workbook.addWorksheet('Child Report');
  worksheet.columns = [
    { key: 'id', header: 'childId', width: 10 },
    { key: 'household_id', header: 'familyId', width: 10 },
    { key: 'name_first', header: 'childFirstName', width: 10 },
    { key: 'gender', header: 'childGender', width: 10 },
    { key: 'gender', header: 'childGender', width: 10 },
    { key: 'age', header: 'childAge', width: 10 },
    { key: 'bike_want', header: 'wantBike', width: 10 },
    { key: 'bike_size', header: 'bikeSize', width: 10 },
    { key: 'bike_style', header: 'bikeStyle', width: 10 },
    { key: 'clothes_want', header: 'wantClothes', width: 10 },
    { key: 'clothes_size_shirt', header: 'shirtSize', width: 10 },
    { key: 'clothes_size_pants', header: 'pantSize', width: 10 },
    { key: 'shoe_size', header: 'shoeSize', width: 10 },
    { key: 'favourite_colour', header: 'favoriteColor', width: 10 },
    { key: 'childNotes', header: 'childNotes', width: 10 },
    { key: 'additional_ideas', header: 'additionalIdeas', width: 10 }
  ];

  const children = await db.child.findAll({
    include: [{
      model: db.household,
      as: 'household',
      where: { approved: true },
      required: true
    }]
  });

  children.forEach(child => {
    child.childNotes = ''; // Link needs this but we don't support it...
    worksheet.addRow(flatten('household', child.toJSON())).commit();
  });
  worksheet.commit();

  await workbook.commit();
}

async function bike_report(req: UserRequest<AdminRole>, res: Response) {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectBikeReport_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  const worksheet = workbook.addWorksheet('Bicycles');
  worksheet.columns = [
    { key: 'household_id', header: 'Family Number', width: 10 },
    { key: 'name_full', header: 'Child Name', width: 15 },
    { key: 'age', header: 'Age', width: 15 },
    { key: 'bike_style', header: 'Bike Style', width: 15 },
    { key: 'bike_size', header: 'Bike Size', width: 15 }
  ];

  const children = await db.child.findAll({
    include: [{
      model: db.household,
      as: 'household',
      where: { approved: true },
      required: true
    }]
  });
  children.forEach(child => worksheet.addRow(flatten('household', child.toJSON())).commit());
  worksheet.commit();
  workbook.commit();
}

async function division_report(req: UserRequest<AdminRole>, res: Response) {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectDivisionReport_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  const worksheet = workbook.addWorksheet('Households');
  worksheet.columns = [
    { key: 'id', header: 'Family Number', width: 10 },
    { key: 'name_full', header: 'Head of Household', width: 15 },
    { key: 'address_street', header: 'Address', width: 15 },
    { key: 'address_street2', header: 'Address line 2', width: 15 },
    { key: 'address_city', header: 'City', width: 15 },
    { key: 'address_state', header: 'State', width: 15 },
    { key: 'address_zip', header: 'Zip', width: 15 },
    { key: 'phone_numbers', header: 'Phone Numbers', width: 15 },
    { key: 'email', header: 'Email', width: 15 },
    { key: 'address_cmpd_division', header: 'Division', width: 15 },
    { key: 'address_cmpd_response_area', header: 'Response Area', width: 15 }
  ];

  const households = await db.household.findAll({
    where: { approved: true },
    include: [
      { model: db.household_address, as: 'address' },
      { model: db.household_phone, as: 'phones' }
    ]
  });
  households.forEach(household => {
    worksheet.addRow(flatten('address', household)).commit();
  });
  worksheet.commit();
  workbook.commit();
}

module.exports = { export_data_excel, link_report, bike_report, division_report };
<commit_msg>Fixed some fields that weren't working right on the LINK report (GIFT-260)<commit_after>// @flow

const Excel = require('exceljs');
const db = require('../../../models');

import type { Response } from '../../lib/typed-express';
import type { UserRequest, AdminRole } from '../../lib/auth';

function headersForExcelFile(name: string): * {
  return {
    'Content-type': 'application/vnd.ms-excel',
    'Content-Disposition': `attachment; filename="${name}.xlsx"`,
    'Cache-Control': 'max-age=0'
  };
}

function flatten(field: string, object: Object): Object {
  const ret = Object.assign({}, object);
  for (const k in object[field]) {
    ret[`${field}_${k}`] = object[field][k];
  }
  return ret;
}

async function export_data_excel(req: UserRequest<AdminRole>, res: Response): Promise<void> {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectDump_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  const columnSpecs = {
    household: {},
    child: {},
    household_address: {},
    household_phone: {},
    user: { id: { width: 3 } }
  };

  for (const table in columnSpecs) {
    const data = await db[table].findAll();
    const worksheet = workbook.addWorksheet(table);
    const cols = [];
    for (const col of Object.getOwnPropertyNames(columnSpecs[table])) {
      if (columnSpecs[table][col] !== false) {
        cols.push(Object.assign({}, { key: col, header: col, width: 10 }, columnSpecs[table][col]));
      }
    }
    if (data[0]) {
      for (const col in data[0].toJSON()) {
        if (!(col in columnSpecs[table])) {
          cols.push({ key: col, header: col, width: 10 });
        }
      }
    }
    worksheet.columns = cols;
    data.forEach(row => {
      if (row.vault !== undefined) {
        row = Object.assign(row, row.vault);
        delete row.vault;
      }
      worksheet.addRow(row).commit();
    });
    worksheet.commit();
  }
  await workbook.commit();
}

async function link_report(req: UserRequest<AdminRole>, res: Response) {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectTheLinkReport_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  let worksheet = workbook.addWorksheet('Household Report');
  worksheet.columns = [
    { key: 'id', header: 'familyId', width: 10 },
    { key: 'name_last', header: 'familyHeadFirst', width: 15 },
    { key: 'name_first', header: 'familyHeadLast', width: 15 },
    { key: 'approved', header: 'familyApproved', width: 15 },
    { key: 'blocked', header: 'familyBlocked', width: 15 },
  ];

  const households = await db.household.findAll();
  // const households = await db.household.findAll({ where: { approved: true } });
  households.forEach(household => {
    // See GIFT-260
    household.approved = (household.approved) ? 1 : 0;
    household.blocked = (household.deleted) ? 1 : 0;
    worksheet.addRow(household).commit();
  });
  worksheet.commit();

  worksheet = workbook.addWorksheet('Child Report');
  worksheet.columns = [
    { key: 'id', header: 'childId', width: 10 },
    { key: 'household_id', header: 'familyId', width: 10 },
    { key: 'name_first', header: 'childFirstName', width: 10 },
    { key: 'gender', header: 'childGender', width: 10 },
    { key: 'age', header: 'childAge', width: 10 },
    { key: 'bike_want', header: 'wantBike', width: 10 },
    { key: 'bike_size', header: 'bikeSize', width: 10 },
    { key: 'bike_style', header: 'bikeStyle', width: 10 },
    { key: 'clothes_want', header: 'wantClothes', width: 10 },
    { key: 'clothes_size_shirt', header: 'shirtSize', width: 10 },
    { key: 'clothes_size_pants', header: 'pantSize', width: 10 },
    { key: 'shoe_size', header: 'shoeSize', width: 10 },
    { key: 'favourite_colour', header: 'favoriteColor', width: 10 },
    { key: 'childNotes', header: 'childNotes', width: 10 },
    { key: 'additional_ideas', header: 'additionalIdeas', width: 10 }
  ];

  const children = await db.child.findAll({
    include: [{
      model: db.household,
      as: 'household',
      where: { approved: true },
      required: true
    }]
  });

  children.forEach(child => {
    child.childNotes = ''; // Link needs this but we don't support it...
    const childData = child.toJSON();
    childData.age = child.age; // Need to append virtual fields
    childData.gender = child.gender; // For some reason this doesn't get auto-included
    worksheet.addRow(flatten('household', childData)).commit();
  });
  worksheet.commit();

  await workbook.commit();
}

async function bike_report(req: UserRequest<AdminRole>, res: Response) {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectBikeReport_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  const worksheet = workbook.addWorksheet('Bicycles');
  worksheet.columns = [
    { key: 'household_id', header: 'Family Number', width: 10 },
    { key: 'name_full', header: 'Child Name', width: 15 },
    { key: 'age', header: 'Age', width: 15 },
    { key: 'bike_style', header: 'Bike Style', width: 15 },
    { key: 'bike_size', header: 'Bike Size', width: 15 }
  ];

  const children = await db.child.findAll({
    include: [{
      model: db.household,
      as: 'household',
      where: { approved: true },
      required: true
    }]
  });
  children.forEach(child => worksheet.addRow(flatten('household', child.toJSON())).commit());
  worksheet.commit();
  workbook.commit();
}

async function division_report(req: UserRequest<AdminRole>, res: Response) {
  const now = new Date().toISOString();
  res.set(headersForExcelFile(`GiftProjectDivisionReport_${now}`));

  const workbook = new Excel.stream.xlsx.WorkbookWriter({ stream: res });

  const worksheet = workbook.addWorksheet('Households');
  worksheet.columns = [
    { key: 'id', header: 'Family Number', width: 10 },
    { key: 'name_full', header: 'Head of Household', width: 15 },
    { key: 'address_street', header: 'Address', width: 15 },
    { key: 'address_street2', header: 'Address line 2', width: 15 },
    { key: 'address_city', header: 'City', width: 15 },
    { key: 'address_state', header: 'State', width: 15 },
    { key: 'address_zip', header: 'Zip', width: 15 },
    { key: 'phone_numbers', header: 'Phone Numbers', width: 15 },
    { key: 'email', header: 'Email', width: 15 },
    { key: 'address_cmpd_division', header: 'Division', width: 15 },
    { key: 'address_cmpd_response_area', header: 'Response Area', width: 15 }
  ];

  const households = await db.household.findAll({
    where: { approved: true },
    include: [
      { model: db.household_address, as: 'address' },
      { model: db.household_phone, as: 'phones' }
    ]
  });
  households.forEach(household => {
    worksheet.addRow(flatten('address', household)).commit();
  });
  worksheet.commit();
  workbook.commit();
}

module.exports = { export_data_excel, link_report, bike_report, division_report };
<|endoftext|>


<commit_before>define([], function() {
  'use strict';

  var hasExactProperties = function(obj) {
    var keys = Object.keys(obj);
    keys.sort();
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
      args.push(arguments[i]);
    }
    args.sort();
    if (keys.length != args.length) {
      return false;
    }
    for (i = 0; i < keys.length; i++) {
      if (keys[i] != args[i]) {
        return false;
      }
    }
    return true;
  };

  var isRefineStart = function(state) {
    return hasExactProperties(state, 'partition') ||
        hasExactProperties(state, 'partition', 'individualizedIndex');
  };

  var isChooseActiveIndex = function(state) {
    var keys = Object.keys(state);
    return keys.indexOf('activeIndexes') != -1 && keys.indexOf('activeIndex') == -1;
  };

  var isChosenActiveIndex = function(state) {
    var keys = Object.keys(state);
    return keys.indexOf('activeIndex') != -1 && keys.indexOf('activeIndexIndex') == -1;
  };

  var isAccumulateAdjacentCells = function(state) {
    return Object.keys(state).indexOf('activeIndexIndex') != -1;
  };

  var isSortAndSplit = function(state) {
    var keys = Object.keys(state);
    return keys.indexOf('nbhdIndex') == -1 &&
           keys.indexOf('activeIndexIndex') == -1 &&
           keys.indexOf('adjacencyCounts') != -1;
  };

  var next = function(state) {
    if (isRefineStart(state)) {
      return nextRefineStart(state);
    }
    if (isChooseActiveIndex(state)) {
      return nextChooseActiveIndex(state);
    }
    if (isChosenActiveIndex(state)) {
      return nextChosenActiveIndex(state);
    }
    if (isAccumulateAdjacentCells(state)) {
      return nextAccumulateAdjacentCells(state);
    }
    if (isSortAndSplit(state)) {
      return nextSortAndSplit(state);
    }
  };

  var nextRefineStart = function(state) {
    return {
      partition: state.partition,
      activeIndexes: state.partition.indexes()
    };
  };

  var nextChooseActiveIndex = function(state) {
    var smallestActiveIndex = state.activeIndexes[0];
    var smallestActiveIndexSize = state.partition.indexSize(smallestActiveIndex);
    var smallestActiveIndexIndex = 0;
    for (var i = 1; i < state.activeIndexes.length; i++) {
      var activeIndex = state.activeIndexes[i];
      var size = state.partition.indexSize(activeIndex);
      if (size < smallestActiveIndexSize) {
        smallestActiveIndexSize = size;
        smallestActiveIndex = activeIndex;
        smallestActiveIndexIndex = i;
      }
    }
    var activeIndexes = state.activeIndexes.splice(0);
    activeIndexes.splice(smallestActiveIndexIndex, 1);
    return {
      partition: state.partition,
      activeIndexes: activeIndexes,
      activeIndex: smallestActiveIndex
    };
  };

  var nextChosenActiveIndex = function(state) {
    return {
      partition: state.partition,
      activeIndexes: state.activeIndexes,
      activeIndex: state.activeIndex,
      activeIndexIndex: 0
    };
  };

  var nextAccumulateAdjacentCells = function(state) {
    var nbhdIndex = state.nbhdIndex + 1 || 0;
    var adjacencyCounts = state.adjacencyCounts || {};
    var u = state.partition.cell(state.activeIndex)[state.activeIndexIndex];
    var nbhd = state.graph.nbhd(u);
    var nextState = {
      graph: state.graph,
      partition: state.partition,
      activeIndexes: state.activeIndexes,
      activeIndex: state.activeIndex,
      activeIndexIndex: state.activeIndexIndex,
      adjacencyCounts: adjacencyCounts
    };
    if (nbhdIndex == nbhd.length) {
      nextState.nbhdIndex = undefined;
      nextState.activeIndexIndex++;
      if (nextState.activeIndexIndex == state.partition.indexSize(state.activeIndex)) {
        nextState.activeIndexIndex = undefined;
      }
      return nextState;
    }
    var v = nbhd[nbhdIndex];
    if (v in adjacencyCounts) {
      adjacencyCounts[v]++;
    } else {
      adjacencyCounts[v] = 1;
    }
    nextState.nbhdIndex = nbhdIndex;
    return nextState;
  };

  var nextSortAndSplit = function(state) {
    // TODO: Implement.
  };

  // A map from string to width,height objects
  var elementDimensions = {};

  var populateUnseenDimensions = function(elements, svg) {
    var unseen = [];
    for (var i = 0; i < elements.length; i++) {
      var e = elements[i];
      if (!elementDimensions[e]) {
        unseen.push(e);
      }
    }
    var texts = svg.append('defs')
      .classed('dimensions-to-remove', true)
      .selectAll('text')
        .data(unseen)
      .enter().append('text')
        .text(function(d) { return d; });

    texts.each(function(d) {
      var bbox = this.getBBox();
      elementDimensions[d] = {width: bbox.width, height: bbox.height};
    });

    svg.select('.dimensions-to-remove')
      .remove();
  };

  var partitionBlockDimensions = function(elements, svg) {
    var blockWidth = 0;
    var blockHeight = 0;
    console.log(elements);
    populateUnseenDimensions(elements, svg);
    for (var i = 0; i < elements.length; i++) {
      var e = elements[i];
      var dims = elementDimensions[e];
      blockWidth = Math.max(dims.width, blockWidth);
      blockHeight = Math.max(dims.height, blockHeight);
    }
    return {width: blockWidth * 1.818, height: blockHeight * 1.1};
  };

  function PartitionRenderer(blockWidth, blockHeight) {
    this.appendLine = function(enter) {
      var multiplyByBlockWidth = function(d) {
        return blockWidth * d;
      };
      return enter.append('line')
          .attr('y1', 0)
          .attr('y2', blockHeight)
          .attr('x1', multiplyByBlockWidth)
          .attr('x2', multiplyByBlockWidth)
          .style('stroke', 'black')
          .classed('cellseparator', true);
    };

    this.xfunction = function(positions) {
      return function(d) {
        return blockWidth * positions[d];
      };
    };
  }

  var graphVertexRadius = function(elements, svg) {
    var maxDim = 0;
    populateUnseenDimensions(elements, svg);
    for (var i = 0; i < elements.length; i++) {
      var e = elements[i];
      var dims = elementDimensions[e];
      maxDim = Math.max(maxDim, Math.sqrt(
          dims.width * dims.width + dims.height * dims.height));
    }
    return (maxDim / 2) * 1.1;
  };

  var renderPartition = function(p, blockWidth, blockHeight, group) {
    var elements = p.domain();
    var indexes = p.indexes();

    group.append('rect')
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', blockWidth * elements.length)
        .attr('height', blockHeight)
        .style({
          fill: 'none',
          stroke: 'black',
          'stroke-width': 1
        });

    var lineselect = group.selectAll('line');
    var renderer = new PartitionRenderer(blockWidth, blockHeight);
    renderer.appendLine(lineselect.data(indexes).enter());

    var positions = {};

    (function() {
      var pos = 0;
      var cells = p.cells();
      for (var i = 0; i < cells.length; i++) {
        var cell = cells[i];
        for (var j = 0; j < cell.length; j++) {
          var e = cell[j];
          positions[e] = pos;
          pos++;
        }
      }
    })();

    var elementsselect = group.selectAll('svg');
    elementsselect.data(elements)
      .enter().append('svg')
        .attr('x', renderer.xfunction(positions))
        .attr('y', 0)
        .attr('width', blockWidth)
        .attr('height', blockHeight)
        .classed('elementholder', true)
        .append('text')
            .text(function(d) { return d; })
            .attr('text-anchor', 'middle')
            .attr('x', '50%')
            .attr('y', '50%')
            .style('dominant-baseline', 'central');

    return new RenderedPartition(group, renderer);
  };

  function RenderedPartition(group, renderer) {

    this.transitionToPartition = function(newElements, newIndexes) {
      var lineselect = group.selectAll('line.cellseparator')
        .data(newIndexes, function(d) { return d; });
      renderer.appendLine(lineselect.enter())
        .style('opacity', 0)
        .transition()
        .duration(1000)
        .style('opacity', 1);
      lineselect.exit()
        .transition()
        .duration(1000)
        .style('opacity', 0)
        .each('end', function() {
            d3.select(this).remove();
          });

      var newPositions = {};
      for (var i = 0; i < newElements.length; i++) {
        var e = newElements[i];
        newPositions[e] = i;
      }
      group.selectAll('.elementholder')
        .transition()
        .duration(1000)
        .attr('x', renderer.xfunction(newPositions));
    };
  }

  var renderGraph = function(g, radius, width, height, top) {
    var vertexes = g.vertexes();
    var vertexToNode = {};
    var nodes = [];
    (function() {
      for (var i = 0; i < vertexes.length; i++) {
        var v = vertexes[i];
        var node = {v: v};
        nodes.push(node);
        vertexToNode[v] = node;
      }
    })();
    var links = [];
    (function() {
      for (var i = 0; i < vertexes.length; i++) {
        var u = vertexes[i];
        var nbhd = g.nbhd(u);
        for (var j = 0; j < nbhd.length; j++) {
          var v = nbhd[j];
          links.push({source: vertexToNode[u], target: vertexToNode[v]});
        }
      }
    })();
    var lines = top.selectAll('line')
        .data(links)
      .enter().append('line')
        .style('stroke', 'black');
    var vertexGroups = top.selectAll('g')
        .data(nodes)
      .enter().append('g');
    vertexGroups.append('circle')
        .attr('r', radius)
        .style('fill', 'white')
        .style('stroke', 'black');
    vertexGroups.append('text')
        .text(function(d) {
          return d.v;
        })
        .style('text-anchor', 'middle')
        .style('dominant-baseline', 'middle');

    var tick = function() {
      lines.attr('x1', function(d) { return d.source.x; })
          .attr('y1', function(d) { return d.source.y; })
          .attr('x2', function(d) { return d.target.x; })
          .attr('y2', function(d) { return d.target.y; });
      vertexGroups.attr('transform', function(d) {
        return 'translate(' + d.x + ',' + d.y + ')';
      });
    };
    var force = d3.layout.force()
        .size([width, height])
        .nodes(nodes)
        .links(links)
        .linkDistance(4 * radius)
        .friction(0.9)
        .charge(-90)
        .linkStrength(0.02)
        .on('tick', tick);
    vertexGroups.call(force.drag);
    force.start();
  };

  return {
    isChooseActiveIndex: isChooseActiveIndex,
    isRefineStart: isRefineStart,
    next: next,
    renderPartition: renderPartition,
    partitionBlockDimensions: partitionBlockDimensions,
    renderGraph: renderGraph,
    graphVertexRadius: graphVertexRadius
  };
});
<commit_msg>Add stubs for highlighting<commit_after>define([], function() {
  'use strict';

  var hasExactProperties = function(obj) {
    var keys = Object.keys(obj);
    keys.sort();
    var args = [];
    for (var i = 1; i < arguments.length; i++) {
      args.push(arguments[i]);
    }
    args.sort();
    if (keys.length != args.length) {
      return false;
    }
    for (i = 0; i < keys.length; i++) {
      if (keys[i] != args[i]) {
        return false;
      }
    }
    return true;
  };

  var isRefineStart = function(state) {
    return hasExactProperties(state, 'partition') ||
        hasExactProperties(state, 'partition', 'individualizedIndex');
  };

  var isChooseActiveIndex = function(state) {
    var keys = Object.keys(state);
    return keys.indexOf('activeIndexes') != -1 && keys.indexOf('activeIndex') == -1;
  };

  var isChosenActiveIndex = function(state) {
    var keys = Object.keys(state);
    return keys.indexOf('activeIndex') != -1 && keys.indexOf('activeIndexIndex') == -1;
  };

  var isAccumulateAdjacentCells = function(state) {
    return Object.keys(state).indexOf('activeIndexIndex') != -1;
  };

  var isSortAndSplit = function(state) {
    var keys = Object.keys(state);
    return keys.indexOf('nbhdIndex') == -1 &&
           keys.indexOf('activeIndexIndex') == -1 &&
           keys.indexOf('adjacencyCounts') != -1;
  };

  var next = function(state) {
    if (isRefineStart(state)) {
      return nextRefineStart(state);
    }
    if (isChooseActiveIndex(state)) {
      return nextChooseActiveIndex(state);
    }
    if (isChosenActiveIndex(state)) {
      return nextChosenActiveIndex(state);
    }
    if (isAccumulateAdjacentCells(state)) {
      return nextAccumulateAdjacentCells(state);
    }
    if (isSortAndSplit(state)) {
      return nextSortAndSplit(state);
    }
  };

  var nextRefineStart = function(state) {
    return {
      partition: state.partition,
      activeIndexes: state.partition.indexes()
    };
  };

  var nextChooseActiveIndex = function(state) {
    var smallestActiveIndex = state.activeIndexes[0];
    var smallestActiveIndexSize = state.partition.indexSize(smallestActiveIndex);
    var smallestActiveIndexIndex = 0;
    for (var i = 1; i < state.activeIndexes.length; i++) {
      var activeIndex = state.activeIndexes[i];
      var size = state.partition.indexSize(activeIndex);
      if (size < smallestActiveIndexSize) {
        smallestActiveIndexSize = size;
        smallestActiveIndex = activeIndex;
        smallestActiveIndexIndex = i;
      }
    }
    var activeIndexes = state.activeIndexes.splice(0);
    activeIndexes.splice(smallestActiveIndexIndex, 1);
    return {
      partition: state.partition,
      activeIndexes: activeIndexes,
      activeIndex: smallestActiveIndex
    };
  };

  var nextChosenActiveIndex = function(state) {
    return {
      partition: state.partition,
      activeIndexes: state.activeIndexes,
      activeIndex: state.activeIndex,
      activeIndexIndex: 0
    };
  };

  var nextAccumulateAdjacentCells = function(state) {
    var nbhdIndex = state.nbhdIndex + 1 || 0;
    var adjacencyCounts = state.adjacencyCounts || {};
    var u = state.partition.cell(state.activeIndex)[state.activeIndexIndex];
    var nbhd = state.graph.nbhd(u);
    var nextState = {
      graph: state.graph,
      partition: state.partition,
      activeIndexes: state.activeIndexes,
      activeIndex: state.activeIndex,
      activeIndexIndex: state.activeIndexIndex,
      adjacencyCounts: adjacencyCounts
    };
    if (nbhdIndex == nbhd.length) {
      nextState.nbhdIndex = undefined;
      nextState.activeIndexIndex++;
      if (nextState.activeIndexIndex == state.partition.indexSize(state.activeIndex)) {
        nextState.activeIndexIndex = undefined;
      }
      return nextState;
    }
    var v = nbhd[nbhdIndex];
    if (v in adjacencyCounts) {
      adjacencyCounts[v]++;
    } else {
      adjacencyCounts[v] = 1;
    }
    nextState.nbhdIndex = nbhdIndex;
    return nextState;
  };

  var nextSortAndSplit = function(state) {
    // TODO: Implement.
  };

  // A map from string to width,height objects
  var elementDimensions = {};

  var populateUnseenDimensions = function(elements, svg) {
    var unseen = [];
    for (var i = 0; i < elements.length; i++) {
      var e = elements[i];
      if (!elementDimensions[e]) {
        unseen.push(e);
      }
    }
    var texts = svg.append('defs')
      .classed('dimensions-to-remove', true)
      .selectAll('text')
        .data(unseen)
      .enter().append('text')
        .text(function(d) { return d; });

    texts.each(function(d) {
      var bbox = this.getBBox();
      elementDimensions[d] = {width: bbox.width, height: bbox.height};
    });

    svg.select('.dimensions-to-remove')
      .remove();
  };

  var partitionBlockDimensions = function(elements, svg) {
    var blockWidth = 0;
    var blockHeight = 0;
    console.log(elements);
    populateUnseenDimensions(elements, svg);
    for (var i = 0; i < elements.length; i++) {
      var e = elements[i];
      var dims = elementDimensions[e];
      blockWidth = Math.max(dims.width, blockWidth);
      blockHeight = Math.max(dims.height, blockHeight);
    }
    return {width: blockWidth * 1.818, height: blockHeight * 1.1};
  };

  function PartitionRenderer(blockWidth, blockHeight) {
    this.appendLine = function(enter) {
      var multiplyByBlockWidth = function(d) {
        return blockWidth * d;
      };
      return enter.append('line')
          .attr('y1', 0)
          .attr('y2', blockHeight)
          .attr('x1', multiplyByBlockWidth)
          .attr('x2', multiplyByBlockWidth)
          .style('stroke', 'black')
          .classed('cellseparator', true);
    };

    this.xfunction = function(positions) {
      return function(d) {
        return blockWidth * positions[d];
      };
    };
  }

  var graphVertexRadius = function(elements, svg) {
    var maxDim = 0;
    populateUnseenDimensions(elements, svg);
    for (var i = 0; i < elements.length; i++) {
      var e = elements[i];
      var dims = elementDimensions[e];
      maxDim = Math.max(maxDim, Math.sqrt(
          dims.width * dims.width + dims.height * dims.height));
    }
    return (maxDim / 2) * 1.1;
  };

  var renderPartition = function(p, blockWidth, blockHeight, group) {
    var elements = p.domain();
    var indexes = p.indexes();

    group.append('rect')
        .attr('x', 0)
        .attr('y', 0)
        .attr('width', blockWidth * elements.length)
        .attr('height', blockHeight)
        .style({
          fill: 'none',
          stroke: 'black',
          'stroke-width': 1
        });

    var lineselect = group.selectAll('line');
    var renderer = new PartitionRenderer(blockWidth, blockHeight);
    renderer.appendLine(lineselect.data(indexes).enter());

    var positions = {};

    (function() {
      var pos = 0;
      var cells = p.cells();
      for (var i = 0; i < cells.length; i++) {
        var cell = cells[i];
        for (var j = 0; j < cell.length; j++) {
          var e = cell[j];
          positions[e] = pos;
          pos++;
        }
      }
    })();

    var elementsselect = group.selectAll('svg');
    elementsselect.data(elements)
      .enter().append('svg')
        .attr('x', renderer.xfunction(positions))
        .attr('y', 0)
        .attr('width', blockWidth)
        .attr('height', blockHeight)
        .classed('elementholder', true)
        .append('text')
            .text(function(d) { return d; })
            .attr('text-anchor', 'middle')
            .attr('x', '50%')
            .attr('y', '50%')
            .style('dominant-baseline', 'central');

    return new RenderedPartition(group, renderer);
  };

  function RenderedPartition(group, renderer) {

    this.transitionToPartition = function(newElements, newIndexes) {
      var lineselect = group.selectAll('line.cellseparator')
        .data(newIndexes, function(d) { return d; });
      renderer.appendLine(lineselect.enter())
        .style('opacity', 0)
        .transition()
        .duration(1000)
        .style('opacity', 1);
      lineselect.exit()
        .transition()
        .duration(1000)
        .style('opacity', 0)
        .each('end', function() {
            d3.select(this).remove();
          });

      var newPositions = {};
      for (var i = 0; i < newElements.length; i++) {
        var e = newElements[i];
        newPositions[e] = i;
      }
      group.selectAll('.elementholder')
        .transition()
        .duration(1000)
        .attr('x', renderer.xfunction(newPositions));
    };

    this.highlightElement = function(e) {

    };

    this.highlightIndex = function(i) {

    };

    this.unhighlightElement = function(e) {

    };

    this.unhighlightIndex = function(e) {

    };
  }

  var renderGraph = function(g, radius, width, height, top) {
    var vertexes = g.vertexes();
    var vertexToNode = {};
    var nodes = [];
    (function() {
      for (var i = 0; i < vertexes.length; i++) {
        var v = vertexes[i];
        var node = {v: v};
        nodes.push(node);
        vertexToNode[v] = node;
      }
    })();
    var links = [];
    (function() {
      for (var i = 0; i < vertexes.length; i++) {
        var u = vertexes[i];
        var nbhd = g.nbhd(u);
        for (var j = 0; j < nbhd.length; j++) {
          var v = nbhd[j];
          links.push({source: vertexToNode[u], target: vertexToNode[v]});
        }
      }
    })();
    var lines = top.selectAll('line')
        .data(links)
      .enter().append('line')
        .style('stroke', 'black');
    var vertexGroups = top.selectAll('g')
        .data(nodes)
      .enter().append('g');
    vertexGroups.append('circle')
        .attr('r', radius)
        .style('fill', 'white')
        .style('stroke', 'black');
    vertexGroups.append('text')
        .text(function(d) {
          return d.v;
        })
        .style('text-anchor', 'middle')
        .style('dominant-baseline', 'middle');

    var tick = function() {
      lines.attr('x1', function(d) { return d.source.x; })
          .attr('y1', function(d) { return d.source.y; })
          .attr('x2', function(d) { return d.target.x; })
          .attr('y2', function(d) { return d.target.y; });
      vertexGroups.attr('transform', function(d) {
        return 'translate(' + d.x + ',' + d.y + ')';
      });
    };
    var force = d3.layout.force()
        .size([width, height])
        .nodes(nodes)
        .links(links)
        .linkDistance(4 * radius)
        .friction(0.9)
        .charge(-90)
        .linkStrength(0.02)
        .on('tick', tick);
    vertexGroups.call(force.drag);
    force.start();
  };

  function RenderedGraph() {

    this.highlightVertex = function(v) {

    };

    this.unhighlightVertex = function(v) {

    };

    this.highlightEdge = function(u, v) {

    };

    this.unhighlightEdge = function(u, v) {

    };
  }

  return {
    isChooseActiveIndex: isChooseActiveIndex,
    isRefineStart: isRefineStart,
    next: next,
    renderPartition: renderPartition,
    partitionBlockDimensions: partitionBlockDimensions,
    renderGraph: renderGraph,
    graphVertexRadius: graphVertexRadius
  };
});
<|endoftext|>


<commit_before>var noBounce = function(){
	var module = {};

  var settings = {
    preventDefault: true,
    animate: true
  };

	var track = [];

	var velocity = {
		x: 0,
		y: 0
	};

  var vector = {
    subtraction: function(v1, v2){
      return {
        x: v1.x - v2.x,
        y: v1.y - v2.y
      };
    },
    length: function(v) {
		  return Math.sqrt((v.x * v.x) + (v.y * v.y));
	  },
    unit: function(v){
      var length = vector.length(v);
      v.x /= length;
      v.y /= length;
    },
    skalarMult: function(v, s) {
      v.x *= s;
      v.y *= s;
    }
  };

  var requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
    })();

	function handleTouchStart (evt){
    if(settings.preventDefault){
      evt.preventDefault();
    }
		var point,
			touch;

		touch = evt.changedTouches[0];
		point = {
			x: touch.clientX,
			y: touch.clientY,
			timeStamp: evt.timeStamp
		};
		track = [point];
	}

	function handleTouchMove (evt){
		var point,
			touch;

		touch = evt.changedTouches[0];
		point = {
			x: touch.clientX,
			y: touch.clientY,
			timeStamp: evt.timeStamp
		};
		track.push(point);
    doScroll();
	}

	function handleTouchEnd (evt){
		if(track.length > 2 && settings.animate){
			velocity = calcVelocity();
      requestAnimFrame(animate);
		}
	}

	function calcVelocity(){
		var p1,
        p2,
        v,
        timeDiff,
        length;

		p1 = track[0];
		p2 = track[track.length-1];
		timeDiff = p2.timeStamp - p1.timeStamp;
		v = vector.subtraction(p2, p1);
		length = vector.length(v);
		vector.unit(v);
		vector.skalarMult(v, length / timeDiff * 20);
		return v;
	}

  function doScroll(){
    var p1,
        p2,
        x,
        y;

    if(track.length > 1){
      p1 = track[track.length -1];
      p2 = track[track.length -2];
      x = p2.x - p1.x;
      y = p2.y - p1.y;
      window.scrollBy(x, y);
    }
  }

  function animate(){
    scrollBy(-velocity.x, -velocity.y);
    vector.skalarMult(velocity, 0.95);
    if(vector.length(velocity) > 0.2){
      requestAnimFrame(animate);
    }
  }

  module.init = function(options){
    if(typeof options.preventDefault === "boolean"){
      settings.preventDefault = options.preventDefault;
    }
    if(typeof options.animate === "boolean"){
      settings.animate = options.animate;
    }

    document.addEventListener("touchstart", handleTouchStart);
    document.addEventListener("touchmove", handleTouchMove);
    document.addEventListener("touchend", handleTouchEnd);
    document.addEventListener("touchcancel", handleTouchEnd);
    document.addEventListener("touchleave", handleTouchEnd);
  };

	return module;
}();

<commit_msg>Fixed flickering in safari iOS 8.<commit_after>var noBounce = function(){
	var module = {};

  var settings = {
    preventDefault: true,
    animate: true
  };

	var track = [];

	var velocity = {
		x: 0,
		y: 0
	};

  var vector = {
    subtraction: function(v1, v2){
      return {
        x: v1.x - v2.x,
        y: v1.y - v2.y
      };
    },
    length: function(v) {
		  return Math.sqrt((v.x * v.x) + (v.y * v.y));
	  },
    unit: function(v){
      var length = vector.length(v);
      v.x /= length;
      v.y /= length;
    },
    skalarMult: function(v, s) {
      v.x *= s;
      v.y *= s;
    }
  };

  var requestAnimFrame = (function(){
      return  window.requestAnimationFrame       ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame    ||
              window.oRequestAnimationFrame      ||
              window.msRequestAnimationFrame     ||
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
    })();

	function handleTouchStart (evt){
    if(settings.preventDefault){
      evt.preventDefault();
    }
		var point,
			touch;

		touch = evt.changedTouches[0];
		point = {
			x: touch.clientX,
			y: touch.clientY,
			timeStamp: evt.timeStamp
		};
		track = [point];
	}

	function handleTouchMove (evt){
		var point,
			touch;

		touch = evt.changedTouches[0];
		point = {
			x: touch.clientX,
			y: touch.clientY,
			timeStamp: evt.timeStamp
		};
		track.push(point);
    doScroll();
	}

	function handleTouchEnd (evt){
		if(track.length > 2 && settings.animate){
			velocity = calcVelocity();
      requestAnimFrame(animate);
		}
	}

	function calcVelocity(){
		var p1,
        p2,
        v,
        timeDiff,
        length;

		p1 = track[0];
		p2 = track[track.length-1];
		timeDiff = p2.timeStamp - p1.timeStamp;
		v = vector.subtraction(p2, p1);
		length = vector.length(v);
		vector.unit(v);
		vector.skalarMult(v, length / timeDiff * 20);
		return v;
	}

  function doScroll(){
    var p1,
        p2,
        x,
        y;

    if(track.length > 1){
      p1 = track[track.length -1];
      p2 = track[track.length -2];
      x = p2.x - p1.x;
      y = p2.y - p1.y;
      requestAnimFrame(function(){
        window.scrollBy(x, y);
      });
    }
  }

  function animate(){
    scrollBy(-velocity.x, -velocity.y);
    vector.skalarMult(velocity, 0.95);
    if(vector.length(velocity) > 0.2){
      requestAnimFrame(animate);
    }
  }

  module.init = function(options){
    if(typeof options.preventDefault === "boolean"){
      settings.preventDefault = options.preventDefault;
    }
    if(typeof options.animate === "boolean"){
      settings.animate = options.animate;
    }

    document.addEventListener("touchstart", handleTouchStart);
    document.addEventListener("touchmove", handleTouchMove);
    document.addEventListener("touchend", handleTouchEnd);
    document.addEventListener("touchcancel", handleTouchEnd);
    document.addEventListener("touchleave", handleTouchEnd);
  };

	return module;
}();

<|endoftext|>


<commit_before>
// Constants
var	  CANVAS_WIDTH = 700
	, CANVAS_HEIGHT = 500
	, FPS = 30
	, GAME_SPEED = 2
	, ORBITAL_SPEED = 0.005
	, PLANET_RADIUS = 20;

// Add canvas to page
var canvasElement = $("<canvas width='" + CANVAS_WIDTH + "' height='" + CANVAS_HEIGHT + "'></canvas>");
var canvas = canvasElement.get(0).getContext("2d");
canvasElement.appendTo('body');

// Render loop
setInterval(function() {
	draw();
}, 1000/FPS);

// Game loop
setInterval( function(){
	update();
}, 1000/GAME_SPEED);

function update() {

}

function draw() {
	canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

	for( var x = 0; x < testNodes.length; x++ ){
		testNodes[x].draw();
	}
}

// Player class
function Player(pri,sec) {
	this.primaryColor = pri;
	this.secondaryColor = sec;
}

// Planet class
function Planet( player, x, y){
	this.owner = player;
	this.planetRadius = PLANET_RADIUS;
	this.x = x;
	this.y = y;
	this.neighbors = new Array();
	this.lowOrbit = PLANET_RADIUS + PLANET_RADIUS * 0.3;
	this.highOrbit = PLANET_RADIUS + PLANET_RADIUS * 1;
	this.midOrbit = (this.lowOrbit + this.highOrbit) / 2;
	this.posture = 'peaceful';
	this.orbiterAngles = new Array(16);
	this.init();
}

Planet.prototype.init = function(){
	this.initOrbiters();
}

Planet.prototype.initOrbiters = function(){
	for( var x = 0; x < this.orbiterAngles.length; x++ ){
		this.orbiterAngles[x] = Math.random() * 2 * Math.PI;
	}
}

Planet.prototype.ambience = function(){
	if( this.posture == 'peaceful' ){
		this.orbitOrbiter();
	}
}

Planet.prototype.orbitOrbiter = function(){
	for( var x = 0; x < this.orbiterAngles.length; x++ ){
		this.orbiterAngles[x] += ORBITAL_SPEED;
		if ( this.orbiterAngles[x] > (2 * Math.PI) )
			this.orbiterAngles[x] = this.orbiterAngles[x] - (2 * Math.PI);
	}
}

Planet.prototype.drawOrbiters = function(){
	if( this.posture == 'peaceful' ){
		for( var x = 0; x < this.orbiterAngles.length; x++ ){
			canvas.beginPath();
			canvas.arc(this.x, this.y, this.lowOrbit, this.orbiterAngles[x], this.orbiterAngles[x] + 0.02 * Math.PI, false);
			canvas.lineWidth = 1;
			canvas.strokeStyle = this.owner.secondaryColor;
			canvas.stroke();
		}
	}
}

Planet.prototype.drawPlanet = function(){
	canvas.beginPath();
	canvas.arc(this.x, this.y, this.planetRadius, 0, 2 * Math.PI, false);
	canvas.fillStyle = this.owner.primaryColor;
	canvas.fill();
	canvas.lineWidth = 3;
	canvas.strokeStyle = this.owner.secondaryColor;
	canvas.stroke();
}

Planet.prototype.getEdgePoint = function( neighbor ){
	// Get the angle from this planet to the neighbor
	var adj = this.x - neighbor.x;
	var opp = this.y - neighbor.y;
	var theta = Math.atan( opp / adj );

	// Adjust theta for signs not placing theta in the correct quadrent
	if( adj > 0 && opp > 0 )
		theta += Math.PI;
	if( adj > 0 && opp < 0 )
		theta += Math.PI;

	// Triangulate coordinate
	var edgeX = this.x + Math.cos( theta ) * this.highOrbit;
	var edgeY = this.y + Math.sin( theta ) * this.highOrbit;
	return { x: edgeX, y: edgeY };
}

Planet.prototype.drawEdgePoints = function(){
	for ( var x = 0; x < this.neighbors.length; x++ ) {
		var coords = this.getEdgePoint( this.neighbors[x] );
		canvas.beginPath();
		canvas.arc( coords.x, coords.y, 4, 0, 2 * Math.PI, false );
		canvas.fillStyle = this.owner.primaryColor;
		canvas.fill();
	}
}

Planet.prototype.drawEdgeConnections = function(){
	for ( var x = 0; x < this.neighbors.length; x++ ) {
		var thisCoords = this.getEdgePoint( this.neighbors[x] );
		var neighborCoords = this.neighbors[x].getEdgePoint( this );

		// Line connecting planets
		canvas.beginPath();
		canvas.moveTo( thisCoords.x, thisCoords.y );
		canvas.lineTo( neighborCoords.x, neighborCoords.y );
		canvas.lineWidth = 1;
		canvas.stroke();
	}
}

Planet.prototype.draw = function(){
	this.ambience();
	this.drawPlanet();
	this.drawOrbiters();
	//this.drawEdgePoints();
	this.drawEdgeConnections();
}

var player1 = new Player("#9B59B6", "#8E44AD");
var testNodes = [];
testNodes.push( new Planet(player1,300,200) );
testNodes.push( new Planet(player1,450,100) );
testNodes.push( new Planet(player1,600,150) );
testNodes[0].neighbors.push( testNodes[1] );
testNodes[1].neighbors.push( testNodes[0] );
testNodes[2].neighbors.push( testNodes[1] );
testNodes[1].neighbors.push( testNodes[2] );
testNodes[0].neighbors.push( testNodes[2] );
testNodes[2].neighbors.push( testNodes[0] );
console.log(testNodes);
//testNodes[0].getEdgePoint( testNodes[1] );

<commit_msg>Added edge connections<commit_after>
// Constants
var	  CANVAS_WIDTH = 700
	, CANVAS_HEIGHT = 500
	, FPS = 30
	, GAME_SPEED = 2
	, ORBITAL_SPEED = 0.005
	, PLANET_RADIUS = 20;

// Add canvas to page
var canvasElement = $("<canvas width='" + CANVAS_WIDTH + "' height='" + CANVAS_HEIGHT + "'></canvas>");
var canvas = canvasElement.get(0).getContext("2d");
canvasElement.appendTo('body');

// Render loop
setInterval(function() {
	draw();
}, 1000/FPS);

// Game loop
setInterval( function(){
	update();
}, 1000/GAME_SPEED);

function update() {

}

function draw() {
	canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

	for( var x = 0; x < testNodes.length; x++ ){
		testNodes[x].draw();
	}
}

// Player class
function Player(pri,sec) {
	this.primaryColor = pri;
	this.secondaryColor = sec;
}

// Planet class
function Planet( player, x, y){
	this.owner = player;
	this.planetRadius = PLANET_RADIUS;
	this.x = x;
	this.y = y;
	this.neighbors = new Array();
	this.lowOrbit = PLANET_RADIUS + PLANET_RADIUS * 0.3;
	this.highOrbit = PLANET_RADIUS + PLANET_RADIUS * 1;
	this.midOrbit = (this.lowOrbit + this.highOrbit) / 2;
	this.posture = 'peaceful';
	this.orbiterAngles = new Array(16);
	this.init();
}

Planet.prototype.init = function(){
	this.initOrbiters();
}

Planet.prototype.initOrbiters = function(){
	for( var x = 0; x < this.orbiterAngles.length; x++ ){
		this.orbiterAngles[x] = Math.random() * 2 * Math.PI;
	}
}

Planet.prototype.ambience = function(){
	if( this.posture == 'peaceful' ){
		this.orbitOrbiter();
	}
}

Planet.prototype.orbitOrbiter = function(){
	for( var x = 0; x < this.orbiterAngles.length; x++ ){
		this.orbiterAngles[x] += ORBITAL_SPEED;
		if ( this.orbiterAngles[x] > (2 * Math.PI) )
			this.orbiterAngles[x] = this.orbiterAngles[x] - (2 * Math.PI);
	}
}

Planet.prototype.drawOrbiters = function(){
	if( this.posture == 'peaceful' ){
		for( var x = 0; x < this.orbiterAngles.length; x++ ){
			canvas.beginPath();
			canvas.arc(this.x, this.y, this.lowOrbit, this.orbiterAngles[x], this.orbiterAngles[x] + 0.02 * Math.PI, false);
			canvas.lineWidth = 1;
			canvas.strokeStyle = this.owner.secondaryColor;
			canvas.stroke();
		}
	}
}

Planet.prototype.drawPlanet = function(){
	canvas.beginPath();
	canvas.arc(this.x, this.y, this.planetRadius, 0, 2 * Math.PI, false);
	canvas.fillStyle = this.owner.primaryColor;
	canvas.fill();
	canvas.lineWidth = 3;
	canvas.strokeStyle = this.owner.secondaryColor;
	canvas.stroke();
}

Planet.prototype.getEdgePoint = function( neighbor ){
	// Get the angle from this planet to the neighbor
	var adj = this.x - neighbor.x;
	var opp = this.y - neighbor.y;
	var theta = Math.atan( opp / adj );

	// Adjust theta for signs not placing theta in the correct quadrent
	if( adj > 0 && opp > 0 )
		theta += Math.PI;
	if( adj > 0 && opp < 0 )
		theta += Math.PI;

	// Triangulate coordinate
	var edgeX = this.x + Math.cos( theta ) * this.highOrbit;
	var edgeY = this.y + Math.sin( theta ) * this.highOrbit;
	return { x: edgeX, y: edgeY };
}

Planet.prototype.drawEdgePoints = function(){
	for ( var x = 0; x < this.neighbors.length; x++ ) {
		var coords = this.getEdgePoint( this.neighbors[x] );
		canvas.beginPath();
		canvas.arc( coords.x, coords.y, 4, 0, 2 * Math.PI, false );
		canvas.fillStyle = this.owner.primaryColor;
		canvas.fill();
	}
}

Planet.prototype.drawEdgeConnections = function(){
	for ( var x = 0; x < this.neighbors.length; x++ ) {
		var thisCoords = this.getEdgePoint( this.neighbors[x] );
		var neighborCoords = this.neighbors[x].getEdgePoint( this );

		// Line connecting planets
		canvas.beginPath();
		canvas.moveTo( thisCoords.x, thisCoords.y );
		canvas.lineTo( neighborCoords.x, neighborCoords.y );
		canvas.lineWidth = 0.2;
		canvas.stroke();
	}
}

Planet.prototype.draw = function(){
	this.ambience();
	this.drawPlanet();
	this.drawOrbiters();
	//this.drawEdgePoints();
	this.drawEdgeConnections();
}

var player1 = new Player("#9B59B6", "#8E44AD");
var testNodes = [];
testNodes.push( new Planet(player1,300,200) );
testNodes.push( new Planet(player1,450,100) );
testNodes.push( new Planet(player1,600,150) );
testNodes[0].neighbors.push( testNodes[1] );
testNodes[1].neighbors.push( testNodes[0] );
testNodes[2].neighbors.push( testNodes[1] );
testNodes[1].neighbors.push( testNodes[2] );
testNodes[0].neighbors.push( testNodes[2] );
testNodes[2].neighbors.push( testNodes[0] );
console.log(testNodes);
//testNodes[0].getEdgePoint( testNodes[1] );

<|endoftext|>


<commit_before>import Permission from './Permission'
import {UnprocessableEntityAPIError} from './APIError'
import { URL } from 'url'

export const FrontierRedeemCode = /^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-FUE[0-9]{2}$/
export const IRCVirtualHost = /^[a-z][a-z0-9.]{3,64}$/
export const CMDRname = /^[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control} ]{3,64}$/u
export const ShipName = /^[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control} ]{3,22}$/u
export const OAuthClientName = /^[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}\p{Punctuation}\p{Space_Separator}]{3,64}$/u
export const ISO8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?))?)?$/
export const IRCNickname = /^[A-Za-z_\\`\[\]{}][A-Za-z0-9_\\`\[\]{}]*/
export const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i

/**
 * Validate wether a list of OAuth Scopes is valid
 * @param value the list of OAuth scopes to validate
 * @constructor
 */
export function OAuthScope (value) {
  for (let scope of value) {
    if (Permission.allPermissions.includes(scope) === false && scope !== '*') {
      throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/scope' })
    }
  }
}

/**
 * Validate wether a value is a valid JSON object for a jsonb field
 * @param value the value to validate
 * @constructor
 */
export function JSONObject (value) {
  if (typeof value !== 'object') {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/data' })
  }
}

const requiredQuoteFields = [
  'message',
  'author',
  'lastAuthor',
  'createdAt',
  'updatedAt'
]

/**
 * Validate wether a value is a valid list of rescue quotes
 * @param value the list of rescue quotes to validate
 * @constructor
 */
export function RescueQuote (value) {
  try {
    value.forEach(quote => {
      quote = JSON.parse(quote)
      requiredQuoteFields.forEach(requiredField => {
        if (quote.hasOwnProperty(requiredField) === false) {
          throw Error()
        }
      })

      for (let [key, value] of Object.entries(quote)) {
        switch (key) {
          case 'message':
            if (typeof value !== 'string') {
              throw Error()
            }
            break

          case 'author':
          case 'lastAuthor':
            if (value !== null && typeof value !== 'string') {
              throw Error()
            }
            break

          case 'createdAt':
          case 'updatedAt':
            if (value !== null && ISO8601.test(value) === false) {
              throw Error()
            }
            break

          default:
            throw Error()
        }
      }
    })
  } catch (ex) {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/quotes' })
  }
}

/**
 * Validate wether a value is a valid list of IRC nicknames
 * @param value the list of IRC nicknames to validate
 * @constructor
 */
export function IRCNicknames (value) {
  if (!Array.isArray(value)) {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/nicknames' })
  }
  value.forEach(nickname => {
    if (!IRCNickname.test(nickname)) {
      throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/nicknames' })
    }
  })
}

/**
 * Validate wether a value is a valid URL
 * @param value the URL to validate
 * @constructor
 */
export function isURL (value) {
  try {
    new URL(value)
  } catch (ex) {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/redirectUri' })
  }
}
<commit_msg>Fix mistake in parsing quotes<commit_after>import Permission from './Permission'
import {UnprocessableEntityAPIError} from './APIError'
import { URL } from 'url'

export const FrontierRedeemCode = /^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-FUE[0-9]{2}$/
export const IRCVirtualHost = /^[a-z][a-z0-9.]{3,64}$/
export const CMDRname = /^[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control} ]{3,64}$/u
export const ShipName = /^[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control} ]{3,22}$/u
export const OAuthClientName = /^[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}\p{Punctuation}\p{Space_Separator}]{3,64}$/u
export const ISO8601 = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?))?)?$/
export const IRCNickname = /^[A-Za-z_\\`\[\]{}][A-Za-z0-9_\\`\[\]{}]*/
export const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i

/**
 * Validate wether a list of OAuth Scopes is valid
 * @param value the list of OAuth scopes to validate
 * @constructor
 */
export function OAuthScope (value) {
  for (let scope of value) {
    if (Permission.allPermissions.includes(scope) === false && scope !== '*') {
      throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/scope' })
    }
  }
}

/**
 * Validate wether a value is a valid JSON object for a jsonb field
 * @param value the value to validate
 * @constructor
 */
export function JSONObject (value) {
  if (typeof value !== 'object') {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/data' })
  }
}

const requiredQuoteFields = [
  'message',
  'author',
  'lastAuthor',
  'createdAt',
  'updatedAt'
]

/**
 * Validate wether a value is a valid list of rescue quotes
 * @param value the list of rescue quotes to validate
 * @constructor
 */
export function RescueQuote (value) {
  try {
    value.forEach(quote => {
      requiredQuoteFields.forEach(requiredField => {
        if (quote.hasOwnProperty(requiredField) === false) {
          throw Error()
        }
      })

      for (let [key, value] of Object.entries(quote)) {
        switch (key) {
          case 'message':
            if (typeof value !== 'string') {
              throw Error()
            }
            break

          case 'author':
          case 'lastAuthor':
            if (value !== null && typeof value !== 'string') {
              throw Error()
            }
            break

          case 'createdAt':
          case 'updatedAt':
            if (value !== null && ISO8601.test(value) === false) {
              throw Error()
            }
            break

          default:
            throw Error()
        }
      }
    })
  } catch (ex) {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/quotes' })
  }
}

/**
 * Validate wether a value is a valid list of IRC nicknames
 * @param value the list of IRC nicknames to validate
 * @constructor
 */
export function IRCNicknames (value) {
  if (!Array.isArray(value)) {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/nicknames' })
  }
  value.forEach(nickname => {
    if (!IRCNickname.test(nickname)) {
      throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/nicknames' })
    }
  })
}

/**
 * Validate wether a value is a valid URL
 * @param value the URL to validate
 * @constructor
 */
export function isURL (value) {
  try {
    new URL(value)
  } catch (ex) {
    throw new UnprocessableEntityAPIError({ pointer: '/data/attributes/redirectUri' })
  }
}
<|endoftext|>


<commit_before>
import {
  OutlinedLeaf,
  SolidLeaf,
  StripedLeaf,
  Logo,
} from "../components/leaves";

import {
  Stats,
  Leaves,
  Image,
  Body,
} from "../components/layout";

import FitText from "../components/fit-text";
import List from "../components/list";

const giveNumbers = [
  { count: "$64,297,130", label: "Total Income" },
  { count: "$7,602,781", label: "Step Up Offering" },
  { count: "$3,819,908", label: "Total Given to Missions" },
  { count: "$3,165,713", label: "Clemson For Christmas" },
];

const ClemsonForChristmas = () => (

      <Stats>
        <FitText compressor={1.2}>

            Because of your generosity, we raised

        </FitText>

        <FitText compressor={0.5}>

          $3,165,713

        </FitText>

        <FitText compressor={1.2}>

          during our year end offering - Clemson for Christmas

        </FitText>
      </Stats>

      {/*
      <Leaves>

        <SolidLeaf
          className="locked-bottom locked-right"
          size="200px"
          color="text-secondary"
          style={{
            transform: "rotate(-225deg)",
            marginBottom: "-50px",
            marginRight: "-150px",
          }}
        />
        <SolidLeaf
          className="locked-bottom locked-right"
          size="130px"
          color="text-tertiary"
          style={{
            transform: "rotate(-270deg)",
            marginBottom: "-100px",
            marginRight: "-10px",
          }}
        />
        <StripedLeaf
          className="locked-bottom locked-right"
          size="90px"
          color="text-secondary"
          style={{
            transform: "rotate(180deg)",
            marginBottom: "60px",
            marginRight: "-20px",
          }}
        />

        <SolidLeaf
          className="locked-bottom locked-left"
          size="250px"
          color="text-secondary"
          style={{
            transform: "rotate(-135deg)",
            marginBottom: "-90px",
            marginLeft: "-150px",
          }}
        />

        <StripedLeaf
          className="locked-bottom locked-left"
          size="120px"
          color="text-tertiary"
          style={{
            transform: "rotate(-90deg)",
            marginBottom: "-20px",
            marginLeft: "0px",
          }}
        />

      </Leaves>
      */}

    {/*

            "I thought being Christian was about being a good person and checking off a list of things. At the Best Weekend Ever service at the Clemson Campus, I realized I didn’t have a relationship with Jesus. I didn’t remember a time I accepted him into my life. I didn’t want to live with doubt any longer. A permanent facility in Clemson is so exciting because I know it will reach students like me."

    */}

Giving:

You Can't Outgive God

      <List items={giveNumbers} />

);

export default ClemsonForChristmas;
<commit_msg>lint celebrate clemson<commit_after>
import {
  Stats,
} from "../components/layout";

import FitText from "../components/fit-text";
import List from "../components/list";

const giveNumbers = [
  { count: "$64,297,130", label: "Total Income" },
  { count: "$7,602,781", label: "Step Up Offering" },
  { count: "$3,819,908", label: "Total Given to Missions" },
  { count: "$3,165,713", label: "Clemson For Christmas" },
];

/* eslint-disable max-len */
const ClemsonForChristmas = () => (

      <Stats>
        <FitText compressor={1.2}>

            Because of your generosity, we raised

        </FitText>

        <FitText compressor={0.5}>

            $3,165,713

        </FitText>

        <FitText compressor={1.2}>

            during our year end offering - Clemson for Christmas

        </FitText>
      </Stats>

      {/*
      <Leaves>

        <SolidLeaf
          className="locked-bottom locked-right"
          size="200px"
          color="text-secondary"
          style={{
            transform: "rotate(-225deg)",
            marginBottom: "-50px",
            marginRight: "-150px",
          }}
        />
        <SolidLeaf
          className="locked-bottom locked-right"
          size="130px"
          color="text-tertiary"
          style={{
            transform: "rotate(-270deg)",
            marginBottom: "-100px",
            marginRight: "-10px",
          }}
        />
        <StripedLeaf
          className="locked-bottom locked-right"
          size="90px"
          color="text-secondary"
          style={{
            transform: "rotate(180deg)",
            marginBottom: "60px",
            marginRight: "-20px",
          }}
        />

        <SolidLeaf
          className="locked-bottom locked-left"
          size="250px"
          color="text-secondary"
          style={{
            transform: "rotate(-135deg)",
            marginBottom: "-90px",
            marginLeft: "-150px",
          }}
        />

        <StripedLeaf
          className="locked-bottom locked-left"
          size="120px"
          color="text-tertiary"
          style={{
            transform: "rotate(-90deg)",
            marginBottom: "-20px",
            marginLeft: "0px",
          }}
        />

      </Leaves>
      */}

    {/*

            "I thought being Christian was about being a good person and checking off a list of things. At the Best Weekend Ever service at the Clemson Campus, I realized I didn’t have a relationship with Jesus. I didn’t remember a time I accepted him into my life. I didn’t want to live with doubt any longer. A permanent facility in Clemson is so exciting because I know it will reach students like me."

    */}

Giving:

You Can't Outgive God

      <List items={giveNumbers} />

);

export default ClemsonForChristmas;
<|endoftext|>


<commit_before>function parseMsg( rawMsg ) {
    return `- ${rawMsg}`;
}

export default function () {
    return {
        command: 'added [msg]',
        describe: 'Writes your changelog indicating new stuff.',
        handler(parser, argv, write) {
            if ( !parser.exists() ) {
                // maybe throw an error... init is needed first
                return;
            }
            const msg = argv.msg;
            if (!msg) return;
            parser.added( parseMsg(msg) );
            return write();
        }
    };
}
<commit_msg>Update: added proper error + lint fix<commit_after>function parseMsg( rawMsg ) {
    return `- ${rawMsg}`;
}

export default function () {
    return {
        command: 'added [msg]',
        describe: 'Writes your changelog indicating new stuff.',
        handler(parser, argv, write) {
            if ( !parser.exists() ) {
                throw new Error('CHANGELOG.md does not exists. You can run: chan init in order to create a fresh new one.');
            }
            const msg = argv.msg;
            if (!msg) return;
            parser.added( parseMsg(msg) );
            write();
        }
    };
}
<|endoftext|>


<commit_before>/*
 * Some license
 */

(function(window, undefined) {
  function Stack() {
    this.reset();
  };
  Stack.prototype.reset = function() {
    this.stack = [[]];
    this.push(0);
  }
  Stack.prototype.pop = function() {
    var context = this.stack.pop()
    var value = eval(context.join(""));

    // If the stack is empty push back an empty array
    if(this.stack.length === 0) {
      this.stack.push([]);
    }

    console.log("POP ", value);

    this.peek().push(value);

    return value;
  };
  Stack.prototype.dpop = function() {
    return this.peek().pop();
  };
  Stack.prototype.push = function(o) {
    console.log("PSH ", o);

    // Push a new array. Key '(' been pressed
    if(o instanceof Array) {
      this.stack.push([]);
    } else {
      this.peek().push(o);
    }
  };
  Stack.prototype.peek = function() {
    // Return the stack if there's nothing else
    if(this.stack.length === 0) {
      return this.stack;
    } else {
      return this.stack[this.stack.length - 1];
    }
  };
  Stack.prototype.dpeek = function() {
    var lstack = this.peek();

    return lstack[lstack.length - 1];
  };

  function Calculator(element, options) {
    this.boundElement = document.querySelector(element);

    this.options = options;
    if(options === undefined)
      this.options = {};

    this.createElements();

    this.keys = this.boundElement.querySelectorAll('span');
    // Default operators
    //this.operators = ['+', '-', 'x', '÷'];
    this.operators = [];
    // Default shortcuts.
    this.shortcuts = ['π'];
    // Default modifiers.
    this.modifiers = ['1/X'];
    // This will determine whether a decimal may be added or not.
    this.decimalAdded = false;
    // The last pressed key
    this.lastKey = undefined;
    // The modifier function. This function will be checked during input
    this.modifierFunc = undefined;

    // Logic stack
    this.stack = new Stack();

    // The element the keys will be added to
    this.appendingKeyElement = '.keys';

    this.initialize();

    // Function keys
    this.appendingKeyElement = '.keys .function-keys';
  };
  Calculator.prototype.defineOperator = function(buttonValue, callbackOrOptions, opts) {
    this.defineKey('operator', buttonValue, callbackOrOptions, opts);
  };
  Calculator.prototype.defineInput = function(buttonValue, callbackOrOptions, opts) {
    this.defineKey('input', buttonValue, callbackOrOptions, opts);
  };
  Calculator.prototype.defineShortcut = function(buttonValue, callbackOrOptions, opts) {
    this.defineKey('shortcut', buttonValue, callbackOrOptions, opts);
  };
  Calculator.prototype.createSpacer = function() {
    this.defineKey('empty');
  }
  Calculator.prototype.createClearButton = function() {
    this.boundElement.querySelector(this.appendingKeyElement).appendChild(this.clearButton);
  }

  Object.defineProperty(Calculator.prototype, 'screen', {
    set: function(text) {
      var screen = this.boundElement.querySelector('.screen');

      screen.innerHTML = text;
    },
    get: function() {
      var screen = this.boundElement.querySelector('.screen');

      return screen.innerHTML;
    }
  });

  Calculator.prototype.defaultShortcut = function(value, stackValue, stack, event) {
    if(this.lastKey !== undefined && this.lastKey.match(/\d+/)) {
      this.stack.dpop();
    }

    var value = value.replace(/π/g, Math.PI);
    this.screen = value;

    this.stack.push(value);
  }

  Calculator.prototype.defaultOperator = function(value, stackValue, stack, event) {
    // Add an indicator that it's selected
    event.srcElement.classList.add("selected");

    // Get the last character from the equation
    var lastChar = this.stack.dpeek();// inputVal[inputVal.length - 1];

    // Only add operator if input is not empty and there is no operator at the last
    if(stackValue !== '') {
      // If last operation is an operator remove it.
      if(this.operators.indexOf(this.stack.dpeek()) !== -1) {
        this.stack.dpop();
      }

      var op = value.replace(/x/g, '*').replace(/÷/g, '/');

      if(stack.length > 3) {
        var tmpStack = stack.slice(0, stack.length - 1);
        this.screen = eval(tmpStack.join(""));
      }

      this.stack.push(op);

      // Allow minus if the string is empty
    } else if(this.stack.dpeek() == '' && value == '-') {
      // TODO
      // Fix minus
    }
  };

  Calculator.prototype.defaultInput = function(value, stackValue, stack, event) {
    var val = value;

    if(val === '.' && !this.decimalAdded) {
      this.decimalAdded = true;

      val = this.stack.dpop() + val;
    } else {
      // Append the number to the last number if it's a number.
      if(this.lastKey !== undefined && this.lastKey.match(/[\d\.]+/)) {
        val = this.stack.dpop() + val;
      }
    }

    // If a modifier function is present, the function should take care of the input.
    if(this.modifierFunc) {
      this.modifierFunc.call(this, val);

      // XXX Not sure if this behaviour should be default or if the modifier should take care of resetting it.
      this.modifierFunc = undefined;
    } else {
      this.stack.push(val);

      this.screen = val;
    }
  };

  Calculator.prototype.onKeyClick = function(e) {
    var selectedOperator = this.boundElement.querySelector('.selected');
    if(selectedOperator) {
      selectedOperator.classList.remove('selected');
    }
  };

  Calculator.prototype.onclick = function(value, callback, event, options) {
    if(!options.preventDefault) {
      this.onKeyClick(event);
    }

    callback.call(this, value, this.stack.dpeek(), this.stack.peek(), event);

    this.lastKey = value;

    event.preventDefault();
  };

  Calculator.prototype.defineKey = function(type, buttonValue, callbackOrOptions, opts) {
    var callback, options;

    if(callbackOrOptions) {
      if(typeof(callbackOrOptions) === 'function') {
        callback = callbackOrOptions
        options = opts;
      } else if(typeof(callbackOrOptions) === 'object') {
        options = callbackOrOptions;
      }
    }

    if(options === undefined) {
      options = {};
    }

    if(callback === undefined && type !== 'empty') {
      switch(type) {
        case 'operator':
          callback = this.defaultOperator;
          break;
        case 'input':
          callback = this.defaultInput;
          break;
        case 'shortcut':
          callback = this.defaultShortcut;
          break;
        case 'empty':
        default:
          throw (new Error("defineKey: No such type '"+type+"' and no callback given (there's no default behaviour implemented given that type!)."));
          break;
      }
    }

    var keysElement = this.boundElement.querySelector(this.appendingKeyElement);
    var key = document.createElement("span");
    key.classList.add(type);

    if(type === 'empty') {
      // Add the empty key
      keysElement.appendChild(key);

      return;
    }

    key.innerHTML = buttonValue;

    if(options.cssClass) {
      if(typeof(options.cssClass) === 'string') {
        options.cssClass = options.cssClass.split(" ");
      }

      for(var i = 0; i < options.cssClass.length; i++) {
        var cssClass = options.cssClass[i];
        key.classList.add(cssClass);
      }
    }

    keysElement.appendChild(key);

    var _this = this;
    key.onclick = function(e) {
      _this.onclick(this.innerHTML, callback, e, options);
    }
  };

  Calculator.prototype.createElements = function() {
    var top = document.createElement('div');
    top.classList.add('top');

    var clear = document.createElement('span');
    clear.classList.add('clear');
    clear.innerHTML = "C";
    var screen = document.createElement('div');
    screen.classList.add('screen');
    screen.innerHTML = "0";

    if('hideDefaultClear' in this.options && this.options.hideDefaultClear) {
      // Do something
      //this.createSpacer();
    } else {
      top.appendChild(clear);
    }
    this.clearButton = clear;

    top.appendChild(screen);

    var keys = document.createElement('div');
    keys.classList.add('keys');
    var func = document.createElement('div');
    func.classList.add('function-keys');
    keys.appendChild(func);

    var copy = document.createElement('div');
    copy.innerHTML = "Created by Jeffrey Wilcke. Get it at https://github.com/stygeo/calculator";
    copy.style.display = 'none';
    this.boundElement.appendChild(copy);
    this.boundElement.appendChild(top);
    this.boundElement.appendChild(keys);
  };

  Calculator.prototype.initialize = function() {
    var _this = this;
    // Define the default behaviour of the calculator.
    //[
    //  [7,   8,   9, "÷"],
    //  [4,   5,   6, "*"],
    //  [1,   2,   3, "+"],
    //  [0, ".", "="],
    //]

    // Define PI
    this.defineShortcut('π', {cssClass:'operator'});
    // Define the '(' and ')' ops.
    this.defineKey('operator', '(', function(value, stackValue, stack, event) {
      this.stack.push([]);
    });
    this.defineKey('operator', ')', function(value, stackValue, stack, event) {
      this.screen = this.stack.pop();
    });
    this.defineOperator('÷');

    this.defineInput(7); this.defineInput(8); this.defineInput(9); this.defineOperator("*")
    this.defineInput(4); this.defineInput(5); this.defineInput(6); this.defineOperator("+")
    this.defineInput(1); this.defineInput(2); this.defineInput(3); this.defineOperator("-")
    var tmpOps = ['+', '-', 'x', '÷'];

    this.defineInput(0); this.defineInput(".");
    // Define 'special' behaviour for the eval key.
    this.defineKey('eval', "=", function(value, stackValue, stack, event) {
      console.log(this.stack.stack);
      this.screen = this.stack.pop();

      decimalAdded = false;
    });

    // Last but not least the default reset button
    this.clearButton.onclick = function(e) {
      _this.screen = '0';
      _this.stack.reset();

      e.preventDefault();
    };
  };

  if(typeof jQuery !== 'undefined') {
    jQuery.fn.calculator = function() {
      for(var _i = 0; i < this.length; i++) {
        var _e = this[_i];
        new Calculator(_e);
      }

      return jQuery;
    };
  }

  if(typeof define === 'function' && define.amd) {
    define( 'calculator', [], function() { return Calculator; } );
  }

  if( typeof window === 'object' && typeof window.document === 'object' ) {
    window.Calculator = Calculator;
  }
})(window);

<commit_msg>Removed 0 push on reset<commit_after>/*
 * Some license
 */

(function(window, undefined) {
  function Stack() {
    this.reset();
  };
  Stack.prototype.reset = function() {
    this.stack = [[]];
  }
  Stack.prototype.pop = function() {
    var context = this.stack.pop()
    var value = eval(context.join(""));

    // If the stack is empty push back an empty array
    if(this.stack.length === 0) {
      this.stack.push([]);
    }

    console.log("POP ", value);

    this.peek().push(value);

    return value;
  };
  Stack.prototype.dpop = function() {
    return this.peek().pop();
  };
  Stack.prototype.push = function(o) {
    console.log("PSH ", o);

    // Push a new array. Key '(' been pressed
    if(o instanceof Array) {
      this.stack.push([]);
    } else {
      this.peek().push(o);
    }
  };
  Stack.prototype.peek = function() {
    // Return the stack if there's nothing else
    if(this.stack.length === 0) {
      return this.stack;
    } else {
      return this.stack[this.stack.length - 1];
    }
  };
  Stack.prototype.dpeek = function() {
    var lstack = this.peek();

    return lstack[lstack.length - 1];
  };

  function Calculator(element, options) {
    this.boundElement = document.querySelector(element);

    this.options = options;
    if(options === undefined)
      this.options = {};

    this.createElements();

    this.keys = this.boundElement.querySelectorAll('span');
    // Default operators
    //this.operators = ['+', '-', 'x', '÷'];
    this.operators = [];
    // Default shortcuts.
    this.shortcuts = ['π'];
    // Default modifiers.
    this.modifiers = ['1/X'];
    // This will determine whether a decimal may be added or not.
    this.decimalAdded = false;
    // The last pressed key
    this.lastKey = undefined;
    // The modifier function. This function will be checked during input
    this.modifierFunc = undefined;

    // Logic stack
    this.stack = new Stack();

    // The element the keys will be added to
    this.appendingKeyElement = '.keys';

    this.initialize();

    // Function keys
    this.appendingKeyElement = '.keys .function-keys';
  };
  Calculator.prototype.defineOperator = function(buttonValue, callbackOrOptions, opts) {
    this.defineKey('operator', buttonValue, callbackOrOptions, opts);
  };
  Calculator.prototype.defineInput = function(buttonValue, callbackOrOptions, opts) {
    this.defineKey('input', buttonValue, callbackOrOptions, opts);
  };
  Calculator.prototype.defineShortcut = function(buttonValue, callbackOrOptions, opts) {
    this.defineKey('shortcut', buttonValue, callbackOrOptions, opts);
  };
  Calculator.prototype.createSpacer = function() {
    this.defineKey('empty');
  }
  Calculator.prototype.createClearButton = function() {
    this.boundElement.querySelector(this.appendingKeyElement).appendChild(this.clearButton);
  }

  Object.defineProperty(Calculator.prototype, 'screen', {
    set: function(text) {
      var screen = this.boundElement.querySelector('.screen');

      screen.innerHTML = text;
    },
    get: function() {
      var screen = this.boundElement.querySelector('.screen');

      return screen.innerHTML;
    }
  });

  Calculator.prototype.defaultShortcut = function(value, stackValue, stack, event) {
    if(this.lastKey !== undefined && this.lastKey.match(/\d+/)) {
      this.stack.dpop();
    }

    var value = value.replace(/π/g, Math.PI);
    this.screen = value;

    this.stack.push(value);
  }

  Calculator.prototype.defaultOperator = function(value, stackValue, stack, event) {
    // Add an indicator that it's selected
    event.srcElement.classList.add("selected");

    // Get the last character from the equation
    var lastChar = this.stack.dpeek();// inputVal[inputVal.length - 1];

    // Only add operator if input is not empty and there is no operator at the last
    if(stackValue !== '') {
      // If last operation is an operator remove it.
      if(this.operators.indexOf(this.stack.dpeek()) !== -1) {
        this.stack.dpop();
      }

      var op = value.replace(/x/g, '*').replace(/÷/g, '/');

      if(stack.length > 3) {
        var tmpStack = stack.slice(0, stack.length - 1);
        this.screen = eval(tmpStack.join(""));
      }

      this.stack.push(op);

      // Allow minus if the string is empty
    } else if(this.stack.dpeek() == '' && value == '-') {
      // TODO
      // Fix minus
    }
  };

  Calculator.prototype.defaultInput = function(value, stackValue, stack, event) {
    var val = value;

    if(val === '.' && !this.decimalAdded) {
      this.decimalAdded = true;

      val = this.stack.dpop() + val;
    } else {
      // Append the number to the last number if it's a number.
      if(this.lastKey !== undefined && this.lastKey.match(/[\d\.]+/)) {
        val = this.stack.dpop() + val;
      }
    }

    // If a modifier function is present, the function should take care of the input.
    if(this.modifierFunc) {
      this.modifierFunc.call(this, val);

      // XXX Not sure if this behaviour should be default or if the modifier should take care of resetting it.
      this.modifierFunc = undefined;
    } else {
      this.stack.push(val);

      this.screen = val;
    }
  };

  Calculator.prototype.onKeyClick = function(e) {
    var selectedOperator = this.boundElement.querySelector('.selected');
    if(selectedOperator) {
      selectedOperator.classList.remove('selected');
    }
  };

  Calculator.prototype.onclick = function(value, callback, event, options) {
    if(!options.preventDefault) {
      this.onKeyClick(event);
    }

    callback.call(this, value, this.stack.dpeek(), this.stack.peek(), event);

    this.lastKey = value;

    event.preventDefault();
  };

  Calculator.prototype.defineKey = function(type, buttonValue, callbackOrOptions, opts) {
    var callback, options;

    if(callbackOrOptions) {
      if(typeof(callbackOrOptions) === 'function') {
        callback = callbackOrOptions
        options = opts;
      } else if(typeof(callbackOrOptions) === 'object') {
        options = callbackOrOptions;
      }
    }

    if(options === undefined) {
      options = {};
    }

    if(callback === undefined && type !== 'empty') {
      switch(type) {
        case 'operator':
          callback = this.defaultOperator;
          break;
        case 'input':
          callback = this.defaultInput;
          break;
        case 'shortcut':
          callback = this.defaultShortcut;
          break;
        case 'empty':
        default:
          throw (new Error("defineKey: No such type '"+type+"' and no callback given (there's no default behaviour implemented given that type!)."));
          break;
      }
    }

    var keysElement = this.boundElement.querySelector(this.appendingKeyElement);
    var key = document.createElement("span");
    key.classList.add(type);

    if(type === 'empty') {
      // Add the empty key
      keysElement.appendChild(key);

      return;
    }

    key.innerHTML = buttonValue;

    if(options.cssClass) {
      if(typeof(options.cssClass) === 'string') {
        options.cssClass = options.cssClass.split(" ");
      }

      for(var i = 0; i < options.cssClass.length; i++) {
        var cssClass = options.cssClass[i];
        key.classList.add(cssClass);
      }
    }

    keysElement.appendChild(key);

    var _this = this;
    key.onclick = function(e) {
      _this.onclick(this.innerHTML, callback, e, options);
    }
  };

  Calculator.prototype.createElements = function() {
    var top = document.createElement('div');
    top.classList.add('top');

    var clear = document.createElement('span');
    clear.classList.add('clear');
    clear.innerHTML = "C";
    var screen = document.createElement('div');
    screen.classList.add('screen');
    screen.innerHTML = "0";

    if('hideDefaultClear' in this.options && this.options.hideDefaultClear) {
      // Do something
      //this.createSpacer();
    } else {
      top.appendChild(clear);
    }
    this.clearButton = clear;

    top.appendChild(screen);

    var keys = document.createElement('div');
    keys.classList.add('keys');
    var func = document.createElement('div');
    func.classList.add('function-keys');
    keys.appendChild(func);

    var copy = document.createElement('div');
    copy.innerHTML = "Created by Jeffrey Wilcke. Get it at https://github.com/stygeo/calculator";
    copy.style.display = 'none';
    this.boundElement.appendChild(copy);
    this.boundElement.appendChild(top);
    this.boundElement.appendChild(keys);
  };

  Calculator.prototype.initialize = function() {
    var _this = this;
    // Define the default behaviour of the calculator.
    //[
    //  [7,   8,   9, "÷"],
    //  [4,   5,   6, "*"],
    //  [1,   2,   3, "+"],
    //  [0, ".", "="],
    //]

    // Define PI
    this.defineShortcut('π', {cssClass:'operator'});
    // Define the '(' and ')' ops.
    this.defineKey('operator', '(', function(value, stackValue, stack, event) {
      this.stack.push([]);
    });
    this.defineKey('operator', ')', function(value, stackValue, stack, event) {
      this.screen = this.stack.pop();
    });
    this.defineOperator('÷');

    this.defineInput(7); this.defineInput(8); this.defineInput(9); this.defineOperator("*")
    this.defineInput(4); this.defineInput(5); this.defineInput(6); this.defineOperator("+")
    this.defineInput(1); this.defineInput(2); this.defineInput(3); this.defineOperator("-")
    var tmpOps = ['+', '-', 'x', '÷'];

    this.defineInput(0); this.defineInput(".");
    // Define 'special' behaviour for the eval key.
    this.defineKey('eval', "=", function(value, stackValue, stack, event) {
      console.log(this.stack.stack);
      this.screen = this.stack.pop();

      this.decimalAdded = false;
    });

    // Last but not least the default reset button
    this.clearButton.onclick = function(e) {
      _this.screen = '0';
      _this.stack.reset();
      _this.lastKey = undefined;

      e.preventDefault();
    };
  };

  if(typeof jQuery !== 'undefined') {
    jQuery.fn.calculator = function() {
      for(var _i = 0; i < this.length; i++) {
        var _e = this[_i];
        new Calculator(_e);
      }

      return jQuery;
    };
  }

  if(typeof define === 'function' && define.amd) {
    define( 'calculator', [], function() { return Calculator; } );
  }

  if( typeof window === 'object' && typeof window.document === 'object' ) {
    window.Calculator = Calculator;
  }
})(window);

<|endoftext|>


<commit_before>const { PopcornTimeEvents } = require('./')
const nodemailer = require('nodemailer');
const _ = require('lodash')

const config = require('./config')

// if(config.email) {
const transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: config.email.user,
    pass: config.email.pass
  }
});

PopcornTimeEvents
  .map(episodes => episodes.sort((e1, e2) => e1.first_aired - e2.first_aired))
  // .subscribe(console.log)
  .subscribe(episodes => {
    const titles = _.uniq(episodes.map(e => e.title))
    const lines = episodes.map(episode => `${episode.title} Season ${episode.season} Episode ${episode.episode}`).join('\n')

    const mailOptions = {
      from: '"Event Notifier" <noreply@gmail.com>',
      to: config.email.user,
      subject: `New "${titles.join(', ')}" epsiodes!`,
      text: `${lines}\n\nIs/Are out on Popcorn Time!`
    };

    transporter.sendMail(mailOptions, (error, info) => {
      if (error) {
        return console.log(error);
      }
      console.log('Email Message sent!');
    });
  })<commit_msg>remove comment xD<commit_after>const { PopcornTimeEvents } = require('./')
const nodemailer = require('nodemailer');
const _ = require('lodash')

const config = require('./config')

const transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: config.email.user,
    pass: config.email.pass
  }
});

PopcornTimeEvents
  .map(episodes => episodes.sort((e1, e2) => e1.first_aired - e2.first_aired))
  // .subscribe(console.log)
  .subscribe(episodes => {
    const titles = _.uniq(episodes.map(e => e.title))
    const lines = episodes.map(episode => `${episode.title} Season ${episode.season} Episode ${episode.episode}`).join('\n')

    const mailOptions = {
      from: '"Event Notifier" <noreply@gmail.com>',
      to: config.email.user,
      subject: `New "${titles.join(', ')}" epsiodes!`,
      text: `${lines}\n\nIs/Are out on Popcorn Time!`
    };

    transporter.sendMail(mailOptions, (error, info) => {
      if (error) {
        return console.log(error);
      }
      console.log('Email Message sent!');
    });
  })<|endoftext|>