<commit_before>import TwitterRealtimeWw2, {MinDurationError, MaxDurationError} from './lib/twitter-realtime-ww2'
import CachedTwitterService from './lib/cached-twitter-service'
import S3TweetRepository from './lib/s3-tweet-repository'
import EventSsmlConverter from './lib/event-ssml-converter'
import Alexa from 'alexa-sdk'
import moment from 'moment'
import bunyan from 'bunyan'
const log = bunyan.createLogger({name: 'alexa-skill'})
const ssmlConverter = new EventSsmlConverter()

const createApp = async () => {
  return new TwitterRealtimeWw2(
    new CachedTwitterService(
      new S3TweetRepository(process.env.TWEET_CACHE_BUCKET_NAME))
  )
}

const currentClock = () => (process.env.CLOCK === 'NOW' ? moment() : moment(process.env.CLOCK)).utc().format()

const wrapErrorHandler = handlers => {
  return Object.keys(handlers).reduce((acc, key) => {
    acc[key] = new Proxy(handlers[key], {
      apply: async (target, thisArg, argumentsList) => {
        try {
          log.info({request: thisArg.event.request, session: thisArg.event.session}, 'Handling incoming request ...')
          await target.apply(thisArg, argumentsList)
          log.info('Finished handling request.')
        } catch (err) {
          log.error(err)
          if (err.name === MinDurationError.name || err.name === MaxDurationError.name) {
            thisArg.emit(':tell', DURATION_LIMIT_MESSAGE)
          } else {
            thisArg.callback(err)
          }
        }
      }
    })
    return acc
  }, {})
}

const DURATION_LIMIT_MESSAGE = 'Sorry, you can only get the recent events from the last 1 to 24 hours'
const HELP_MESSAGE = 'You can say, what is happening since the last 24 hours, or, tell me the latest event.'
const HELP_REPROMPT = 'What can I help you with?'
const STOP_MESSAGE = 'Goodbye!'

const handlers = wrapErrorHandler({
  'LaunchRequest': function () {
    this.emit('GetRecentEventsIntent', 24)
  },
  'GetLatestEventIntent': async function () {
    const app = await exports.createApp()
    let latestEvent = await app.getLatestEvent()
    this.emit(':tell', ssmlConverter.convert([latestEvent]))
  },
  'GetRecentEventsIntent': async function (d) {
    const duration = d || this.event.request.intent.slots.Duration.value
    const app = await exports.createApp()
    const recentEvents = await app.getRecentEvents(duration, currentClock())
    let speechOutput = recentEvents.length === 0
        ? `Sorry, there is nothing happening in the last ${duration} hour${duration > 1 ? 's' : ''}`
        : [`<p>Here are the events happening in the last ${duration} hour${duration > 1 ? 's' : ''}</p>`]
          .concat(ssmlConverter.convert(recentEvents)).join('')

    this.emit(':tell', speechOutput)
  },
  'AMAZON.HelpIntent': function () {
    this.response.speak(HELP_MESSAGE).listen(HELP_REPROMPT)
    this.emit(':responseReady')
  },
  'AMAZON.CancelIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  },
  'AMAZON.StopIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  },
  'SessionEndedRequest': function () {
    log.info(this.event.request, 'session ended')
  }
})

exports.handler = function (event, context, callback) {
  const alexa = Alexa.handler(event, context, callback)
  alexa.appId = process.env.ALEXA_SKILL_ID
  alexa.registerHandlers(handlers)
  alexa.execute()
}

exports.createApp = createApp
exports.handlers = handlers
<commit_msg>Refactor LaunchRequest to not delegate to IntentRequest.<commit_after>import TwitterRealtimeWw2, {MinDurationError, MaxDurationError} from './lib/twitter-realtime-ww2'
import CachedTwitterService from './lib/cached-twitter-service'
import S3TweetRepository from './lib/s3-tweet-repository'
import EventSsmlConverter from './lib/event-ssml-converter'
import Alexa from 'alexa-sdk'
import moment from 'moment'
import bunyan from 'bunyan'
const log = bunyan.createLogger({name: 'alexa-skill'})
const ssmlConverter = new EventSsmlConverter()

const createApp = async () => {
  return new TwitterRealtimeWw2(
    new CachedTwitterService(
      new S3TweetRepository(process.env.TWEET_CACHE_BUCKET_NAME))
  )
}

const currentClock = () => (process.env.CLOCK === 'NOW' ? moment() : moment(process.env.CLOCK)).utc().format()

const wrapErrorHandler = handlers => {
  return Object.keys(handlers).reduce((acc, key) => {
    acc[key] = new Proxy(handlers[key], {
      apply: async (target, thisArg, argumentsList) => {
        try {
          log.info({request: thisArg.event.request, session: thisArg.event.session}, 'Handling incoming request ...')
          await target.apply(thisArg, argumentsList)
          log.info('Finished handling request.')
        } catch (err) {
          log.error(err)
          if (err.name === MinDurationError.name || err.name === MaxDurationError.name) {
            thisArg.emit(':tell', DURATION_LIMIT_MESSAGE)
          } else {
            thisArg.callback(err)
          }
        }
      }
    })
    return acc
  }, {})
}

const DURATION_LIMIT_MESSAGE = 'Sorry, you can only get the recent events from the last 1 to 24 hours'
const HELP_MESSAGE = 'You can say, what is happening since the last 24 hours, or, tell me the latest event.'
const HELP_REPROMPT = 'What can I help you with?'
const STOP_MESSAGE = 'Goodbye!'

const getLatestEventMessage = async () => {
  const app = await exports.createApp()
  let latestEvent = await app.getLatestEvent()
  return ssmlConverter.convert([latestEvent])
}

const getRecentEventsMessage = async (duration) => {
  const app = await exports.createApp()
  const recentEvents = await app.getRecentEvents(duration, currentClock())
  return recentEvents.length === 0
      ? `Sorry, there is nothing happening in the last ${duration} hour${duration > 1 ? 's' : ''}`
      : [`<p>Here are the events happening in the last ${duration} hour${duration > 1 ? 's' : ''}</p>`]
        .concat(ssmlConverter.convert(recentEvents)).join('')
}

const handlers = wrapErrorHandler({
  'LaunchRequest': async function () {
    this.emit(':tell', await getRecentEventsMessage(24))
  },
  'GetLatestEventIntent': async function () {
    this.emit(':tell', await getLatestEventMessage())
  },
  'GetRecentEventsIntent': async function (d) {
    const duration = this.event.request.intent.slots.Duration.value
    this.emit(':tell', await getRecentEventsMessage(duration))
  },
  'AMAZON.HelpIntent': function () {
    this.response.speak(HELP_MESSAGE).listen(HELP_REPROMPT)
    this.emit(':responseReady')
  },
  'AMAZON.CancelIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  },
  'AMAZON.StopIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  },
  'SessionEndedRequest': function () {
    log.info(this.event.request, 'session ended')
  }
})

exports.handler = function (event, context, callback) {
  const alexa = Alexa.handler(event, context, callback)
  alexa.appId = process.env.ALEXA_SKILL_ID
  alexa.registerHandlers(handlers)
  alexa.execute()
}

exports.createApp = createApp
exports.handlers = handlers
<|endoftext|>


<commit_before>var updateDatabase = function(conn, dbversion) {
	// The "scale" column was added on 2015-06-27
	let versionresult = null;
	if (yield conn.tableExists("settings")) {
		versionresult = yield conn.execute("SELECT value FROM settings WHERE key='dbversion'");
	}
	if (!versionresult || versionresult.length !== 1 || versionresult[0].getResultByName("value") < 20150627) {
		try {
			yield conn.execute('ALTER TABLE journals ADD COLUMN scale TEXT DEFAULT "1"');
		} catch (e) {
			// ignore; will try the CREATE TABLE IF NOT EXISTS command below instead
		}
	}

	yield conn.execute(
		"CREATE TABLE IF NOT EXISTS journals (" +
			"id INTEGER PRIMARY KEY ASC ON CONFLICT REPLACE," +
			"priority INTEGER," +
			"lastModified TEXT DEFAULT CURRENT_TIMESTAMP," +
			"enabled INTEGER," +
			"longname TEXT," +
			"shortname TEXT," +
			"minDate INTEGER," +
			"maxDate INTEGER," +
			"m1 TEXT," +
			"m2 TEXT," +
			"m3 TEXT," +
			"m4 TEXT," +
			"coverpage INTEGER," +
			"k2pdfoptParams TEXT," +
			'scale TEXT DEFAULT "1"' +
		")"
	);
	yield conn.execute("CREATE TABLE IF NOT EXISTS deletedBuiltinJournals (id INTEGER PRIMARY KEY ON CONFLICT IGNORE)");
	yield conn.execute("CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY ON CONFLICT REPLACE, value TEXT)");
	yield conn.execute("INSERT INTO settings VALUES ('dbversion', ?)", [dbversion]);

	// [id, priority, lastModified, enabled, longname, shortname, minDate, maxDate, m1, m2, m3, m4, coverpage, k2pdfoptParams]
	let builtinJournals = [
		[-1, 2621440, "2014-12-06 00:01:01", 1, "Advances in Physics", "", 20070101, 20090501, "13", "18.3", "5", "24.5", 1, "", "1"],
		[-2, 2621504, "2014-12-06 00:01:02", 1, "Annals of Physics", "Annals of Physics", 19850401, 19920101, "5.0", "27.8", "5.0", "5.0", 0, "", "1"],
		[-3, 2621504, "2014-02-16 10:34:02", 1, "Annals of Physics", "", 20061231, 20110101, "13", "19.6", "5", "5", 0, "", "1"],
		[-4, 2621440, "2014-02-16 10:34:03", 1, "EPL (Europhysics Letters)", "EPL", 20070601, 20110901, "13", "24.3", "5", "20.8", 1, "", "1"],
		[-5, 2621440, "2014-02-16 10:34:04", 1, "Europhysics Letters (EPL)", "", 20041231, 20061231, "5", "29.5", "5", "12.8", 1, "", "1"],
		[-6, 2621504, "2014-02-16 10:34:05", 1, "Journal of Magnetism and Magnetic Materials", "Journal of Magnetism and Magnetic Materials", 19871231, 19960101, "13", "19.7", "5", "21", 0, "", "1"],
		[-7, 2621440, "2014-02-16 10:34:06", 1, "Journal of Physics C: Solid State Physics", "J. Phys. C: Solid State Phys.", 19770628, 19801110, "13", "18.8", "5", "20", 1, "", "1"],
		[-8, 2621440, "2014-02-16 10:34:07", 1, "Journal of Physics C: Solid State Physics", "", 19820810, 19870310, "13", "16.6", "5", "16.2", 1, "", "1"],
		[-9, 2359296, "2014-12-06 00:01:03", 1, "Journal of Physics: Condensed Matter", "", 19971117, 0, "13", "22.5", "5", "23.9", 1, "", "1"],
		[-10, 2621504, "2014-02-16 10:34:09", 1, "Nature", "Nature", 20100408, 20100617, "5", "12.1", "5", "9.4", 0, "", "1"],
		[-11, 2621504, "2014-12-06 00:01:04", 1, "Physical Review", "Phys. Rev.", 19491231, 19610815, "13", "32", "5", "5", 0, "", "1"],
		[-12, 2359360, "2014-12-06 00:01:05", 1, "Physical Review A", "Phys. Rev. A", 20010312, 0, "13", "20", "5", "17.6", 0, "", "1"],
		[-13, 262208, "2014-12-06 00:01:06", 0, "Physical Review B", "Phys. Rev. B", 0, 19990101, "10", "18", "5", "5", 0, "", "1"],
		[-14, 2359360, "2014-12-06 00:01:07", 1, "Physical Review B", "Phys. Rev. B", 20010613, 0, "10", "19.5", "5", "17.5", 0, "", "1"],
		[-15, 2621504, "2014-12-06 00:01:08", 1, "Physical Review E", "Phys. Rev. E", 20030822, 20110101, "13", "19.7", "5", "18", 0, "", "1"],
		[-16, 262208, "2014-12-06 00:01:09", 0, "Physical Review Letters", "Phys. Rev. Lett.", 0, 19990509, "13", "27.1", "5", "23.5", 0, "", "1"],
		[-17, 2359360, "2014-02-16 10:34:16", 1, "Physical Review Letters", "Phys. Rev. Lett.", 19990510, 0, "13", "15.7", "5", "19.8", 0, "", "1"],
		[-18, 2097216, "2014-02-16 10:34:24", 1, "Physical Review X", "Phys. Rev. X", 0, 0, "5", "15.2", "5", "16.4", 0, "", "1"],
		[-19, 2621504, "2014-02-16 10:34:17", 1, "Physics Letters B", "Physics Letters B", 19831103, 19930101, "5", "25.6", "5", "26.4", 0, "", "1"],
		[-20, 2621504, "2014-02-16 10:34:18", 1, "Resonance", "Reson", 20050401, 20050501, "13", "17.3", "5", "21.5", 0, "", "1"],
		[-21, 2621504, "2014-12-06 00:01:10", 1, "Reviews of Modern Physics", "Rev. Mod. Phys.", 19751001, 19940101, "13", "21.9", "5", "23.7", 0, "", "1"],
		[-22, 2621504, "2014-12-06 00:01:11", 1, "Reviews of Modern Physics", "Rev. Mod. Phys.", 19960101, 20101108, "13", "11.9", "5", "10.7", 0, "", "1"],
		[-23, 524288, "2014-02-16 10:34:21", 0, "Science", "Science", 20010330, 20030905, "5", "22.7", "12.3", "9", 1, "", "1"],
		[-24, 262216, "2014-12-06 00:01:12", 0, "Science", "Science", 20090213, 0, "5", "11.4", "12.0", "9.0", 0, "-col 3", "1"],
		[-25, 2621504, "2014-02-16 10:34:23", 1, "Zeitschrift für Physik", "", 19251231, 19280101, "13", "28.6", "5", "5", 0, "", "1"],
		[-26, 2621504, "2014-12-06 00:02:01", 1, "Journal of the Physical Society of Japan", "J. Phys. Soc. Jpn.", 20040101, 20070515, "5.0", "20.4", "5.0", "13.3", 0, "", "1"],
		[-27, 2359360, "2014-12-06 00:02:02", 1, "Journal of the Physical Society of Japan", "", 20121215, 0, "5.0", "20.5", "5.0", "16.0", 0, "", "1"],
		[-28, 2359360, "2014-12-06 00:02:03", 1, "Nature Physics", "Nat Phys", 20111231, 0, "5.0", "15.8", "5.0", "10.6", 0, "", "1"],
		[-29, 2621504, "2014-12-06 00:02:04", 1, "Physical Review A", "Phys. Rev. A", 19970201, 19991201, "5.0", "16.3", "5.0", "5.0", 0, "", "1"],
		[-30, 2359360, "2014-12-06 00:02:05", 1, "Physics", "Physics", 20110502, 0, "5.0", "19.9", "5.0", "31.7", 0, "", "1"],
		[-31, 2359360, "2014-12-06 00:02:06", 1, "Scientific Reports", "Sci. Rep.", 20140417, 0, "5.0", "15.8", "5.0", "10.1", 0, "", "1"],
		[-32, 524352, "2014-12-06 00:02:07", 0, "Proceedings of the Royal Society of London A: Mathematical, Physical and Engineering Sciences", "", 19320901, 19871109, "13", "24.0", "5", "9.2", 0, "", "1"]
	];

	for (let i=0; i<builtinJournals.length; i++) {
		yield conn.executeCached("INSERT INTO journals VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", builtinJournals[i]);
	}

	// Disable any builtin journals that had already been deleted by the user.
	yield conn.execute("UPDATE journals SET enabled=0, priority=priority & ~2097152 WHERE id IN (SELECT id FROM deletedBuiltinJournals)");
}
<commit_msg>Improve initialization of sqlite database<commit_after>var updateDatabase = function(conn, dbversion) {
	// The "scale" column was added on 2015-06-27
	if (yield conn.tableExists("settings")) {
		try {
			let versionresult = yield conn.execute("SELECT value FROM settings WHERE key='dbversion'");
			if (versionresult.length === 1 && versionresult[0].getResultByName("value") < 20150627) {
				yield conn.execute('ALTER TABLE journals ADD COLUMN scale TEXT DEFAULT "1"');
			} catch (e) {
				// ignore; will try the CREATE TABLE IF NOT EXISTS command below instead
			}
		}
	}

	yield conn.execute(
		"CREATE TABLE IF NOT EXISTS journals (" +
			"id INTEGER PRIMARY KEY ASC ON CONFLICT REPLACE," +
			"priority INTEGER," +
			"lastModified TEXT DEFAULT CURRENT_TIMESTAMP," +
			"enabled INTEGER," +
			"longname TEXT," +
			"shortname TEXT," +
			"minDate INTEGER," +
			"maxDate INTEGER," +
			"m1 TEXT," +
			"m2 TEXT," +
			"m3 TEXT," +
			"m4 TEXT," +
			"coverpage INTEGER," +
			"k2pdfoptParams TEXT," +
			'scale TEXT DEFAULT "1"' +
		")"
	);
	yield conn.execute("CREATE TABLE IF NOT EXISTS deletedBuiltinJournals (id INTEGER PRIMARY KEY ON CONFLICT IGNORE)");
	yield conn.execute("CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY ON CONFLICT REPLACE, value TEXT)");
	yield conn.execute("INSERT INTO settings VALUES ('dbversion', ?)", [dbversion]);

	// [id, priority, lastModified, enabled, longname, shortname, minDate, maxDate, m1, m2, m3, m4, coverpage, k2pdfoptParams]
	let builtinJournals = [
		[-1, 2621440, "2014-12-06 00:01:01", 1, "Advances in Physics", "", 20070101, 20090501, "13", "18.3", "5", "24.5", 1, "", "1"],
		[-2, 2621504, "2014-12-06 00:01:02", 1, "Annals of Physics", "Annals of Physics", 19850401, 19920101, "5.0", "27.8", "5.0", "5.0", 0, "", "1"],
		[-3, 2621504, "2014-02-16 10:34:02", 1, "Annals of Physics", "", 20061231, 20110101, "13", "19.6", "5", "5", 0, "", "1"],
		[-4, 2621440, "2014-02-16 10:34:03", 1, "EPL (Europhysics Letters)", "EPL", 20070601, 20110901, "13", "24.3", "5", "20.8", 1, "", "1"],
		[-5, 2621440, "2014-02-16 10:34:04", 1, "Europhysics Letters (EPL)", "", 20041231, 20061231, "5", "29.5", "5", "12.8", 1, "", "1"],
		[-6, 2621504, "2014-02-16 10:34:05", 1, "Journal of Magnetism and Magnetic Materials", "Journal of Magnetism and Magnetic Materials", 19871231, 19960101, "13", "19.7", "5", "21", 0, "", "1"],
		[-7, 2621440, "2014-02-16 10:34:06", 1, "Journal of Physics C: Solid State Physics", "J. Phys. C: Solid State Phys.", 19770628, 19801110, "13", "18.8", "5", "20", 1, "", "1"],
		[-8, 2621440, "2014-02-16 10:34:07", 1, "Journal of Physics C: Solid State Physics", "", 19820810, 19870310, "13", "16.6", "5", "16.2", 1, "", "1"],
		[-9, 2359296, "2014-12-06 00:01:03", 1, "Journal of Physics: Condensed Matter", "", 19971117, 0, "13", "22.5", "5", "23.9", 1, "", "1"],
		[-10, 2621504, "2014-02-16 10:34:09", 1, "Nature", "Nature", 20100408, 20100617, "5", "12.1", "5", "9.4", 0, "", "1"],
		[-11, 2621504, "2014-12-06 00:01:04", 1, "Physical Review", "Phys. Rev.", 19491231, 19610815, "13", "32", "5", "5", 0, "", "1"],
		[-12, 2359360, "2014-12-06 00:01:05", 1, "Physical Review A", "Phys. Rev. A", 20010312, 0, "13", "20", "5", "17.6", 0, "", "1"],
		[-13, 262208, "2014-12-06 00:01:06", 0, "Physical Review B", "Phys. Rev. B", 0, 19990101, "10", "18", "5", "5", 0, "", "1"],
		[-14, 2359360, "2014-12-06 00:01:07", 1, "Physical Review B", "Phys. Rev. B", 20010613, 0, "10", "19.5", "5", "17.5", 0, "", "1"],
		[-15, 2621504, "2014-12-06 00:01:08", 1, "Physical Review E", "Phys. Rev. E", 20030822, 20110101, "13", "19.7", "5", "18", 0, "", "1"],
		[-16, 262208, "2014-12-06 00:01:09", 0, "Physical Review Letters", "Phys. Rev. Lett.", 0, 19990509, "13", "27.1", "5", "23.5", 0, "", "1"],
		[-17, 2359360, "2014-02-16 10:34:16", 1, "Physical Review Letters", "Phys. Rev. Lett.", 19990510, 0, "13", "15.7", "5", "19.8", 0, "", "1"],
		[-18, 2097216, "2014-02-16 10:34:24", 1, "Physical Review X", "Phys. Rev. X", 0, 0, "5", "15.2", "5", "16.4", 0, "", "1"],
		[-19, 2621504, "2014-02-16 10:34:17", 1, "Physics Letters B", "Physics Letters B", 19831103, 19930101, "5", "25.6", "5", "26.4", 0, "", "1"],
		[-20, 2621504, "2014-02-16 10:34:18", 1, "Resonance", "Reson", 20050401, 20050501, "13", "17.3", "5", "21.5", 0, "", "1"],
		[-21, 2621504, "2014-12-06 00:01:10", 1, "Reviews of Modern Physics", "Rev. Mod. Phys.", 19751001, 19940101, "13", "21.9", "5", "23.7", 0, "", "1"],
		[-22, 2621504, "2014-12-06 00:01:11", 1, "Reviews of Modern Physics", "Rev. Mod. Phys.", 19960101, 20101108, "13", "11.9", "5", "10.7", 0, "", "1"],
		[-23, 524288, "2014-02-16 10:34:21", 0, "Science", "Science", 20010330, 20030905, "5", "22.7", "12.3", "9", 1, "", "1"],
		[-24, 262216, "2014-12-06 00:01:12", 0, "Science", "Science", 20090213, 0, "5", "11.4", "12.0", "9.0", 0, "-col 3", "1"],
		[-25, 2621504, "2014-02-16 10:34:23", 1, "Zeitschrift für Physik", "", 19251231, 19280101, "13", "28.6", "5", "5", 0, "", "1"],
		[-26, 2621504, "2014-12-06 00:02:01", 1, "Journal of the Physical Society of Japan", "J. Phys. Soc. Jpn.", 20040101, 20070515, "5.0", "20.4", "5.0", "13.3", 0, "", "1"],
		[-27, 2359360, "2014-12-06 00:02:02", 1, "Journal of the Physical Society of Japan", "", 20121215, 0, "5.0", "20.5", "5.0", "16.0", 0, "", "1"],
		[-28, 2359360, "2014-12-06 00:02:03", 1, "Nature Physics", "Nat Phys", 20111231, 0, "5.0", "15.8", "5.0", "10.6", 0, "", "1"],
		[-29, 2621504, "2014-12-06 00:02:04", 1, "Physical Review A", "Phys. Rev. A", 19970201, 19991201, "5.0", "16.3", "5.0", "5.0", 0, "", "1"],
		[-30, 2359360, "2014-12-06 00:02:05", 1, "Physics", "Physics", 20110502, 0, "5.0", "19.9", "5.0", "31.7", 0, "", "1"],
		[-31, 2359360, "2014-12-06 00:02:06", 1, "Scientific Reports", "Sci. Rep.", 20140417, 0, "5.0", "15.8", "5.0", "10.1", 0, "", "1"],
		[-32, 524352, "2014-12-06 00:02:07", 0, "Proceedings of the Royal Society of London A: Mathematical, Physical and Engineering Sciences", "", 19320901, 19871109, "13", "24.0", "5", "9.2", 0, "", "1"]
	];

	for (let i=0; i<builtinJournals.length; i++) {
		yield conn.executeCached("INSERT INTO journals VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", builtinJournals[i]);
	}

	// Disable any builtin journals that had already been deleted by the user.
	yield conn.execute("UPDATE journals SET enabled=0, priority=priority & ~2097152 WHERE id IN (SELECT id FROM deletedBuiltinJournals)");
}
<|endoftext|>


<commit_before>'use strict';

angular.module('myapp')
  .controller('PropietarioController', ['$scope', '$modal', 'resolvedPropietario', 'Propietario',
    function($scope, $modal, resolvedPropietario, Propietario) {

      $scope.Propietarios = resolvedPropietario;
      $scope.create = function() {
        $scope.clear();
        $scope.open();
      };

      $scope.update = function(id) {
        $scope.Propietario = Propietario.get({
          id: id
        });
        $scope.open(id);
      };

      $scope.delete = function(id) {
        Propietario.delete({
            id: id
          },
          function() {
            $scope.Propietarios = Propietario.query();
          });
      };

      $scope.save = function(id) {
        var PropietarioSave = {
          "Documento": $scope.Propietario.Documento,
          "PrimerNombre": $scope.Propietario.PrimerNombre,
          "OtrosNombres": $scope.Propietario.OtrosNombres,
          "PrimerApellido": $scope.Propietario.PrimerApellido,
          "SegundoApellido": $scope.Propietario.SegundoApellido,
          "IdTipoPropietario": {
            "Id": $scope.Propietario.IdTipoPropietario.Id,
            "Tipo": "",
            "Descripcion": ""
          }
        };
        if (id) {
          Propietario.update({
              id: id
            }, PropietarioSave,
            function() {
              $scope.Propietarios = Propietario.query();
              $scope.clear();
            });
        } else {
          Propietario.save(PropietarioSave,
            function() {
              $scope.Propietarios = Propietario.query();
              $scope.clear();
            });
        }
      };

      $scope.clear = function() {
        $scope.Propietario = {

          "Documento": "",

          "PrimerNombre": "",

          "OtrosNombres": "",

          "PrimerApellido": "",

          "SegundoApellido": "",

          "IdTipoPropietario": "",

          "id": ""
        };
      };

      $scope.open = function(id) {
        var PropietarioSave = $modal.open({
          templateUrl: 'Propietario-save.html',
          controller: 'PropietarioSaveController',
          resolve: {
            Propietario: function() {
              return $scope.Propietario;
            }

          }
        });

        PropietarioSave.result.then(function(entity) {
          $scope.Propietario = entity;
          $scope.save(id);
        });
      };
    }
  ])
  .controller('PropietarioSaveController', ['$scope', '$http', '$modalInstance', 'Propietario',
    function($scope, $http, $modalInstance, Propietario) {
      $scope.Propietario = Propietario;
      var f = [];
      $http.get("/v1/tipo_propietario")
        .success(function(data) {
          data.forEach(function(entry, index) {
            f[index] = entry.Id;
          });
          console.log(f);
          $scope.PropietarioIds = f;
        })
        .error(function(err) {});

      $scope.ok = function() {
        $modalInstance.close($scope.Propietario);
      };

      $scope.cancel = function() {
        $modalInstance.dismiss('cancel');
      };
    }
  ]);
<commit_msg>Se modifica el controlador para correcto funcionamiento con angularjs 1.5.8: modal=>uimodal<commit_after>'use strict';

angular.module('myapp')
  .controller('PropietarioController', ['$scope', '$uibModal', 'resolvedPropietario', 'Propietario',
    function($scope, $modal, resolvedPropietario, Propietario) {

      $scope.Propietarios = resolvedPropietario;
      $scope.create = function() {
        $scope.clear();
        $scope.open();
      };

      $scope.update = function(id) {
        $scope.Propietario = Propietario.get({
          id: id
        });
        $scope.open(id);
      };

      $scope.delete = function(id) {
        Propietario.delete({
            id: id
          },
          function() {
            $scope.Propietarios = Propietario.query();
          });
      };

      $scope.save = function(id) {
        var PropietarioSave = {
          "Documento": $scope.Propietario.Documento,
          "PrimerNombre": $scope.Propietario.PrimerNombre,
          "OtrosNombres": $scope.Propietario.OtrosNombres,
          "PrimerApellido": $scope.Propietario.PrimerApellido,
          "SegundoApellido": $scope.Propietario.SegundoApellido,
          "IdTipoPropietario": {
            "Id": $scope.Propietario.IdTipoPropietario.Id,
            "Tipo": "",
            "Descripcion": ""
          }
        };
        if (id) {
          Propietario.update({
              id: id
            }, PropietarioSave,
            function() {
              $scope.Propietarios = Propietario.query();
              $scope.clear();
            });
        } else {
          Propietario.save(PropietarioSave,
            function() {
              $scope.Propietarios = Propietario.query();
              $scope.clear();
            });
        }
      };

      $scope.clear = function() {
        $scope.Propietario = {

          "Documento": "",

          "PrimerNombre": "",

          "OtrosNombres": "",

          "PrimerApellido": "",

          "SegundoApellido": "",

          "IdTipoPropietario": "",

          "id": ""
        };
      };

      $scope.open = function(id) {
        var PropietarioSave = $modal.open({
          templateUrl: 'Propietario-save.html',
          controller: 'PropietarioSaveController',
          resolve: {
            Propietario: function() {
              return $scope.Propietario;
            }

          }
        });

        PropietarioSave.result.then(function(entity) {
          $scope.Propietario = entity;
          $scope.save(id);
        });
      };
    }
  ])
  .controller('PropietarioSaveController', ['$scope', '$http', '$uibModalInstance', 'Propietario',
    function($scope, $http, $modalInstance, Propietario) {
      $scope.Propietario = Propietario;
      var f = [];
      $http.get("/v1/tipo_propietario")
        .success(function(data) {
          data.forEach(function(entry, index) {
            f[index] = entry.Id;
          });
          console.log(f);
          $scope.PropietarioIds = f;
        })
        .error(function(err) {});

      $scope.ok = function() {
        $modalInstance.close($scope.Propietario);
      };

      $scope.cancel = function() {
        $modalInstance.dismiss('cancel');
      };
    }
  ]);
<|endoftext|>


<commit_before>import Ember from 'ember';
import ajax from 'ic-ajax';

export default Ember.Route.extend({
    beforeModel: function() {
        var self = this;
        if (this.session.get('isLoggedIn') &&
            this.session.get('currentUser') === null)
        {
            return ajax('/me').then(function(response) {
                var user = self.store.push('user', response.user);
                user.set('api_token', response.api_token);
                self.session.set('currentUser', user);
            }).catch(function() {
                self.session.logoutUser();
            });
        }
    },

    actions: {
        didTransition: function() {
            this.controllerFor('application').stepFlash();
        },

        willTransition: function() {
            this.controllerFor('application').aboutToTransition();
            return true;
        },
    },
});
<commit_msg>Trying to debug a login problem...<commit_after>import Ember from 'ember';
import ajax from 'ic-ajax';

export default Ember.Route.extend({
    beforeModel: function() {
        var self = this;
        console.log(this.session.get('isLoggedIn'),
                    this.session.get('currentUser'));
        if (this.session.get('isLoggedIn') &&
            this.session.get('currentUser') === null)
        {
            return ajax('/me').then(function(response) {
                var user = self.store.push('user', response.user);
                user.set('api_token', response.api_token);
                self.session.set('currentUser', user);
            }).catch(function() {
                self.session.logoutUser();
            });
        }
    },

    actions: {
        didTransition: function() {
            this.controllerFor('application').stepFlash();
        },

        willTransition: function() {
            this.controllerFor('application').aboutToTransition();
            return true;
        },
    },
});
<|endoftext|>


<commit_before>import TextArea from '@ember/component/text-area';
import { isNone } from '@ember/utils';
import { get, computed } from '@ember/object';
import AutoResize from "../mixins/autoresize";

/**
  @element text-area
 */
TextArea.reopen(AutoResize, {

  /**
    By default, textareas only resize
    their height.

    @attribute shouldResizeHeight
    @type Boolean
   */
  shouldResizeHeight: true,

  /**
    Whitespace should be treated as significant
    for text areas.

    @attribute significantWhitespace
    @default true
    @type Boolean
   */
  significantWhitespace: true,

  /**
    Optimistically resize the height
    of the textarea so when users reach
    the end of a line, they will be
    presented with space to begin typing.

    If a placeholder is set,
    it will be used instead of the value.

    @attribute autoResizeText
    @type String
   */
  autoResizeText: computed('value', 'placeholder', {
    get() {
      var placeholder = get(this, 'placeholder');
      var value = get(this, 'value');

      if (isNone(value)) {
        return isNone(placeholder) ? '@' : placeholder;
      }

      return value + '@';
    }
  })

});
<commit_msg>Use isEmpty instead of isNone<commit_after>import TextArea from '@ember/component/text-area';
import { isEmpty } from '@ember/utils';
import { get, computed } from '@ember/object';
import AutoResize from "../mixins/autoresize";

/**
  @element text-area
 */
TextArea.reopen(AutoResize, {

  /**
    By default, textareas only resize
    their height.

    @attribute shouldResizeHeight
    @type Boolean
   */
  shouldResizeHeight: true,

  /**
    Whitespace should be treated as significant
    for text areas.

    @attribute significantWhitespace
    @default true
    @type Boolean
   */
  significantWhitespace: true,

  /**
    Optimistically resize the height
    of the textarea so when users reach
    the end of a line, they will be
    presented with space to begin typing.

    If a placeholder is set,
    it will be used instead of the value.

    @attribute autoResizeText
    @type String
   */
  autoResizeText: computed('value', 'placeholder', {
    get() {
      var placeholder = get(this, 'placeholder');
      var value = get(this, 'value');
      var fillChar = '@';

      if (isEmpty(value)) {
        return isEmpty(placeholder) ? fillChar : placeholder + fillChar;
      }

      return value + fillChar;
    }
  })

});
<|endoftext|>


<commit_before>/**
 * Copyright IBM Corp. 2018, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { breakpoint, breakpoints, px, rem } from '@carbon/layout';
import { fluid } from './fluid';
import { fontFamilies } from './fontFamily';
import { fontWeights } from './fontWeight';
import { scale } from './scale';

export const caption01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[0]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const label01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[0]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const helperText01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[0]),
  fontStyle: 'italic',
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const bodyShort01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(18),
  letterSpacing: px(0.16),
};

export const bodyLong01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(20),
  letterSpacing: px(0.16),
};

export const bodyShort02 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[2]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(22),
  letterSpacing: 0,
};

export const bodyLong02 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[2]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(24),
  letterSpacing: 0,
};

export const code01 = {
  fontFamily: fontFamilies.mono,
  fontSize: rem(scale[0]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const code02 = {
  fontFamily: fontFamilies.mono,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(20),
  letterSpacing: px(0.32),
};

export const heading01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.semibold,
  lineHeight: rem(18),
  letterSpacing: px(0.16),
};

export const heading02 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[2]),
  fontWeight: fontWeights.semibold,
  lineHeight: rem(22),
  letterSpacing: 0,
};

export const heading03 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[4]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(26),
  letterSpacing: 0,
};

export const productiveHeading04 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[5]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(30),
  letterSpacing: 0,
};

export const productiveHeading05 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[7]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(40),
  letterSpacing: 0,
};

export const expressiveHeading04 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[5]),
  fontWeight: fontWeights.regular,
  lineHeight: '130%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[5]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.regular,
      lineHeight: rem(26),
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[6]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.regular,
      lineHeight: '125%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[6]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.regular,
      lineHeight: '129%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[7]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.regular,
      lineHeight: '125%',
      letterSpacing: 0,
    },
  },
});

export const expressiveHeading05 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[6]),
  fontWeight: fontWeights.light,
  lineHeight: '129%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[8]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '122%',
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[9]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '119%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[10]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '117%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[12]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: rem(70),
      letterSpacing: 0,
    },
  },
});

export const quotation01 = fluid({
  fontFamily: fontFamilies.serif,
  fontSize: rem(scale[4]),
  fontWeight: fontWeights.regular,
  lineHeight: '130%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[4]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[5]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      lineHeight: '125%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[6]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      lineHeight: '129%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[7]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      lineHeight: '125%',
      letterSpacing: 0,
    },
  },
});

export const quotation02 = fluid({
  fontFamily: fontFamilies.serif,
  fontSize: rem(scale[6]),
  fontWeight: fontWeights.light,
  lineHeight: '129%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[8]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      lineHeight: '122%',
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[9]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      lineHeight: '119%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[10]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      lineHeight: '117%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[12]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      letterSpacing: 0,
    },
  },
});

export const display01 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.light,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[9]),
    },
    lg: {
      fontSize: rem(scale[11]),
    },
    xlg: {
      fontSize: rem(scale[12]),
      lineHeight: '117%',
    },
    max: {
      fontSize: rem(scale[14]),
      lineHeight: '113%',
    },
  },
});

export const display02 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.semibold,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[9]),
    },
    lg: {
      fontSize: rem(scale[11]),
    },
    xlg: {
      fontSize: rem(scale[12]),
      lineHeight: '116%',
    },
    max: {
      fontSize: rem(scale[14]),
      lineHeight: '113%',
    },
  },
});

export const display03 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.light,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[13]),
      lineHeight: '115%',
    },
    lg: {
      fontSize: rem(scale[16]),
      lineHeight: '111%',
      letterSpacing: px(-0.64),
    },
    xlg: {
      fontSize: rem(scale[19]),
      lineHeight: '107%',
    },
    max: {
      fontSize: rem(scale[22]),
      lineHeight: '105%',
      letterSpacing: px(-0.96),
    },
  },
});

export const display04 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.semibold,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[13]),
      lineHeight: '115%',
    },
    lg: {
      fontSize: rem(scale[16]),
      lineHeight: '111%',
      letterSpacing: px(-0.64),
    },
    xlg: {
      fontSize: rem(scale[19]),
      lineHeight: '107%',
      letterSpacing: px(-0.64),
    },
    max: {
      fontSize: rem(scale[22]),
      lineHeight: '105%',
      letterSpacing: px(-0.96),
    },
  },
});
<commit_msg>Update $expressive-heading-04 token weights<commit_after>/**
 * Copyright IBM Corp. 2018, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { breakpoint, breakpoints, px, rem } from '@carbon/layout';
import { fluid } from './fluid';
import { fontFamilies } from './fontFamily';
import { fontWeights } from './fontWeight';
import { scale } from './scale';

export const caption01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[0]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const label01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[0]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const helperText01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[0]),
  fontStyle: 'italic',
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const bodyShort01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(18),
  letterSpacing: px(0.16),
};

export const bodyLong01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(20),
  letterSpacing: px(0.16),
};

export const bodyShort02 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[2]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(22),
  letterSpacing: 0,
};

export const bodyLong02 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[2]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(24),
  letterSpacing: 0,
};

export const code01 = {
  fontFamily: fontFamilies.mono,
  fontSize: rem(scale[0]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(16),
  letterSpacing: px(0.32),
};

export const code02 = {
  fontFamily: fontFamilies.mono,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(20),
  letterSpacing: px(0.32),
};

export const heading01 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[1]),
  fontWeight: fontWeights.semibold,
  lineHeight: rem(18),
  letterSpacing: px(0.16),
};

export const heading02 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[2]),
  fontWeight: fontWeights.semibold,
  lineHeight: rem(22),
  letterSpacing: 0,
};

export const heading03 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[4]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(26),
  letterSpacing: 0,
};

export const productiveHeading04 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[5]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(30),
  letterSpacing: 0,
};

export const productiveHeading05 = {
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[7]),
  fontWeight: fontWeights.regular,
  lineHeight: rem(40),
  letterSpacing: 0,
};

export const expressiveHeading04 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[5]),
  fontWeight: fontWeights.regular,
  lineHeight: '130%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[5]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.regular,
      lineHeight: rem(26),
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[6]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '125%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[6]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '129%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[7]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '125%',
      letterSpacing: 0,
    },
  },
});

export const expressiveHeading05 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[6]),
  fontWeight: fontWeights.light,
  lineHeight: '129%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[8]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '122%',
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[9]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '119%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[10]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: '117%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[12]),
      fontFamily: fontFamilies.sans,
      fontWeight: fontWeights.light,
      lineHeight: rem(70),
      letterSpacing: 0,
    },
  },
});

export const quotation01 = fluid({
  fontFamily: fontFamilies.serif,
  fontSize: rem(scale[4]),
  fontWeight: fontWeights.regular,
  lineHeight: '130%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[4]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[5]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      lineHeight: '125%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[6]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      lineHeight: '129%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[7]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.regular,
      lineHeight: '125%',
      letterSpacing: 0,
    },
  },
});

export const quotation02 = fluid({
  fontFamily: fontFamilies.serif,
  fontSize: rem(scale[6]),
  fontWeight: fontWeights.light,
  lineHeight: '129%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[8]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      lineHeight: '122%',
      letterSpacing: 0,
    },
    lg: {
      fontSize: rem(scale[9]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      lineHeight: '119%',
      letterSpacing: 0,
    },
    xlg: {
      fontSize: rem(scale[10]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      lineHeight: '117%',
      letterSpacing: 0,
    },
    max: {
      fontSize: rem(scale[12]),
      fontFamily: fontFamilies.serif,
      fontWeight: fontWeights.light,
      letterSpacing: 0,
    },
  },
});

export const display01 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.light,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[9]),
    },
    lg: {
      fontSize: rem(scale[11]),
    },
    xlg: {
      fontSize: rem(scale[12]),
      lineHeight: '117%',
    },
    max: {
      fontSize: rem(scale[14]),
      lineHeight: '113%',
    },
  },
});

export const display02 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.semibold,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[9]),
    },
    lg: {
      fontSize: rem(scale[11]),
    },
    xlg: {
      fontSize: rem(scale[12]),
      lineHeight: '116%',
    },
    max: {
      fontSize: rem(scale[14]),
      lineHeight: '113%',
    },
  },
});

export const display03 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.light,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[13]),
      lineHeight: '115%',
    },
    lg: {
      fontSize: rem(scale[16]),
      lineHeight: '111%',
      letterSpacing: px(-0.64),
    },
    xlg: {
      fontSize: rem(scale[19]),
      lineHeight: '107%',
    },
    max: {
      fontSize: rem(scale[22]),
      lineHeight: '105%',
      letterSpacing: px(-0.96),
    },
  },
});

export const display04 = fluid({
  fontFamily: fontFamilies.sans,
  fontSize: rem(scale[9]),
  fontWeight: fontWeights.semibold,
  lineHeight: '119%',
  letterSpacing: 0,
  breakpoints: {
    md: {
      fontSize: rem(scale[13]),
      lineHeight: '115%',
    },
    lg: {
      fontSize: rem(scale[16]),
      lineHeight: '111%',
      letterSpacing: px(-0.64),
    },
    xlg: {
      fontSize: rem(scale[19]),
      lineHeight: '107%',
      letterSpacing: px(-0.64),
    },
    max: {
      fontSize: rem(scale[22]),
      lineHeight: '105%',
      letterSpacing: px(-0.96),
    },
  },
});
<|endoftext|>


<commit_before>exports.log = jsio.__env.log;

exports.bind = function(context, method /*, VARGS*/) {
	if(arguments.length > 2) {
		var args = Array.prototype.slice.call(arguments, 2);
		return typeof method == 'string'
			? function() { return context[method].apply(context, args.concat(Array.prototype.slice.call(arguments, 0))); }
			: function() { return method.apply(context, args.concat(Array.prototype.slice.call(arguments, 0))); }
	} else {
		return typeof method == 'string'
			? function() { exports.log('crash?', method, context, arguments); return context[method].apply(context, arguments); }
			: function() { return method.apply(context, arguments); }
	}
}

exports.Class = function(parent, proto) {
	if(!parent) { throw new Error('parent or prototype not provided'); }
	if(!proto) { proto = parent; }
	else if(parent instanceof Array) { // multiple inheritance, use at your own risk =)
		proto.prototype = {};
		for(var i = 0, p; p = parent[i]; ++i) {
			for(var item in p.prototype) {
				if(!(item in proto.prototype)) {
					proto.prototype[item] = p.prototype[item];
				}
			}
		}
		parent = parent[0];
	} else {
		proto.prototype = parent.prototype;
	}

	var cls = function() { if(this.init) { return this.init.apply(this, arguments); }}
	cls.prototype = new proto(function(context, method, args) {
		var args = args || [];
		var target = proto;
		while(target = target.prototype) {
			if(target[method]) {
				return target[method].apply(context, args);
			}
		}
		throw new Error('method ' + method + ' does not exist');
	});
	cls.prototype.constructor = cls;
	return cls;
}

exports.$setTimeout = function(f, t/*, VARGS */) {
	var args = Array.prototype.slice.call(arguments, 2);
	return setTimeout(function() {
		try {
			f.apply(this, args);
		} catch(e) {
			// log?
		}
	}, t)
}

exports.$setInterval = function(f, t/*, VARGS */) {
	var args = Array.prototype.slice.call(arguments, 2);
	return setInterval(function() {
		try {
			f.apply(this, args);
		} catch(e) {
			// log?
		}
	}, t)
}

// node doesn't let you call clearTimeout(null)
exports.$clearTimeout = function (timer) { return timer ? clearTimeout(timer) : null; };
exports.$clearInterval = function (timer) { return timer ? clearInterval(timer) : null; };

// keep logging local variables out of other closures in this file!
exports.logging = (function() {

	// logging namespace, this is what is exported
	var logging = {
		DEBUG: 1,
		LOG: 2,
		INFO: 3,
		WARN: 4,
		ERROR: 5
	};

	// effectively globals - all loggers and a global production state
	var loggers = {}
	var production = false;

	logging.setProduction = function(prod) { production = !!prod; }
	logging.get = function(name) {
		return loggers.hasOwnProperty(name) ? loggers[name]
			: (loggers[name] = new Logger(name));
	}
	logging.getAll = function() { return loggers; }

	logging.__create = function(pkg, ctx) { ctx.logger = logging.get(pkg); }

	var Logger = exports.Class(function() {
		this.init = function(name, level) {
			this._name = name;
			this._level = level || logging.DEBUG;
		}

		this.setLevel = function(level) { this._level = level; }

		var slice = Array.prototype.slice;
		function makeLogFunction(level, type) {
			return function() {
				if (!production && level >= this._level) {
					log.apply(log, [type, this._name].concat(slice.call(arguments, 0)));
				}
				return arguments[0];
			}
		}

		this.debug = makeLogFunction(logging.DEBUG, "DEBUG");
		this.log = makeLogFunction(logging.LOG, "LOG");
		this.info = makeLogFunction(logging.INFO, "INFO");
		this.warn = makeLogFunction(logging.WARN, "WARN");
		this.error = makeLogFunction(logging.ERROR, "ERROR");
	});

	return logging;
})();
<commit_msg>bug fix: need to define the local variable log<commit_after>exports.log = jsio.__env.log;

exports.bind = function(context, method /*, VARGS*/) {
	if(arguments.length > 2) {
		var args = Array.prototype.slice.call(arguments, 2);
		return typeof method == 'string'
			? function() { return context[method].apply(context, args.concat(Array.prototype.slice.call(arguments, 0))); }
			: function() { return method.apply(context, args.concat(Array.prototype.slice.call(arguments, 0))); }
	} else {
		return typeof method == 'string'
			? function() { exports.log('crash?', method, context, arguments); return context[method].apply(context, arguments); }
			: function() { return method.apply(context, arguments); }
	}
}

exports.Class = function(parent, proto) {
	if(!parent) { throw new Error('parent or prototype not provided'); }
	if(!proto) { proto = parent; }
	else if(parent instanceof Array) { // multiple inheritance, use at your own risk =)
		proto.prototype = {};
		for(var i = 0, p; p = parent[i]; ++i) {
			for(var item in p.prototype) {
				if(!(item in proto.prototype)) {
					proto.prototype[item] = p.prototype[item];
				}
			}
		}
		parent = parent[0];
	} else {
		proto.prototype = parent.prototype;
	}

	var cls = function() { if(this.init) { return this.init.apply(this, arguments); }}
	cls.prototype = new proto(function(context, method, args) {
		var args = args || [];
		var target = proto;
		while(target = target.prototype) {
			if(target[method]) {
				return target[method].apply(context, args);
			}
		}
		throw new Error('method ' + method + ' does not exist');
	});
	cls.prototype.constructor = cls;
	return cls;
}

exports.$setTimeout = function(f, t/*, VARGS */) {
	var args = Array.prototype.slice.call(arguments, 2);
	return setTimeout(function() {
		try {
			f.apply(this, args);
		} catch(e) {
			// log?
		}
	}, t)
}

exports.$setInterval = function(f, t/*, VARGS */) {
	var args = Array.prototype.slice.call(arguments, 2);
	return setInterval(function() {
		try {
			f.apply(this, args);
		} catch(e) {
			// log?
		}
	}, t)
}

// node doesn't let you call clearTimeout(null)
exports.$clearTimeout = function (timer) { return timer ? clearTimeout(timer) : null; };
exports.$clearInterval = function (timer) { return timer ? clearInterval(timer) : null; };

// keep logging local variables out of other closures in this file!
exports.logging = (function() {

	// logging namespace, this is what is exported
	var logging = {
		DEBUG: 1,
		LOG: 2,
		INFO: 3,
		WARN: 4,
		ERROR: 5
	};

	// effectively globals - all loggers and a global production state
	var loggers = {}
	var production = false;

	logging.setProduction = function(prod) { production = !!prod; }
	logging.get = function(name) {
		return loggers.hasOwnProperty(name) ? loggers[name]
			: (loggers[name] = new Logger(name));
	}
	logging.getAll = function() { return loggers; }

	logging.__create = function(pkg, ctx) { ctx.logger = logging.get(pkg); }

	var Logger = exports.Class(function() {
		this.init = function(name, level) {
			this._name = name;
			this._level = level || logging.DEBUG;
		}

		this.setLevel = function(level) { this._level = level; }

		var slice = Array.prototype.slice;
		var log = exports.log;
		function makeLogFunction(level, type) {
			return function() {
				if (!production && level >= this._level) {
					log.apply(log, [type, this._name].concat(slice.call(arguments, 0)));
				}
				return arguments[0];
			}
		}

		this.debug = makeLogFunction(logging.DEBUG, "DEBUG");
		this.log = makeLogFunction(logging.LOG, "LOG");
		this.info = makeLogFunction(logging.INFO, "INFO");
		this.warn = makeLogFunction(logging.WARN, "WARN");
		this.error = makeLogFunction(logging.ERROR, "ERROR");
	});

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


<commit_before>'use strict'

import TwitterRealtimeWw2 from './lib/twitter-realtime-ww2'
import CachedTwitterService from './lib/cached-twitter-service'
import S3TweetRepository from './lib/s3-tweet-repository'
import Alexa from 'alexa-sdk'
import moment from 'moment'

const createApp = async () => {
  return new TwitterRealtimeWw2(
    new CachedTwitterService(
      new S3TweetRepository(process.env.TWEET_CACHE_BUCKET_NAME))
  )
}

const convertToSsml = (event, includeDate = true) => {
  const datetime = moment(event.datetime)
  const dateSsml = includeDate ? `<s><say-as interpret-as="date">${datetime.format('YYYYMMDD')}</say-as></s>` : ''
  return '<p>' +
    dateSsml +
    `<s>${datetime.format('LT')}</s>` +
    `<s>${event.content}</s></p>`
}

const DURATION_LIMIT_MESSAGE = 'Sorry, you can only get the recent events from the last 1 to 24 hours'
const HELP_MESSAGE = 'You can say tell me the latest news, or, you can say exit... What can I help you with?'
const HELP_REPROMPT = 'What can I help you with?'
const STOP_MESSAGE = 'Goodbye!'

const handlers = {
  'LaunchRequest': function () {
    this.emit('GetLatestIntent')
  },
  'GetLatestIntent': function () {
    return exports.createApp()
      .then(app => app.getLatestNews())
      .then(latestNews => {
        this.emit(':tell', convertToSsml(latestNews))
      })
      .catch(err => {
        console.error(err)
        this.emit(':tell', 'Please try again later')
      })
  },
  'GetRecentEventsIntent': async function () {
    try {
      const app = await exports.createApp()
      const duration = this.event.request.intent.slots.Duration.value
      if (duration < 1 || duration > 24) {
        this.emit(':tell', DURATION_LIMIT_MESSAGE)
        return
      }

      const clock = process.env.CLOCK === 'NOW' ? moment() : moment(process.env.CLOCK)
      const recentEvents = await app.getRecentEvents(duration, clock.utc().format())
      let speechOutput = recentEvents.length === 0
        ? `Sorry, there is nothing happening in the last ${duration} hour${duration > 1 ? 's' : ''}`
        : recentEvents.map((event, i, arr) => {
          let includeDate
          if (i > 0) {
            const previousMoment = moment(arr[i - 1].datetime)
            const currentMoment = moment(event.datetime)
            includeDate = !(previousMoment.isSame(currentMoment, 'year') && previousMoment.isSame(currentMoment, 'month') && previousMoment.isSame(currentMoment, 'day'))
          } else {
            includeDate = true
          }
          return convertToSsml(event, includeDate)
        }).join('')

      this.emit(':tell', speechOutput)
    } catch (err) {
      console.error(err)
      this.emit(':tell', 'Please try again later')
    }
  },
  'AMAZON.HelpIntent': function () {
    this.response.speak(HELP_MESSAGE).listen(HELP_REPROMPT)
    this.emit(':responseReady')
  },
  'AMAZON.CancelIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  },
  'AMAZON.StopIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  }
}

exports.handler = function (event, context, callback) {
  const alexa = Alexa.handler(event, context, callback)
  alexa.appId = 'amzn1.ask.skill.8955b37b-4975-4462-a4d9-4aba0ad647f0'
  alexa.registerHandlers(handlers)
  alexa.execute()
}

exports.createApp = createApp
exports.handlers = handlers
<commit_msg>Remove unnecessary use strict.<commit_after>import TwitterRealtimeWw2 from './lib/twitter-realtime-ww2'
import CachedTwitterService from './lib/cached-twitter-service'
import S3TweetRepository from './lib/s3-tweet-repository'
import Alexa from 'alexa-sdk'
import moment from 'moment'

const createApp = async () => {
  return new TwitterRealtimeWw2(
    new CachedTwitterService(
      new S3TweetRepository(process.env.TWEET_CACHE_BUCKET_NAME))
  )
}

const convertToSsml = (event, includeDate = true) => {
  const datetime = moment(event.datetime)
  const dateSsml = includeDate ? `<s><say-as interpret-as="date">${datetime.format('YYYYMMDD')}</say-as></s>` : ''
  return '<p>' +
    dateSsml +
    `<s>${datetime.format('LT')}</s>` +
    `<s>${event.content}</s></p>`
}

const DURATION_LIMIT_MESSAGE = 'Sorry, you can only get the recent events from the last 1 to 24 hours'
const HELP_MESSAGE = 'You can say tell me the latest news, or, you can say exit... What can I help you with?'
const HELP_REPROMPT = 'What can I help you with?'
const STOP_MESSAGE = 'Goodbye!'

const handlers = {
  'LaunchRequest': function () {
    this.emit('GetLatestIntent')
  },
  'GetLatestIntent': function () {
    return exports.createApp()
      .then(app => app.getLatestNews())
      .then(latestNews => {
        this.emit(':tell', convertToSsml(latestNews))
      })
      .catch(err => {
        console.error(err)
        this.emit(':tell', 'Please try again later')
      })
  },
  'GetRecentEventsIntent': async function () {
    try {
      const app = await exports.createApp()
      const duration = this.event.request.intent.slots.Duration.value
      if (duration < 1 || duration > 24) {
        this.emit(':tell', DURATION_LIMIT_MESSAGE)
        return
      }

      const clock = process.env.CLOCK === 'NOW' ? moment() : moment(process.env.CLOCK)
      const recentEvents = await app.getRecentEvents(duration, clock.utc().format())
      let speechOutput = recentEvents.length === 0
        ? `Sorry, there is nothing happening in the last ${duration} hour${duration > 1 ? 's' : ''}`
        : recentEvents.map((event, i, arr) => {
          let includeDate
          if (i > 0) {
            const previousMoment = moment(arr[i - 1].datetime)
            const currentMoment = moment(event.datetime)
            includeDate = !(previousMoment.isSame(currentMoment, 'year') && previousMoment.isSame(currentMoment, 'month') && previousMoment.isSame(currentMoment, 'day'))
          } else {
            includeDate = true
          }
          return convertToSsml(event, includeDate)
        }).join('')

      this.emit(':tell', speechOutput)
    } catch (err) {
      console.error(err)
      this.emit(':tell', 'Please try again later')
    }
  },
  'AMAZON.HelpIntent': function () {
    this.response.speak(HELP_MESSAGE).listen(HELP_REPROMPT)
    this.emit(':responseReady')
  },
  'AMAZON.CancelIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  },
  'AMAZON.StopIntent': function () {
    this.emit(':tell', STOP_MESSAGE)
  }
}

exports.handler = function (event, context, callback) {
  const alexa = Alexa.handler(event, context, callback)
  alexa.appId = 'amzn1.ask.skill.8955b37b-4975-4462-a4d9-4aba0ad647f0'
  alexa.registerHandlers(handlers)
  alexa.execute()
}

exports.createApp = createApp
exports.handlers = handlers
<|endoftext|>


<commit_before>var markers = [];
var map;
var currentMarker = null;
var initialLocation;
var browserSupportFlag =  new Boolean();
var tuesLocation;
var addSpaceContent;
var removeMarker = false;
var currentTitle = "Title";
var currentDescription = "You can plant a tree here";
var editingTitle = false;
var editingDescription = false;

$(document).ready(function(){
	Parse.initialize("ypv4dSS2h2pN6UTduc8hC9czpjBRJIklN7gN4ULv", "EgGSdtxDzc7GtuIvnGaaF3NBbRmuRRPq6B6yKbRV");
	$("#saving").hide();
	loadMarkers();
});

function initMap() {
	map = new google.maps.Map(document.getElementById('map'), {
		center: {lat: 42.667877, lng: 25.163029},
		zoom: 8
	});
	google.maps.event.addListener(map, "click", function(e) {
		placeMarker(e.latLng, map);
	});

	if(navigator.geolocation) {
    	browserSupportFlag = true;
    	navigator.geolocation.getCurrentPosition(function(position) {
      	initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
      	map.setCenter(initialLocation);
    	}
					//bugs out for me
				 //, function() {
      	//	handleNoGeolocation(browserSupportFlag);
    		//}
																							);
	}
	// Browser doesn't support Geolocation
	else {
		browserSupportFlag = false;
	    handleNoGeolocation(browserSupportFlag);
	}
}

function hideInfos()
{
	for (var key in markers) {
	    markers[key].info.close();
	}
}

function setImage(id)
{
	var ParseSpace = Parse.Object.extend("Spaces");
	var query = new Parse.Query(ParseSpace);
	$("#saving").show();
	query.get(id, {
	  success: function(object) {
		  var imageFile = object.get('image');
			var imageURL = imageFile.url();
			$('#spot-image')[0].src = imageURL;
			$('#spot-image-big')[0].href = imageURL;

			imageFile = object.get('image2');
			if(imageFile)
			{
				imageURL = imageFile.url();
				$('#image-label')[0].src = imageURL;
			}
			else
			{
				$('#image-label')[0].src = "../images/add_picture.png";
			}
			$("#saving").hide();
	  },
	  error: function(object, error) {
	    alert ("error "+ error.code);
			$("#saving").hide();
	  }
	});
}

function findId(mark)
{
	for (var key in markers) {

	    if(markers[key] == mark)
	    {
	    	return key;
	    }
	}

	return false;
}

function placeMarker(pos, map){

	if(removeMarker)
	{
		currentMarker.setMap(null);
	}
	else
	{
		removeMarker = true;
	}

	hideInfos()

	currentMarker = new google.maps.Marker({
		position: pos,
		map: map,
		icon: "../images/freespot.png"
	});

	currentMarker.info = new google.maps.InfoWindow({
		content: addSpaceContent
	});

	currentMarker.addListener("click", function(){
		hideInfos();
		this.info.open(map, this);
		removeMarker = !findId(currentMarker);
		setImage(findId(this));
	});

	currentMarker.info.open(map, currentMarker);
}

function loadMarkers(){
	var ParseSpace = Parse.Object.extend("Spaces");
	var query = new Parse.Query(ParseSpace);
	query.find({
		success: function(results){
			for(var i = 0; i < results.length; i++){
				var id = results[i].id;
				var currIcon;

				if(results[i].get("plantedTree"))
				{
					currIcon = "../images/tree_small.png";
				}
				else{
					currIcon = "../images/freespot.png";
				}
				var marker_pos = results[i].get("coordinates");
				markers[id ] = new google.maps.Marker({
					position: new google.maps.LatLng(marker_pos.latitude, marker_pos.longitude),
					icon: currIcon
				});

				markers[id].info = new google.maps.InfoWindow({
					content: results[i].get("info")
				});

				markers[id].addListener("click", function(){
					hideInfos()

					if(removeMarker)
					{
						currentMarker.setMap(null);
					}
					else
					{
						removeMarker = true;
					}

					this.info.open(map, this);
					removeMarker = false;
					currentMarker = this;
					setImage(findId(this));
				});

				markers[id].setMap(map);
			}
		},
		error: function(error){
			alert("error " + error.code);
		}
	});
}

function getFileName()
{
	var fullPath = document.getElementById('file-input').value;
	if (fullPath) {
		var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
		var filename = fullPath.substring(startIndex);
		if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
			filename = filename.substring(1);
		}
		return filename;
	}
}

function saveMarker(){

	spaceContent = '
'+
	'
'+currentTitle+'

 '+currentDescription+'

' +

	'

' +
						''+
						'	'+
		''+
						''+
							''+
							'<input id="file-input" onchange="readURL(this)" type="file"/>'+
						''+
					'

'+
					'
'+
					''+
					''+
							'<button onclick="deleteMarker()">Delete</button>'+
						''+
					''+
					'	'+
					''+
					''+
							'<button onclick="updateMarker()">Update</button>'+
					''
					'

';

	localStorage.clear();
	var ParseSpace = Parse.Object.extend("Spaces");
	var new_parse_space = new ParseSpace();
	var space_pos = new Parse.GeoPoint(currentMarker.position.lat(), currentMarker.position.lng());
	// new_parse_space.set("objectId", $("#infoTitle").html());
	new_parse_space.set("coordinates", space_pos);
	new_parse_space.set("info", spaceContent);
	new_parse_space.set("name", currentTitle);
	new_parse_space.set("plantedTree", false);

	// imageUpload

	var fileUploadControl = $("#file-input")[0];

	//get the file from the html element
	var file = fileUploadControl.files[0];

	if(file)
	{
		//name for the file
		var name = getFileName();
		//make the file ready for the DB
		var parseFile = new Parse.File(name, file);

		new_parse_space.set("image", parseFile);
		$("#saving").show();
		new_parse_space.save(null, {
			success: function(object) {
				currentMarker.info.close();
				markers[new_parse_space.id] = currentMarker;
				currentMarker = 0;
				removeMarker = false;
				markers[new_parse_space.id].info = new google.maps.InfoWindow({
					content: spaceContent
				});
				$("#saving").hide();
			},
			error: function(model, error) {
			// Show the error message somewhere and let the user try again.
					alert("Error: " + error.code + " " + error.message);
					$("#saving").hide();
			}
		});
	}
	else
	{
		alert("You must add an image!");
	}
};

function handleNoGeolocation(errorFlag) {
	if (errorFlag == true) {
	  alert("Geolocation service failed.");
	  initialLocation = tuesLocation;
	} else {
	  alert("Your browser doesn't support geolocation. We have placed you in TUES!");
	  initialLocation = tuesLocation;
	}

	map.setCenter(initialLocation);
}

function readURL(input) {

    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#image-label').attr('src', e.target.result);
        }

        reader.readAsDataURL(input.files[0]);
    }
}

function deleteMarker(){

	if(currentMarker)
	{
		var ParseSpace = Parse.Object.extend("Spaces");
		var query = new Parse.Query(ParseSpace);
		$("#saving").show();

		query.get(findId(currentMarker), {
		  success: function(object) {
			    object.destroy();
				$("#saving").hide();
		  },
		  error: function(object, error) {
		    alert ("error "+ error.code);
				$("#saving").hide();
		  }
		});

		currentMarker.setMap(null);
	}
}

function editTitle()
{
	if(!editingTitle)
	{
		$("#infoTitle").before('<input type="text" id = "titleEdit" class = "editingBox" name="" value="'+$("#infoTitle").html()+'">');
		document.getElementById("infoTitle").style.display = 'none';
	}
	else
	{
		currentTitle = $('#titleEdit').val();
		$("#infoTitle").html(currentTitle);
		document.getElementById("infoTitle").style.display = 'block';
		$("#titleEdit").remove();

	}

	editingTitle = !editingTitle;
}

function editDescription()
{
	if(!editingDescription)
	{
		$("#infoDescription").before('<input type="text" id = "descriptionEdit" class = "editingBox" name="" value="'+$("#infoDescription").html()+'">');
		document.getElementById("infoDescription").style.display = 'none';
	}
	else
	{
		currentDescription = $('#descriptionEdit').val();
		$("#infoDescription").html(currentDescription);
		document.getElementById("infoDescription").style.display = 'block';
		$("#descriptionEdit").remove();
	}

	editingDescription = !editingDescription;
}

function updateMarker(){

	if(currentMarker)
	{

		var ParseSpace = Parse.Object.extend("Spaces");
		var query = new Parse.Query(ParseSpace);
		var id = findId(currentMarker);
		$("#saving").show();
		query.get(id, {
		  success: function(object) {
			    var fileUploadControl = $("#file-input")[0];

				var file = fileUploadControl.files[0];

				if(file)
				{
					//name for the file
					var name = getFileName();
					//make the file ready for the DB
					var parseFile = new Parse.File(name, file);

					object.set("image2", parseFile);
					object.set("plantedTree", true);
					currentMarker.setIcon("../images/tree_small.png");
					currentMarker.info.close();
					currentMarker = 0;
					removeMarker = false;
					object.save();
				}
				else
				{
					alert("You must add an image!");
				}
				$("#saving").hide();
		  },
		  error: function(object, error) {
		    alert ("error "+ error.code);
				$("#saving").hide();
		  }
		});
	}
};

addSpaceContent = '
' +
					'
'+currentTitle+'
<input class ="editButton"type=image src = "../images/pencil.png" onclick = "editTitle()">

'+
					'
'+currentDescription+'
 <input class ="editButton"type=image src = "../images/pencil.png" onclick = "editDescription()">

' +
					'

'+
					'
'+
						'
'+
						'<input id="file-input" onchange="readURL(this)" type="file"/>
'+
					'
'+
					'
'+
						'<button onclick="saveMarker()">Accept</button>'+
					'
'+
				'
';

/*

'<input type="file" name="fileselect" id="fileselect"></input>'+
    					'<input id="uploadbutton" type="button" value="Upload"> </input>'+

addSpaceContent = '
'+
	'
name

 description
' +

	'

' +
						'

'+
						'	'+
		''+
						'

'+
					'

'+
		'

'+
						'<input type="submit" value = "Add picture" id = "ADDING"/>'+
					'
	'+
					'
'+
						'<input type="submit" value = "Add picture" id = "ADDING"/>'+
					'

';*/<commit_msg>WORKIKINGNGNGNGN<commit_after>var markers = [];
var map;
var currentMarker = null;
var initialLocation;
var browserSupportFlag =  new Boolean();
var tuesLocation;
var addSpaceContent;
var removeMarker = false;
var currentTitle = "Title";
var currentDescription = "You can plant a tree here";
var editingTitle = false;
var editingDescription = false;

$(document).ready(function(){
	Parse.initialize("ypv4dSS2h2pN6UTduc8hC9czpjBRJIklN7gN4ULv", "EgGSdtxDzc7GtuIvnGaaF3NBbRmuRRPq6B6yKbRV");
	$("#saving").hide();
	loadMarkers();
});

function initMap() {
	map = new google.maps.Map(document.getElementById('map'), {
		center: {lat: 42.667877, lng: 25.163029},
		zoom: 8
	});
	google.maps.event.addListener(map, "click", function(e) {
		placeMarker(e.latLng, map);
	});

	if(navigator.geolocation) {
    	browserSupportFlag = true;
    	navigator.geolocation.getCurrentPosition(function(position) {
      	initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
      	map.setCenter(initialLocation);
    	}
					//bugs out for me
				 //, function() {
      	//	handleNoGeolocation(browserSupportFlag);
    		//}
																							);
	}
	// Browser doesn't support Geolocation
	else {
		browserSupportFlag = false;
	    handleNoGeolocation(browserSupportFlag);
	}
}

function hideInfos()
{
	for (var key in markers) {
	    markers[key].info.close();
	}
}

function setImage(id)
{
	var ParseSpace = Parse.Object.extend("Spaces");
	var query = new Parse.Query(ParseSpace);
	$("#saving").show();
	query.get(id, {
	  success: function(object) {
		  var imageFile = object.get('image');
			var imageURL = imageFile.url();
			$('#spot-image')[0].src = imageURL;
			$('#spot-image-big')[0].href = imageURL;

			imageFile = object.get('image2');
			if(imageFile)
			{
				imageURL = imageFile.url();
				$('#image-label')[0].src = imageURL;
			}
			else
			{
				$('#image-label')[0].src = "../images/add_picture.png";
			}
			$("#saving").hide();
	  },
	  error: function(object, error) {
	    alert ("error "+ error.code);
			$("#saving").hide();
	  }
	});
}

function findId(mark)
{
	for (var key in markers) {

	    if(markers[key] == mark)
	    {
	    	return key;
	    }
	}

	return false;
}

function placeMarker(pos, map){

	if(removeMarker)
	{
		currentMarker.setMap(null);
	}
	else
	{
		removeMarker = true;
	}

	hideInfos()

	currentMarker = new google.maps.Marker({
		position: pos,
		map: map,
		icon: "../images/freespot.png"
	});

	currentMarker.info = new google.maps.InfoWindow({
		content: addSpaceContent
	});

	currentMarker.addListener("click", function(){
		hideInfos();
		this.info.open(map, this);
		removeMarker = !findId(currentMarker);
		currentMarker = this;
		setImage(findId(this));
	});

	currentMarker.info.open(map, currentMarker);
}

function loadMarkers(){
	var ParseSpace = Parse.Object.extend("Spaces");
	var query = new Parse.Query(ParseSpace);
	query.find({
		success: function(results){
			for(var i = 0; i < results.length; i++){
				var id = results[i].id;
				var currIcon;

				if(results[i].get("plantedTree"))
				{
					currIcon = "../images/tree_small.png";
				}
				else{
					currIcon = "../images/freespot.png";
				}
				var marker_pos = results[i].get("coordinates");
				markers[id ] = new google.maps.Marker({
					position: new google.maps.LatLng(marker_pos.latitude, marker_pos.longitude),
					icon: currIcon
				});

				markers[id].info = new google.maps.InfoWindow({
					content: results[i].get("info")
				});

				markers[id].addListener("click", function(){
					hideInfos()

					if(removeMarker)
					{
						currentMarker.setMap(null);
					}
					else
					{
						removeMarker = true;
					}

					this.info.open(map, this);
					removeMarker = false;
					currentMarker = this;
					setImage(findId(this));
				});

				markers[id].setMap(map);
			}
		},
		error: function(error){
			alert("error " + error.code);
		}
	});
}

function getFileName()
{
	var fullPath = document.getElementById('file-input').value;
	if (fullPath) {
		var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
		var filename = fullPath.substring(startIndex);
		if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
			filename = filename.substring(1);
		}
		return filename;
	}
}

function saveMarker(){

	spaceContent = '
'+
	'
'+currentTitle+'

 '+currentDescription+'

' +

	'

' +
						''+
						'	'+
		''+
						''+
							''+
							'<input id="file-input" onchange="readURL(this)" type="file"/>'+
						''+
					'

'+
					'
'+
					''+
					''+
							'<button onclick="deleteMarker()">Delete</button>'+
						''+
					''+
					'	'+
					''+
					''+
							'<button onclick="updateMarker()">Update</button>'+
					''
					'

';

	localStorage.clear();
	var ParseSpace = Parse.Object.extend("Spaces");
	var new_parse_space = new ParseSpace();
	var space_pos = new Parse.GeoPoint(currentMarker.position.lat(), currentMarker.position.lng());
	// new_parse_space.set("objectId", $("#infoTitle").html());
	new_parse_space.set("coordinates", space_pos);
	new_parse_space.set("info", spaceContent);
	new_parse_space.set("name", currentTitle);
	new_parse_space.set("plantedTree", false);

	// imageUpload

	var fileUploadControl = $("#file-input")[0];

	//get the file from the html element
	var file = fileUploadControl.files[0];

	if(file)
	{
		//name for the file
		var name = getFileName();
		//make the file ready for the DB
		var parseFile = new Parse.File(name, file);

		new_parse_space.set("image", parseFile);
		$("#saving").show();
		new_parse_space.save(null, {
			success: function(object) {
				currentMarker.info.close();
				markers[new_parse_space.id] = currentMarker;
				currentMarker = 0;
				removeMarker = false;
				markers[new_parse_space.id].info = new google.maps.InfoWindow({
					content: spaceContent
				});
				$("#saving").hide();
			},
			error: function(model, error) {
			// Show the error message somewhere and let the user try again.
					alert("Error: " + error.code + " " + error.message);
					$("#saving").hide();
			}
		});
	}
	else
	{
		alert("You must add an image!");
	}
};

function handleNoGeolocation(errorFlag) {
	if (errorFlag == true) {
	  alert("Geolocation service failed.");
	  initialLocation = tuesLocation;
	} else {
	  alert("Your browser doesn't support geolocation. We have placed you in TUES!");
	  initialLocation = tuesLocation;
	}

	map.setCenter(initialLocation);
}

function readURL(input) {

    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#image-label').attr('src', e.target.result);
        }

        reader.readAsDataURL(input.files[0]);
    }
}

function deleteMarker(){

	if(currentMarker)
	{
		var ParseSpace = Parse.Object.extend("Spaces");
		var query = new Parse.Query(ParseSpace);
		$("#saving").show();

		query.get(findId(currentMarker), {
		  success: function(object) {
			    object.destroy();
				$("#saving").hide();
		  },
		  error: function(object, error) {
		    alert ("error "+ error.code);
				$("#saving").hide();
		  }
		});

		currentMarker.setMap(null);
	}
}

function editTitle()
{
	if(!editingTitle)
	{
		$("#infoTitle").before('<input type="text" id = "titleEdit" class = "editingBox" name="" value="'+$("#infoTitle").html()+'">');
		document.getElementById("infoTitle").style.display = 'none';
	}
	else
	{
		currentTitle = $('#titleEdit').val();
		$("#infoTitle").html(currentTitle);
		document.getElementById("infoTitle").style.display = 'block';
		$("#titleEdit").remove();

	}

	editingTitle = !editingTitle;
}

function editDescription()
{
	if(!editingDescription)
	{
		$("#infoDescription").before('<input type="text" id = "descriptionEdit" class = "editingBox" name="" value="'+$("#infoDescription").html()+'">');
		document.getElementById("infoDescription").style.display = 'none';
	}
	else
	{
		currentDescription = $('#descriptionEdit').val();
		$("#infoDescription").html(currentDescription);
		document.getElementById("infoDescription").style.display = 'block';
		$("#descriptionEdit").remove();
	}

	editingDescription = !editingDescription;
}

function updateMarker(){
	if(currentMarker)
	{

		var ParseSpace = Parse.Object.extend("Spaces");
		var query = new Parse.Query(ParseSpace);
		var id = findId(currentMarker);
		$("#saving").show();
		query.get(id, {
		  success: function(object) {
			    var fileUploadControl = $("#file-input")[0];

				var file = fileUploadControl.files[0];

				if(file)
				{
					//name for the file
					var name = getFileName();
					//make the file ready for the DB
					var parseFile = new Parse.File(name, file);

					object.set("image2", parseFile);
					object.set("plantedTree", true);
					currentMarker.setIcon("../images/tree_small.png");
					currentMarker.info.close();
					removeMarker = false;
					object.save();
				}
				else
				{
					alert("You must add an image!");
				}
				$("#saving").hide();
		  },
		  error: function(object, error) {
		    alert ("error "+ error.code);
				$("#saving").hide();
		  }
		});
	}
};

addSpaceContent = '
' +
					'
'+currentTitle+'
<input class ="editButton"type=image src = "../images/pencil.png" onclick = "editTitle()">

'+
					'
'+currentDescription+'
 <input class ="editButton"type=image src = "../images/pencil.png" onclick = "editDescription()">

' +
					'

'+
					'
'+
						'
'+
						'<input id="file-input" onchange="readURL(this)" type="file"/>
'+
					'
'+
					'
'+
						'<button onclick="saveMarker()">Accept</button>'+
					'
'+
				'
';

/*

'<input type="file" name="fileselect" id="fileselect"></input>'+
    					'<input id="uploadbutton" type="button" value="Upload"> </input>'+

addSpaceContent = '
'+
	'
name

 description
' +

	'

' +
						'

'+
						'	'+
		''+
						'

'+
					'

'+
		'

'+
						'<input type="submit" value = "Add picture" id = "ADDING"/>'+
					'
	'+
					'
'+
						'<input type="submit" value = "Add picture" id = "ADDING"/>'+
					'

';*/<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name webApp.controller:SubjectscontrollerCtrl
 * @description
 * # SubjectscontrollerCtrl
 * Controller of the webApp
 */
angular.module('webApp')
  .controller('SubjectsCtrl', function ($scope, $location, subjects) {
    $scope.subjects = subjects.getList();

    $scope.ranges = subjects.getRanges();

    $scope.selections={};
    var defaultval = "-All-";
    $scope.selections.gender=defaultval;
    $scope.selections.ethnicity = defaultval;
    $scope.selections.injuryLevel = defaultval;
    $scope.selections.shotAtPolice = defaultval;
    $scope.selections.weapons = defaultval;
    $scope.selections.year = defaultval;
    $scope.selections.agerange = defaultval;
    $scope.selections = _.extend($scope.selections,$location.search());

    subjects.setCriteria($scope.selections);

    function getNonDefaultSelections(){
        var culledList = {};
        for (var prop in $scope.selections) {
          if($scope.selections.hasOwnProperty(prop) && $scope.selections[prop]!=defaultval){
                culledList[prop]= $scope.selections[prop];
          }
      }
      return culledList;
  }

    $scope.update = function(){
        $location.search(getNonDefaultSelections());
        subjects.filterList($scope.selections);
    }

    //$scope.update();
  });
<commit_msg>updates<commit_after>'use strict';

/**
 * @ngdoc function
 * @name webApp.controller:SubjectscontrollerCtrl
 * @description
 * # SubjectsCtrl
 * Controller of the webApp
 */
angular.module('webApp')
  .controller('SubjectsCtrl', function ($scope, $location, subjects) {
    $scope.subjects = subjects.getList();

    $scope.ranges = subjects.getRanges();

    $scope.selections={};
    var defaultval = "-All-";
    $scope.selections.gender=defaultval;
    $scope.selections.ethnicity = defaultval;
    $scope.selections.injuryLevel = defaultval;
    $scope.selections.shotAtPolice = defaultval;
    $scope.selections.weapons = defaultval;
    $scope.selections.year = defaultval;
    $scope.selections.agerange = defaultval;
    $scope.selections = _.extend($scope.selections,$location.search());

    subjects.setCriteria($scope.selections);

    function getNonDefaultSelections(){
        var culledList = {};
        for (var prop in $scope.selections) {
          if($scope.selections.hasOwnProperty(prop) && $scope.selections[prop]!=defaultval){
                culledList[prop]= $scope.selections[prop];
          }
        }
        return culledList;
    }

    $scope.update = function(){
        $location.search(getNonDefaultSelections());
        subjects.filterList($scope.selections);
    }
  });
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var cost = function(c) {
    if (c === '^') return 3;

    if (c === '*') return 2;

    return 1;
};

var walkable = function(c) {
    return !(c === undefined || c === '~');
};

var p = function(x,y) {
    return {
	x: x,
	y: y
    };
};

var manhattanDistance = function(p1,p2) {
    return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
};

var Map = function(rows) {
    this.rows = rows;

    var findIt = function(rows, it) {
	for (var y=0;y<rows.length;++y)
	    for (var x=0;x<rows[y].length;++x)
		if (rows[y][x] === it)
		    return p(x,y);
    };

    this.goal = function() {
	return findIt(this.rows, 'X');
    };

    this.start = function() {
	return findIt(this.rows, '@');
    };

    this.at = function(pt) {
	if (this.rows[pt.y])
	    return this.rows[pt.y][pt.x];
    };

    var surroundings = function(pt) {
	var left = p(pt.x-1,pt.y);
	var right = p(pt.x+1,pt.y);
	var up = p(pt.x, pt.y-1);
	var down = p(pt.x, pt.y+1);

	return [left,right,up,down];
    };

    this.moves = function(pt) {
	var choices = [];
	var deltas = surroundings(pt);

	for (var i=0;i<deltas.length;++i)
	    if (walkable(this.at(deltas[i])))
		choices.push(deltas[i]);

	return choices;
    };

    this.cost = function(pt) {
	return 1;
    };

    return this;
};

var load = function(s) {
    return new Map(s.split('\n'));
};

describe('a* search algorithm', function() {

    describe('map', function() {

	var defaultMap = '@.\n.X';

	it('finds goal', function() {
	    var map = load(defaultMap);
	    var p = map.goal();

	    assert.equal(1, p.x);
	    assert.equal(1, p.y);
	});

	it('finds start', function() {
	    var map = load(defaultMap);
	    var p = map.start();

	    assert.equal(0, p.x);
	    assert.equal(0, p.y);
	});

	it('finds choices', function() {
	    var map = load(defaultMap);

	    var choices = map.moves(map.start());

	    assert.equal(2, choices.length);
	});

	it('can cost choices', function() {
	    var map = load(defaultMap);
	    var choices = map.moves(map.start());

	    assert.equal(map.cost(choices[0]), map.cost(choices[1]));
	    assert.equal(1, map.cost(choices[0]));
	});
    });

    describe('costs', function() {
	it('flatlands cost 1', function() {
	    assert.equal(1, cost('.'));
	    assert.equal(1, cost('@'));
	    assert.equal(1, cost('X'));
	});

	it('forest costs 2', function() {
	    assert.equal(2, cost('*'));
	});

	it('mountain costs 3', function() {
	    assert.equal(3, cost('^'));
	});

	it('walkable', function() {
	    assert(walkable('.'));
	    assert(walkable('*'));
	    assert(walkable('^'));
	    assert(walkable('@'));
	    assert(walkable('X'));
	});

	it('non-walkable', function() {
	    assert(!walkable(undefined));
	    assert(!walkable('~'));
	});
    });

    describe('Manhattan distance', function() {
	it('works in a straight line', function() {
	    assert.equal(5, manhattanDistance(p(0,0), p(5,0)));
	    assert.equal(3, manhattanDistance(p(0,3), p(0,0)));
	});
    });
});
<commit_msg>should have differing values<commit_after>"use strict";

var assert = require('assert');

var cost = function(c) {
    if (c === '^') return 3;

    if (c === '*') return 2;

    return 1;
};

var walkable = function(c) {
    return !(c === undefined || c === '~');
};

var p = function(x,y) {
    return {
	x: x,
	y: y
    };
};

var manhattanDistance = function(p1,p2) {
    return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y);
};

var Map = function(rows) {
    this.rows = rows;

    var findIt = function(rows, it) {
	for (var y=0;y<rows.length;++y)
	    for (var x=0;x<rows[y].length;++x)
		if (rows[y][x] === it)
		    return p(x,y);
    };

    this.goal = function() {
	return findIt(this.rows, 'X');
    };

    this.start = function() {
	return findIt(this.rows, '@');
    };

    this.at = function(pt) {
	if (this.rows[pt.y])
	    return this.rows[pt.y][pt.x];
    };

    var surroundings = function(pt) {
	var left = p(pt.x-1,pt.y);
	var right = p(pt.x+1,pt.y);
	var up = p(pt.x, pt.y-1);
	var down = p(pt.x, pt.y+1);

	return [left,right,up,down];
    };

    this.moves = function(pt) {
	var choices = [];
	var deltas = surroundings(pt);

	for (var i=0;i<deltas.length;++i)
	    if (walkable(this.at(deltas[i])))
		choices.push(deltas[i]);

	return choices;
    };

    this.cost = function(pt) {
	return 1;
    };

    return this;
};

var load = function(s) {
    return new Map(s.split('\n'));
};

describe('a* search algorithm', function() {

    describe('map', function() {

	var defaultMap = '@.\n.X';

	it('finds goal', function() {
	    var map = load(defaultMap);
	    var p = map.goal();

	    assert.equal(1, p.x);
	    assert.equal(1, p.y);
	});

	it('finds start', function() {
	    var map = load(defaultMap);
	    var p = map.start();

	    assert.equal(0, p.x);
	    assert.equal(0, p.y);
	});

	it('finds choices', function() {
	    var map = load(defaultMap);

	    var choices = map.moves(map.start());

	    assert.equal(2, choices.length);
	});

	it('can cost choices', function() {
	    var map = load(defaultMap);
	    var choices = map.moves(map.start());

	    assert.equal(map.cost(choices[0]), map.cost(choices[1]));
	    assert.equal(1, map.cost(choices[0]));
	});

	it('can cost variable choices', function() {
	    var map = load('@*\n.X');
	    var choices = map.moves(map.start());

	    assert(map.cost(choices[0]) !== map.cost(choices[1]));
	});
    });

    describe('costs', function() {
	it('flatlands cost 1', function() {
	    assert.equal(1, cost('.'));
	    assert.equal(1, cost('@'));
	    assert.equal(1, cost('X'));
	});

	it('forest costs 2', function() {
	    assert.equal(2, cost('*'));
	});

	it('mountain costs 3', function() {
	    assert.equal(3, cost('^'));
	});

	it('walkable', function() {
	    assert(walkable('.'));
	    assert(walkable('*'));
	    assert(walkable('^'));
	    assert(walkable('@'));
	    assert(walkable('X'));
	});

	it('non-walkable', function() {
	    assert(!walkable(undefined));
	    assert(!walkable('~'));
	});
    });

    describe('Manhattan distance', function() {
	it('works in a straight line', function() {
	    assert.equal(5, manhattanDistance(p(0,0), p(5,0)));
	    assert.equal(3, manhattanDistance(p(0,3), p(0,0)));
	});
    });
});
<|endoftext|>