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

// regular expression patterns
var find_tmpl = /\{([\w\.]+)\}/g;
var find_braces = /\{|\}/g;

/**
 * Resolve data fields in for incoming configs.
 *
 * @private
 * @param {object} The config config.
 * @param {object} The data object.
 * @param {object} The module instance.
 */
module.exports = function (stream, options, data) {

    // ignore if data is null
    if (data === null) {
        return data;
    }

    if (typeof data !== 'object') {
        data = {data: data};
    }

    // ensure data object
    if (options && (options.data || options.set)) {
        data = data || {};
    }

    // extend data with location data (hash, search, path)
    if (global.location) {
        handleStateValues(data);
    }

    var key;

    // "data": {"key": "{value}"}
    if (options.data) {
        for (key in options.data) {

            // parse the data field values
            data[key] = parsePath(options.data[key], this._, data);
        }
    }

    // search for path in data and module instance and set it to the cloned config
    // "set": {"key": "{path}", "key": "${#css:attr}"}
    if (options.set) {
        for (key in options.set) {
            data[key] = parsePath(options.set[key], this._, data, true);
        }
    }

    // create nest objects with flat keys
    if (options.data || options.set) {
        data = utils.deep(data);
    }

    return data;
};

/**
 * Extend event object with location data.
 *
 * @private
 * @param {object} The event object.
 */
function handleStateValues (data) {

    // add pathname to data object
    data._path = global.location.pathname.substr(1).split('/');

    // parse and append url search to data
    if (global.location.search && !data._search) {
        data._search = searchToJSON(global.location.search);
    }

    // append url hash to data
    if (global.location.hash && !data._hash) {
        data._hash = global.location.hash.substr(1);
    }
}

/**
 * Parse a state search string to JSON.
 * Credentials: http://snipplr.com/view/70905/search-string-to-json/
 *
 * @private
 */
function searchToJSON(search) {
    var rep = {'?':'{"','=':'":"','&':'","'};
    var s = search.replace(/[\?\=\&]/g, function(r) {
        return rep[r];
    });
    return JSON.parse(s.length? s+'"}' : "{}");
}

/**
 * Replace data fields in a string.
 *
 * @private
 * @param {string} The string.
 * @param {object} The data context.
 */
function parsePath (path, module_instance, data, getValue) {

    if (typeof path !== 'string') {
        return path;
    }

    if (path.indexOf('{') < 0) {
        return getValue ? getPathValue(path, data, module_instance) : path;
    }

    var match = path.match(find_tmpl);

    // replace route with data
    if (match) {
        for (var i = 0, value; i < match.length; ++i) {

            // get value from object
            value = utils.path(match[i].replace(find_braces, ''), [data, module_instance]);

            // replace value in route
            if (typeof value !== 'undefined') {
                path = typeof value === 'object' ? value : path.replace(match[i], value);
            }
        }
    }

    // get path value or return path
    return getValue ? getPathValue(path, data, module_instance) : path;
}

/**
 * Merge dynamic data to the event data object.
 *
 * @private
 * @param {object} The module instance.
 * @param {object} The event config.
 * @param {object} The event data object.
 */
function getPathValue (path, module_instance, data) {

    // get an attribute value from a dom element or the element itself
    if (path[0] === '$') {
        path = path.substr(1).split(':');

        // get find an element in the document
        path[0] = document.querySelector(path[0]);

        // set data key to the dom attribute value or the dom element
        return path[1] && path[0][path[1]] !== undefined ? path[0][path[1]] : path[0];

    }

    if (!data) {
        return utils.path(path, [module_instance, global]);
    }

    // return search value with a path: 1. data, 3. instance, 4. global
    return utils.path(path, [data, module_instance, global]);
}
<commit_msg>transforming data is job of a module<commit_after><|endoftext|>


<commit_before>var key = 'product_';

function something()
{
	var x = window.localStorage.getItem('aaa');

	x = x*1 + 1;

	window.localStorage.setItem('aaa', x);

	alert(x);
}

function add_to_cart(id)
{
	var x = window.localStorage.getItem(key+id);
	x = x*1 + 1;
	window.localStorage.setItem(key+id, x);
}

function get_total_product_count ()
{
	var total = 0;

	$.each(localStorage, function(k, v){
  		if (k.indexOf(key) > -1) {
			total = total*1 + v*1;
  		}
 	});

	window.localStorage.setItem('total', total)
}

function get_product_count (id)
{
	var result = window.localStorage.getItem(key+id);
	if (result == null) return 0
		else
	return result;
}

<commit_msg>Add comments<commit_after>var key = 'product_';

function something()
{
	var x = window.localStorage.getItem('aaa');

	x = x*1 + 1;

	window.localStorage.setItem('aaa', x);

	alert(x);
}

function add_to_cart(id)
{
	var x = window.localStorage.getItem(key+id);
	x = x*1 + 1;
	window.localStorage.setItem(key+id, x);
}

function get_total_product_count ()
{
	var total = 0;

	$.each(localStorage, function(k, v){
  		if (k.indexOf(key) > -1) {
			total = total*1 + v*1;
  		}
 	});

	window.localStorage.setItem('total', total)
}

function get_product_count (id)
{
	//var key = window.localStorage.key(index); // get the key in hash
	var result = window.localStorage.getItem(key+id);
	if (result == null) return 0
		else
	return result;
}

/*
function change(el)
{
    el.value = el.value*1 + 1;
}
*/<|endoftext|>


<commit_before>define(function(require) {
  var $ = require('jquery')

  function DateTime(year, month, date, hours, minutes, seconds) {
    if(arguments.length == 0) this.date = new Date()
    else if(year instanceof Date) this.date = new Date(year.getTime())
    else if(year instanceof DateTime) this.date = new Date(year.date.getTime())
    else if(typeof year == 'string') this.date = new Date(year)
    else if(typeof year == 'number') this.date = createSafeDate(+year, +month, +date, +hours, +minutes, +seconds)
    else throw Error('None of supported parameters was used for constructor: ' + Array.prototype.slice.call(arguments).join(', '))

    function createSafeDate(year, month, date, hours, minutes, seconds) {
      hours = hours || 0
      minutes = minutes || 0
      seconds = seconds || 0
      var newDate = new Date(year, month -1, date, hours, minutes, seconds, 0)
      if(newDate.toString() == 'Invalid Date' ||
        month != newDate.getMonth() + 1 ||
        year != newDate.getFullYear() ||
        date != newDate.getDate() ||
        hours != newDate.getHours() ||
        minutes != newDate.getMinutes() ||
        seconds != newDate.getSeconds()) throw Error('Invalid Date: ' + year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + seconds)
      return  newDate
    }
  }

  DateTime.SUNDAY = 0
  DateTime.MONDAY = 1
  DateTime.TUESDAY = 2
  DateTime.WEDNESDAY = 3
  DateTime.THURSDAY = 4
  DateTime.FRIDAY = 5
  DateTime.SATURDAY = 6

  DateTime.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  DateTime.y2kYear = 50
  DateTime.monthNumbers = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 }

  DateTime.fromDateTime = function(year, month, day, hours, minutes) {
    return new DateTime(year, month, day, hours, minutes)
  }

  DateTime.fromDate = function(year, month, day) {
    return DateTime.fromDateTime(year, month, day, 0, 0)
  }

  DateTime.fromDateObject = function(date) {
    return DateTime.fromMillis(date.getTime())
  }

  /**
   * Returns date from ISO date ignoring time information
   * @param isoDate String YYYY-MM-DDTHH-MM
   * @return {DateTime}
   */
  DateTime.fromIsoDate = function(isoDate) {
    var optionalTimePattern = /^\d{4}-[01]\d-[0-3]\d(T[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z?))?$/
    if(!optionalTimePattern.test(isoDate)) throw Error(isoDate + ' is not valid ISO Date (YYYY-MM-DD or YYYY-MM-DDTHH:MM)')
    var date = parseDate(isoDate.split('T')[0])
    return DateTime.fromDate(date.year, date.month, date.day)
  }

  /**
   * Returns date with time from ISO date
   * @param isoDateTime String YYYY-MM-DDTHH-MM
   * @return {DateTime}
   */
  DateTime.fromIsoDateTime = function(isoDateTime) {
    var fullPatternTest = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z?)/
    if(!fullPatternTest.test(isoDateTime)) throw Error(isoDateTime + ' is not valid ISO Date (YYYY-MM-DDTHH:MM)')

    var dateAndTime = isoDateTime.split('T')
    var time = parseTime(dateAndTime.length == 2 && dateAndTime[1])
    var date = parseDate(dateAndTime[0])
    return new DateTime(date.year, date.month, date.day, time.hours, time.minutes, time.seconds)
  }

  function parseDate(str) {
    var dateComponents = str.split('-')
    return {
      year : +dateComponents[0],
      month: +dateComponents[1],
      day  : +dateComponents[2]
    }
  }

  function parseTime(str) {
    if(str) {
      var timeComponents = str.split(':')
      return {
        hours  : +timeComponents[0],
        minutes: +timeComponents[1],
        seconds: +timeComponents[2] || 0
      }
    } else {
      return { hours: 0, minutes: 0 }
    }
  }

  DateTime.fromMillis = function(ms) { return new DateTime(new Date(ms)) }

  $.each([
    'getTime',
    'getFullYear',
    'getDate',
    'getDay',
    'getHours',
    'getMinutes',
    'getSeconds',
    'getMilliseconds'
  ], function(_index, func) {
    DateTime.prototype[func] = function() { return this.date[func]() }
  })

  DateTime.prototype.withResetMS = function() {
    var newDate = this.clone()
    newDate.date.setMilliseconds(0)
    return newDate
  }

  DateTime.prototype.withTime = function(h, m) {
    if(typeof h == 'string') {
      var hoursAndMinutes = h.split(':')
      h = hoursAndMinutes[0]
      m = hoursAndMinutes[1]
    }
    var dateWithTime = this.clone()
    dateWithTime.date.setHours(h)
    dateWithTime.date.setMinutes(m)
    dateWithTime.date.setSeconds(0)
    dateWithTime.date.setMilliseconds(0)
    return dateWithTime
  }

  DateTime.SECOND = 1000
  DateTime.MINUTE = 60 * DateTime.SECOND
  DateTime.HOUR = 60 * DateTime.MINUTE
  DateTime.DAY = 24 * DateTime.HOUR
  DateTime.WEEK = 7 * DateTime.DAY

  DateTime.now = function() {
    if(typeof DateTime._now == 'undefined') {
      DateTime._now = new DateTime()
    }
    return DateTime._now
  }

  DateTime.getDaysInMonth = function(year, month) {
    if(month > 12 || month < 1)
      throw new Error('Month must be between 1-12')
    var yearAndMonth = year * 12 + month
    return DateTime.fromDate(Math.floor(yearAndMonth / 12), yearAndMonth % 12 + 1, 1).minusDays(1).getDate()
  }

  DateTime.getDayInYear = function(year, month, day) {
    return DateTime.fromDate(year, 1, 1).distanceInDays(DateTime.fromDate(year, month, day)) + 1
  }

  DateTime.prototype.getDaysInMonth = function() { return DateTime.getDaysInMonth(this.getFullYear(), this.getMonth()) }

  DateTime.prototype.getDayInYear = function() { return DateTime.getDayInYear(this.getFullYear(), this.getMonth(), this.getDate()) }

  DateTime.prototype.plusDays = function(days) {
    var newDateTime = this.clone()
    var hours = this.getHours()
    newDateTime.date.setTime(this.getTime() + days * DateTime.DAY)

    // Fix the DateTime offset caused by daylight saving time
    var delta = hours - newDateTime.getHours()
    if(delta != 0) {
      // Correct the delta to be between [-12, 12]
      if(delta > 12) {
        delta -= 24
      }
      if(delta < -12) {
        delta += 24
      }
      newDateTime.date.setTime(newDateTime.getTime() + (delta * DateTime.HOUR))
    }
    return newDateTime
  }

  DateTime.prototype.minusDays = function(days) {
    return this.plusDays(-days)
  }

  DateTime.prototype.compareTo = function(date) {
    if(!date) {
      return 1
    }
    var lhs = this.getTime()
    var rhs = date.getTime()
    if(lhs < rhs) {
      return -1
    } else {
      if(lhs > rhs) {
        return 1
      } else {
        return 0
      }
    }
  }

  DateTime.prototype.isToday = function() { return this.equalsOnlyDate(DateTime.now()) }

  DateTime.prototype.getWeekInYear = function(weekNumberingSystem) {
    if(weekNumberingSystem != 'US' && weekNumberingSystem != 'ISO') {
      throw('Week numbering system must be either US or ISO, was ' + weekNumberingSystem)
    }

    var firstDay = new Date(this.getFullYear(), 0, 1).getDay()
    if(weekNumberingSystem == 'US') {
      return Math.ceil((this.getDayInYear() + firstDay) / 7)
    }
    var THU = 4
    var weekday = this.getDay()
    if(weekday == 0) weekday = 7
    if(firstDay == 0) firstDay = 7
    // If Dec 29 falls on Mon, Dec 30 on Mon or Tue, Dec 31 on Mon - Wed, it's on the first week of next year
    if(this.getMonth() == 12 && this.getDate() >= 29 && (this.getDate() - weekday) > 27) {
      return 1
    }
    // If Jan 1-3 falls on Fri, Sat or Sun, it's on the last week of the previous year
    if(this.getMonth() == 1 && this.getDate() < 4 && weekday > THU) {
      return new DateTime(new Date(this.getFullYear() - 1, 11, 31)).getWeekInYear('ISO')
    }
    var week = Math.ceil((this.getDayInYear() + firstDay - 1) / 7)
    // If first days of this year are on last year's last week, the above gives one week too much
    if(firstDay > THU) week--
    return week
  }

  DateTime.prototype.clone = function() { return new DateTime(this.date) }

  DateTime.prototype.isOddMonth = function() { return this.getMonth() % 2 == 0 }

  DateTime.prototype.equalsOnlyDate = function(date) {
    if(!date) {
      return false
    }
    return this.getMonth() == date.getMonth() && this.getDate() == date.getDate() && this.getFullYear() == date.getFullYear()
  }

  DateTime.prototype.isBetweenDates = function(start, end) {
    if(start.getTime() > end.getTime()) throw Error("start date can't be after end date")
    return this.compareTo(start) >= 0 && this.compareTo(end) <= 0
  }

  DateTime.prototype.firstDateOfMonth = function() { return DateTime.fromDate(this.getFullYear(), this.getMonth(), 1) }

  DateTime.prototype.lastDateOfMonth = function() { return DateTime.fromDate(this.getFullYear(), this.getMonth(), this.getDaysInMonth()) }

  DateTime.prototype.distanceInDays = function(date) {
    var first = parseInt(this.getTime() / DateTime.DAY, 10)
    var last = parseInt(date.getTime() / DateTime.DAY, 10)
    return (last - first)
  }

  DateTime.prototype.withWeekday = function(weekday) { return this.plusDays(weekday - this.getDay()) }

  DateTime.prototype.getOnlyDate = function() { return DateTime.fromDate(this.getFullYear(), this.getMonth(), this.getDate()) }

  DateTime.prototype.isWeekend = function() { return this.getDay() == 6 || this.getDay() == 0 }

  DateTime.prototype.toString = function() { return this.toISOString() }

  DateTime.prototype.getFirstDateOfWeek = function(locale) {
    var firstWeekday = locale ? locale.firstWeekday : DateTime.MONDAY
    if(firstWeekday < this.getDay()) return this.plusDays(firstWeekday - this.getDay())
    else if(firstWeekday > this.getDay()) return this.plusDays(firstWeekday - this.getDay() - 7)
    else return this.clone()
  }

  DateTime.prototype.toISOString = function() {
    return $.map([this.getFullYear(), (this.getMonth()), this.getDate()], withTwoDigitsAtLeast).join('-') + 'T' +
      $.map([this.getHours(), this.getMinutes(), this.getSeconds()], withTwoDigitsAtLeast).join(':')
    function withTwoDigitsAtLeast(value) { return value < 10 ? '0' + value : '' + value}
  }

  DateTime.prototype.getMonth = function() {
    return this.date.getMonth() + 1
  }

  return DateTime
})
<commit_msg>Ignore times in isBetweenDates method<commit_after>define(function(require) {
  var $ = require('jquery')

  function DateTime(year, month, date, hours, minutes, seconds) {
    if(arguments.length == 0) this.date = new Date()
    else if(year instanceof Date) this.date = new Date(year.getTime())
    else if(year instanceof DateTime) this.date = new Date(year.date.getTime())
    else if(typeof year == 'string') this.date = new Date(year)
    else if(typeof year == 'number') this.date = createSafeDate(+year, +month, +date, +hours, +minutes, +seconds)
    else throw Error('None of supported parameters was used for constructor: ' + Array.prototype.slice.call(arguments).join(', '))

    function createSafeDate(year, month, date, hours, minutes, seconds) {
      hours = hours || 0
      minutes = minutes || 0
      seconds = seconds || 0
      var newDate = new Date(year, month -1, date, hours, minutes, seconds, 0)
      if(newDate.toString() == 'Invalid Date' ||
        month != newDate.getMonth() + 1 ||
        year != newDate.getFullYear() ||
        date != newDate.getDate() ||
        hours != newDate.getHours() ||
        minutes != newDate.getMinutes() ||
        seconds != newDate.getSeconds()) throw Error('Invalid Date: ' + year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + seconds)
      return  newDate
    }
  }

  DateTime.SUNDAY = 0
  DateTime.MONDAY = 1
  DateTime.TUESDAY = 2
  DateTime.WEDNESDAY = 3
  DateTime.THURSDAY = 4
  DateTime.FRIDAY = 5
  DateTime.SATURDAY = 6

  DateTime.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  DateTime.y2kYear = 50
  DateTime.monthNumbers = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 }

  DateTime.fromDateTime = function(year, month, day, hours, minutes) {
    return new DateTime(year, month, day, hours, minutes)
  }

  DateTime.fromDate = function(year, month, day) {
    return DateTime.fromDateTime(year, month, day, 0, 0)
  }

  DateTime.fromDateObject = function(date) {
    return DateTime.fromMillis(date.getTime())
  }

  /**
   * Returns date from ISO date ignoring time information
   * @param isoDate String YYYY-MM-DDTHH-MM
   * @return {DateTime}
   */
  DateTime.fromIsoDate = function(isoDate) {
    var optionalTimePattern = /^\d{4}-[01]\d-[0-3]\d(T[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z?))?$/
    if(!optionalTimePattern.test(isoDate)) throw Error(isoDate + ' is not valid ISO Date (YYYY-MM-DD or YYYY-MM-DDTHH:MM)')
    var date = parseDate(isoDate.split('T')[0])
    return DateTime.fromDate(date.year, date.month, date.day)
  }

  /**
   * Returns date with time from ISO date
   * @param isoDateTime String YYYY-MM-DDTHH-MM
   * @return {DateTime}
   */
  DateTime.fromIsoDateTime = function(isoDateTime) {
    var fullPatternTest = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z?)/
    if(!fullPatternTest.test(isoDateTime)) throw Error(isoDateTime + ' is not valid ISO Date (YYYY-MM-DDTHH:MM)')

    var dateAndTime = isoDateTime.split('T')
    var time = parseTime(dateAndTime.length == 2 && dateAndTime[1])
    var date = parseDate(dateAndTime[0])
    return new DateTime(date.year, date.month, date.day, time.hours, time.minutes, time.seconds)
  }

  function parseDate(str) {
    var dateComponents = str.split('-')
    return {
      year : +dateComponents[0],
      month: +dateComponents[1],
      day  : +dateComponents[2]
    }
  }

  function parseTime(str) {
    if(str) {
      var timeComponents = str.split(':')
      return {
        hours  : +timeComponents[0],
        minutes: +timeComponents[1],
        seconds: +timeComponents[2] || 0
      }
    } else {
      return { hours: 0, minutes: 0 }
    }
  }

  DateTime.fromMillis = function(ms) { return new DateTime(new Date(ms)) }

  $.each([
    'getTime',
    'getFullYear',
    'getDate',
    'getDay',
    'getHours',
    'getMinutes',
    'getSeconds',
    'getMilliseconds'
  ], function(_index, func) {
    DateTime.prototype[func] = function() { return this.date[func]() }
  })

  DateTime.prototype.withResetMS = function() {
    var newDate = this.clone()
    newDate.date.setMilliseconds(0)
    return newDate
  }

  DateTime.prototype.withTime = function(h, m) {
    if(typeof h == 'string') {
      var hoursAndMinutes = h.split(':')
      h = hoursAndMinutes[0]
      m = hoursAndMinutes[1]
    }
    var dateWithTime = this.clone()
    dateWithTime.date.setHours(h)
    dateWithTime.date.setMinutes(m)
    dateWithTime.date.setSeconds(0)
    dateWithTime.date.setMilliseconds(0)
    return dateWithTime
  }

  DateTime.SECOND = 1000
  DateTime.MINUTE = 60 * DateTime.SECOND
  DateTime.HOUR = 60 * DateTime.MINUTE
  DateTime.DAY = 24 * DateTime.HOUR
  DateTime.WEEK = 7 * DateTime.DAY

  DateTime.now = function() {
    if(typeof DateTime._now == 'undefined') {
      DateTime._now = new DateTime()
    }
    return DateTime._now
  }

  DateTime.getDaysInMonth = function(year, month) {
    if(month > 12 || month < 1)
      throw new Error('Month must be between 1-12')
    var yearAndMonth = year * 12 + month
    return DateTime.fromDate(Math.floor(yearAndMonth / 12), yearAndMonth % 12 + 1, 1).minusDays(1).getDate()
  }

  DateTime.getDayInYear = function(year, month, day) {
    return DateTime.fromDate(year, 1, 1).distanceInDays(DateTime.fromDate(year, month, day)) + 1
  }

  DateTime.prototype.getDaysInMonth = function() { return DateTime.getDaysInMonth(this.getFullYear(), this.getMonth()) }

  DateTime.prototype.getDayInYear = function() { return DateTime.getDayInYear(this.getFullYear(), this.getMonth(), this.getDate()) }

  DateTime.prototype.plusDays = function(days) {
    var newDateTime = this.clone()
    var hours = this.getHours()
    newDateTime.date.setTime(this.getTime() + days * DateTime.DAY)

    // Fix the DateTime offset caused by daylight saving time
    var delta = hours - newDateTime.getHours()
    if(delta != 0) {
      // Correct the delta to be between [-12, 12]
      if(delta > 12) {
        delta -= 24
      }
      if(delta < -12) {
        delta += 24
      }
      newDateTime.date.setTime(newDateTime.getTime() + (delta * DateTime.HOUR))
    }
    return newDateTime
  }

  DateTime.prototype.minusDays = function(days) {
    return this.plusDays(-days)
  }

  DateTime.prototype.compareTo = function(date) {
    if(!date) {
      return 1
    }
    var lhs = this.getTime()
    var rhs = date.getTime()
    if(lhs < rhs) {
      return -1
    } else {
      if(lhs > rhs) {
        return 1
      } else {
        return 0
      }
    }
  }

  DateTime.prototype.isToday = function() { return this.equalsOnlyDate(DateTime.now()) }

  DateTime.prototype.getWeekInYear = function(weekNumberingSystem) {
    if(weekNumberingSystem != 'US' && weekNumberingSystem != 'ISO') {
      throw('Week numbering system must be either US or ISO, was ' + weekNumberingSystem)
    }

    var firstDay = new Date(this.getFullYear(), 0, 1).getDay()
    if(weekNumberingSystem == 'US') {
      return Math.ceil((this.getDayInYear() + firstDay) / 7)
    }
    var THU = 4
    var weekday = this.getDay()
    if(weekday == 0) weekday = 7
    if(firstDay == 0) firstDay = 7
    // If Dec 29 falls on Mon, Dec 30 on Mon or Tue, Dec 31 on Mon - Wed, it's on the first week of next year
    if(this.getMonth() == 12 && this.getDate() >= 29 && (this.getDate() - weekday) > 27) {
      return 1
    }
    // If Jan 1-3 falls on Fri, Sat or Sun, it's on the last week of the previous year
    if(this.getMonth() == 1 && this.getDate() < 4 && weekday > THU) {
      return new DateTime(new Date(this.getFullYear() - 1, 11, 31)).getWeekInYear('ISO')
    }
    var week = Math.ceil((this.getDayInYear() + firstDay - 1) / 7)
    // If first days of this year are on last year's last week, the above gives one week too much
    if(firstDay > THU) week--
    return week
  }

  DateTime.prototype.clone = function() { return new DateTime(this.date) }

  DateTime.prototype.isOddMonth = function() { return this.getMonth() % 2 == 0 }

  DateTime.prototype.equalsOnlyDate = function(date) {
    if(!date) {
      return false
    }
    return this.getMonth() == date.getMonth() && this.getDate() == date.getDate() && this.getFullYear() == date.getFullYear()
  }

  DateTime.prototype.isBetweenDates = function(start, end) {
    if(start.getTime() > end.getTime()) throw Error("start date can't be after end date")
    var onlyDate = this.getOnlyDate()
    return onlyDate.compareTo(start.getOnlyDate()) >= 0 && onlyDate.compareTo(end.getOnlyDate()) <= 0
  }

  DateTime.prototype.firstDateOfMonth = function() { return DateTime.fromDate(this.getFullYear(), this.getMonth(), 1) }

  DateTime.prototype.lastDateOfMonth = function() { return DateTime.fromDate(this.getFullYear(), this.getMonth(), this.getDaysInMonth()) }

  DateTime.prototype.distanceInDays = function(date) {
    var first = parseInt(this.getTime() / DateTime.DAY, 10)
    var last = parseInt(date.getTime() / DateTime.DAY, 10)
    return (last - first)
  }

  DateTime.prototype.withWeekday = function(weekday) { return this.plusDays(weekday - this.getDay()) }

  DateTime.prototype.getOnlyDate = function() { return DateTime.fromDate(this.getFullYear(), this.getMonth(), this.getDate()) }

  DateTime.prototype.isWeekend = function() { return this.getDay() == 6 || this.getDay() == 0 }

  DateTime.prototype.toString = function() { return this.toISOString() }

  DateTime.prototype.getFirstDateOfWeek = function(locale) {
    var firstWeekday = locale ? locale.firstWeekday : DateTime.MONDAY
    if(firstWeekday < this.getDay()) return this.plusDays(firstWeekday - this.getDay())
    else if(firstWeekday > this.getDay()) return this.plusDays(firstWeekday - this.getDay() - 7)
    else return this.clone()
  }

  DateTime.prototype.toISOString = function() {
    return $.map([this.getFullYear(), (this.getMonth()), this.getDate()], withTwoDigitsAtLeast).join('-') + 'T' +
      $.map([this.getHours(), this.getMinutes(), this.getSeconds()], withTwoDigitsAtLeast).join(':')
    function withTwoDigitsAtLeast(value) { return value < 10 ? '0' + value : '' + value}
  }

  DateTime.prototype.getMonth = function() {
    return this.date.getMonth() + 1
  }

  return DateTime
})
<|endoftext|>


<commit_before>let Promise = require('bluebird');
let fs = require('fs');
let path = require('path');
let url = require('url');
let showdown = require('showdown');
let cheerio = require('cheerio');
let pdf = require('html-pdf');
let Handlebars = require('handlebars');
Promise.promisifyAll(fs);

// Main layout template
let layoutPath = path.join(__dirname, 'layout.hbs');

// Syntax highlighting
let highlightJs = path.join(__dirname, '/assets/highlight/highlight.pack.js');

function getCssAsHtml(stylesheets) {
    // Read in all stylesheets and format them into HTML to
    // be placed in the header. We do this because the normal
    // <link...> doesn't work for the headers and footers.
    let styleHtml = '';
    for(var i in stylesheets) {
        let style = fs.readFileSync(stylesheets[i], 'utf8');
        styleHtml += '<style>' + style + '</style>';
    }

    return styleHtml;
}

function getAllStyles(options) {
    let cssStyleSheets = [];

    // GitHub Markdown Style
    if (options.ghStyle) {
        cssStyleSheets.push(path.join(__dirname, '/assets/github-markdown-css.css'));
    }
    // Highlight CSS
    cssStyleSheets.push(path.join(__dirname + '/assets/highlight/styles/github.css'));

    // Some additional defaults such as margins
    if (options.defaultStyle) {
        cssStyleSheets.push(path.join(__dirname, '/assets/default.css'));
    }

    // Optional user given CSS
    if (options.styles) {
        cssStyleSheets.push(options.styles);
    }

    return getCssAsHtml(cssStyleSheets);
}

function parseMarkdownToHtml(markdown) {
    showdown.setFlavor('github');
    let converter = new showdown.Converter({
        prefixHeaderId: false,
        ghCompatibleHeaderId: true
    });

    return converter.makeHtml(markdown);
}

function processSrc(src) {
    if (url.parse(src).protocol) {
        // Has a protocol so should be absolute, jobs done
        return src;
    } else if (path.resolve(src) !== src) {
        // Relative path with no protocol, prepend both
        src = path.resolve(__dirname, src);
        return 'file://' + src;
    } else {
        // Absolute path, just prepend a protocol
        return 'file://' + src;
    }
}

function qualifyImgSources(html) {
    let $ = cheerio.load(html);

    $('img').each(function(i, img) {
        img.attribs.src = processSrc(img.attribs.src);
    });

    return $.html();
}

function convert(options) {
    return new Promise((resolve, reject) => {

        options = options || {};
        if (!options.source) {
            reject(new Error('Source path must be provided'));
        }

        if (!options.destination) {
            reject(new Error('Desintation path must be provided'));
        }

        let template = {};
        let local = {
            highlightJs: highlightJs,
            css: new Handlebars.SafeString(getAllStyles(options))
        };

        fs.readFileAsync(layoutPath, 'utf8').then(function(layout) {
            template = Handlebars.compile(layout);

            // Read the header if one has been provided
            if (options.header) {
                let header = fs.readFileSync(options.header, 'utf8');
                local.header = new Handlebars.SafeString(header);
            }

            return fs.readFileAsync(options.source, 'utf8');
        }).then(function(md) {
            let content = parseMarkdownToHtml(md);

            content = qualifyImgSources(content);

            // Append final html to the template body
            local.body = new Handlebars.SafeString(content);

            // Generate html from layout and templates
            let html = template(local);

            if (options.debug) {
                // Write debug html
                fs.writeFileSync(options.debug, html);
            }

            // Create and write PDF to the desintation file
            pdf.create(html, options.pdf).toFile(options.destination, function(err, res) {
                if (err) console.log(err);

                resolve(res.filename);
            });
        }).catch(function(err) {
            reject(err);
        });
    });
}

module.exports = {
    convert: convert
};<commit_msg>Use process.cwd for image src manipulation rather than __dirname<commit_after>let Promise = require('bluebird');
let fs = require('fs');
let path = require('path');
let url = require('url');
let showdown = require('showdown');
let cheerio = require('cheerio');
let pdf = require('html-pdf');
let Handlebars = require('handlebars');
Promise.promisifyAll(fs);

// Main layout template
let layoutPath = path.join(__dirname, 'layout.hbs');

// Syntax highlighting
let highlightJs = path.join(__dirname, '/assets/highlight/highlight.pack.js');

function getCssAsHtml(stylesheets) {
    // Read in all stylesheets and format them into HTML to
    // be placed in the header. We do this because the normal
    // <link...> doesn't work for the headers and footers.
    let styleHtml = '';
    for(var i in stylesheets) {
        let style = fs.readFileSync(stylesheets[i], 'utf8');
        styleHtml += '<style>' + style + '</style>';
    }

    return styleHtml;
}

function getAllStyles(options) {
    let cssStyleSheets = [];

    // GitHub Markdown Style
    if (options.ghStyle) {
        cssStyleSheets.push(path.join(__dirname, '/assets/github-markdown-css.css'));
    }
    // Highlight CSS
    cssStyleSheets.push(path.join(__dirname + '/assets/highlight/styles/github.css'));

    // Some additional defaults such as margins
    if (options.defaultStyle) {
        cssStyleSheets.push(path.join(__dirname, '/assets/default.css'));
    }

    // Optional user given CSS
    if (options.styles) {
        cssStyleSheets.push(options.styles);
    }

    return getCssAsHtml(cssStyleSheets);
}

function parseMarkdownToHtml(markdown) {
    showdown.setFlavor('github');
    let converter = new showdown.Converter({
        prefixHeaderId: false,
        ghCompatibleHeaderId: true
    });

    return converter.makeHtml(markdown);
}

function processSrc(src) {
    if (url.parse(src).protocol) {
        // Has a protocol so should be absolute, jobs done
        return src;
    } else if (path.resolve(src) !== src) {
        // Relative path with no protocol, prepend both
        src = path.resolve(process.cwd(), src);
        return 'file://' + src;
    } else {
        // Absolute path, just prepend a protocol
        return 'file://' + src;
    }
}

function qualifyImgSources(html) {
    let $ = cheerio.load(html);

    $('img').each(function(i, img) {
        img.attribs.src = processSrc(img.attribs.src);
    });

    return $.html();
}

function convert(options) {
    return new Promise((resolve, reject) => {

        options = options || {};
        if (!options.source) {
            reject(new Error('Source path must be provided'));
        }

        if (!options.destination) {
            reject(new Error('Desintation path must be provided'));
        }

        let template = {};
        let local = {
            highlightJs: highlightJs,
            css: new Handlebars.SafeString(getAllStyles(options))
        };

        fs.readFileAsync(layoutPath, 'utf8').then(function(layout) {
            template = Handlebars.compile(layout);

            // Read the header if one has been provided
            if (options.header) {
                let header = fs.readFileSync(options.header, 'utf8');
                local.header = new Handlebars.SafeString(header);
            }

            return fs.readFileAsync(options.source, 'utf8');
        }).then(function(md) {
            let content = parseMarkdownToHtml(md);

            content = qualifyImgSources(content);

            // Append final html to the template body
            local.body = new Handlebars.SafeString(content);

            // Generate html from layout and templates
            let html = template(local);

            if (options.debug) {
                // Write debug html
                fs.writeFileSync(options.debug, html);
            }

            // Create and write PDF to the desintation file
            pdf.create(html, options.pdf).toFile(options.destination, function(err, res) {
                if (err) console.log(err);

                resolve(res.filename);
            });
        }).catch(function(err) {
            reject(err);
        });
    });
}

module.exports = {
    convert: convert
};<|endoftext|>


<commit_before>var AppRouter = Backbone.Router.extend({

    routes:{
		":mapId/globe":"setUniqueGlobe",
		":mapId/map":"setUniqueMap",
		":mapId/setup":"setNewMap",
		":mapId":"setUniqueMap",
		"removed":"home",
		"":"home",
    },

    initialize:function() {
		var self = this;
		this.vent = _.extend({}, Backbone.Events);
    },

	render:function(state)
	{
 		this.headerView = new HeaderView({vent: this.vent, mapName:_mapName});
        $('#app').append(this.headerView.render().el);

		this.sideBarView = new SideBarView({vent: this.vent, page: 'map'});
        $('#app').append(this.sideBarView.render().el);

		this.chatView = new ChatView({vent: this.vent});
        $('#app').append(this.chatView.render().el);

		this.setupView = new SetupView({vent: this.vent, mapId:_mapId, mapAdminId:_mapAdminId, mapName:_mapName});
		$('#app').append(this.setupView.render().el);

		this.graphView = new GraphView({vent: this.vent});
		$('#app').append(this.graphView.render().el);

		$('body').css("overflow","hidden");

		this.addCommentData();

		this.vent.trigger("setToggleStates", {state:state});

		if(_setupRoute)
			$('#setupModal').modal('show');
	},

	setUniqueMapName: function(name)
	{
		_mapName = name;
	},

	setUniqueMap: function(uniqueMapId)
	{
		this.setFromUniqueMapId({mapId:uniqueMapId, state:'map'});
	},

	setNewMap: function(uniqueMapId)
	{
		_setupRoute = true;
		$('#app').empty();
		this.setFromUniqueMapId({mapId:uniqueMapId, state:'map'});
	},

	setUniqueGlobe: function(uniqueMapId)
	{
		this.setFromUniqueMapId({mapId:uniqueMapId, state:'mapgl'});
	},

	setFromUniqueMapId: function(options)
	{
		var self = this;
		mapIdLength = options.mapId.length;

		if(mapIdLength == 10) // Viewer Route
		{
			$.ajax({
				type: 'GET',
				url: '/api/map/' + options.mapId,
				success: function(data) {
					_admin = false;
					_mapName = data[0].name;
					_mapId = options.mapId;
					if(options.state == 'map')
					{
						self.map();
					}
					else
					{
						self.mapGL();
					}

					if(!self.sideBarView)
						self.render(options.state);

				},
				error: function() {
					console.error('failed to fetch unique map');
				}
			});

		} else if(mapIdLength == 15) // Admin Route
		{
			$.ajax({
				type: 'GET',
				url: '/api/map/admin/' + options.mapId,
				success: function(data) {
					_admin = true;
					_mapName = data[0].name;
					_mapId = data[0].mapid;
					_mapAdminId = data[0].mapadminid;
					console.log(data);
					if(options.state == 'map')
					{
						self.map();
					}
					else
					{
						self.mapGL();
					}

					if(!self.sideBarView)
						self.render(options.state);

				},
				error: function() {
					console.error('failed to fetch unique map');
				}
			});
		}
	},

	home:function () {

		if(_firstLoad)
		{
			_firstLoad = false;
			this.homepageView = new HomepageView();
	        $('#home').append(this.homepageView.render().el);
		} else
		{
			window.location.reload(true);
		}
	},

    map:function () {
		var self = this;

		if(this.mapView)
		{
			this.mapView.remove();
			this.mapView = null;
		}

	    if (!this.mapView)
		{
            this.mapView = new MapOLView({
				vent: self.vent
			});
			$('#app').append(this.mapView.render().el);
			this.mapView.start();
        }

		this.fetchCollections('mapdata');
    },

	mapGL:function () {
		var self = this;

		if(this.mapView)
		{
			this.mapView.remove();
			this.mapView = null;
		}

	    if (!this.mapView)
		{
            this.mapView = new MapGLView({
				vent: self.vent
			});
			$('#app').append(this.mapView.render().el);
			this.mapView.start();
        }

		this.fetchCollections('mapdata');
    },

	fetchCollections: function(type)
	{
		var self = this;
		var collectionObject = ["Hello","World"];
		$.ajax({
			type: 'GET',
			url: '/api/map/' + _mapId,
			success: function(data) {

				if(data[0].collections)
				{
					_mapCollections = data[0].collections;

					for(var i = 0; i < _mapCollections.length; ++i)
					{
						$.ajax({
							type: 'GET',
							url: '/api/pointcollection/' + _mapCollections[i],
							success: function(data) {
								self.addExistingDataSource(data[0].collectionid, type)
							},
							error: function() {
								console.error('failed to fetch distinct collections');
							}
						});
					}
					//Save the distinct collection Id(s) to app scope
					_num_data_sources = _mapCollections.length;
				}
			},
			error: function() {
				console.error('failed to fetch distinct collections');
			}
		});
	},

	addExistingDataSource: function(index,type)
	{
		var self = this;

		$.ajax({
			type: 'GET',
			url: '/api/pointcollection/' + index,
			success: function(data) {

				self.vent.trigger("setStateType", 'loading');

				var mapId = data[0].mapid;
				var maxVal = data[0].maxval;
				var minVal = data[0].minval;
				var name = data[0].name;

				pointCollection[index] = new PointCollection({collectionId:index, mapId:mapId, maxVal:maxVal, minVal:minVal, name:name, newData:false});

				pointCollection[index].fetch({success: function(data) {

					self.vent.trigger("setStateType", 'complete');

					if(_firstLoad == true || type == 'newData' || type == 'dataLibrary')
					{
			 			self.addSideBarDataView({collectionId:index,dataLength:data.length,title:name});
					}

					self.addMapCollection(index, pointCollection[index]);

					self.addGraphCollection(index, pointCollection[index]);

					_loaded_data_sources += 1;
					if(_loaded_data_sources == _num_data_sources)
						_firstLoad = false;

				}});

			},
			error: function() {
				console.error('failed to fetch existing data source');
			}
		});
	},

	addFromDataLibrary: function(collectionId)
	{
		$.ajax({
			type: 'POST',
			url: '/api/bindmapcollection/'+_mapId+'/' + collectionId,
			success: function(data) {
				_num_data_sources+=1;
				app.addExistingDataSource(collectionId, 'dataLibrary')
			},
			error: function() {
				console.error('failed to join map with collection');
			}
		});
	},

	addData:function (options)
	{
		var self = this;
		var uniqid = this.uniqId();
		var uniqueMapId = _mapId;
		var title = options.title
		var data = options.data;
		var colorLow = options.colorLow;
		var colorHigh = options.colorHigh;
		var dataSet = [];
		var maxVal = 0;
		var minVal;

		for(var i = 0; i < data.length; ++i)
		{
			var location = '';
			var lat = '';
			var lng = '';
			var intensity = '';
			var name = '';
			var val = '';
			var date = '';
			var day = '';
			var month = '';
			var year = '';

			$.each(data[i], function(key, val) {

				if(key == 'Location')
				{
					location = val;
				}
				if(key == 'location')
				{
					location = val;
				}
				else if (key == 'lat')
				{
					lat = val;
				}
				else if (key == 'lng')
				{
					lng = val;
				}
				else if (key == 'lon')
				{
					lng = val;
				}
				else if (key == 'intensity' || key == 'value')
				{
					intensity = val;
				}
				else if (key == 'name' || key == 'title')
				{
					name = val;
				}
				else if (key == 'color')
				{
					color = val;
				}
				else if (key == 'date')
				{
					date = val;
				}
				else if (key == 'day')
				{
					day = val;
				}
				else if (key == 'month')
				{
					month = val;
				}
				else if (key == 'year')
				{
					year = val;
				}

			});

			//Format date
			if(date == '')
			{
				if(day != '' && month != '' & year != '')
				{
					var d = Date.UTC(year,month,day);
					date =  d;
				}
			}

			//Check for lat/lng location
			if(location == '')
				location = lat + ',' + lng;

			if(lat == '' && lng == '')
			{
				var latlngStr = location.split(/[, ]/, 2);
				lat = parseFloat(latlngStr[0]);
				lng = parseFloat(latlngStr[1]);
			}

			//Substitute intensity for val
			if(val == '')
				val = intensity;

			if(val >= maxVal)
				maxVal = val;

			if(minVal == undefined)
				minVal = val;

			if(val <= minVal)
				minVal = val;

			//Substitute intensity for val
			if(val == '')
				val = 10;

			dataSet.push({'name':name,'location':location,'lat':lat,'lon':lng,'val':val, 'date':date, 'colorlow':colorLow, 'colorhigh':colorHigh});
		}

		//First increment total number of data sources
		_num_data_sources +=1;

		if(maxVal == '')
			maxVal = 1;

		if(minVal == '')
			minVal = 0;

		//Create collection
		pointCollection[_num_data_sources] = new PointCollection({
			collectionId:uniqid,
			mapId:uniqueMapId,
			title:title,
			maxVal: maxVal,
			minVal: minVal,
			newData:true,
		});

		//Create Points
		pointCollection[_num_data_sources].addData(dataSet, function(){
			app.addExistingDataSource(uniqid, 'newData');
		});

		$('#addDataModal').modal('hide');
		this.vent.trigger("setStateType", 'post');
	},

	addCommentData: function(options)
	{
		this.commentCollection = new CommentCollection({});
		this.mapView.addCommentCollection(this.commentCollection);
	},

	addTwitterData: function (options)
	{
		console.log('adding tweets');
	},

	addSideBarDataView:function (options) {
		this.sideBarDataView = new SideBarDataView({vent: this.vent,collection:pointCollection[options.collectionId], collectionId: options.collectionId, title:options.title, dataLength:options.dataLength});
		$('#accordion').append(this.sideBarDataView.render().el);
	},

	addMapCollection: function(id, collection)
	{
		this.mapView.addCollection(id, collection);
	},

	addGraphCollection: function(id, collection)
	{
		this.graphView.addCollection(id, collection);
	},

	uniqId: function ()
	{
	    var newDate = new Date;
	    return newDate.getTime();
	},

});

tpl.loadTemplates(['homepage', 'graph', 'setup', 'map', 'map-gl', 'header','sidebar','sidebar-data', 'chat', 'modal', 'add-data', 'edit-data', 'data-library'],
    function () {
        app = new AppRouter();
        Backbone.history.start({ pushState: true });
});<commit_msg>Abstracting collection/map binding from add data and data library into contained method<commit_after>var AppRouter = Backbone.Router.extend({

    routes:{
		":mapId/globe":"setUniqueGlobe",
		":mapId/map":"setUniqueMap",
		":mapId/setup":"setNewMap",
		":mapId":"setUniqueMap",
		"removed":"home",
		"":"home",
    },

    initialize:function() {
		var self = this;
		this.vent = _.extend({}, Backbone.Events);
    },

	render:function(state)
	{
 		this.headerView = new HeaderView({vent: this.vent, mapName:_mapName});
        $('#app').append(this.headerView.render().el);

		this.sideBarView = new SideBarView({vent: this.vent, page: 'map'});
        $('#app').append(this.sideBarView.render().el);

		this.chatView = new ChatView({vent: this.vent});
        $('#app').append(this.chatView.render().el);

		this.setupView = new SetupView({vent: this.vent, mapId:_mapId, mapAdminId:_mapAdminId, mapName:_mapName});
		$('#app').append(this.setupView.render().el);

		this.graphView = new GraphView({vent: this.vent});
		$('#app').append(this.graphView.render().el);

		$('body').css("overflow","hidden");

		this.addCommentData();

		this.vent.trigger("setToggleStates", {state:state});

		if(_setupRoute)
			$('#setupModal').modal('show');
	},

	setUniqueMapName: function(name)
	{
		_mapName = name;
	},

	setUniqueMap: function(uniqueMapId)
	{
		this.setFromUniqueMapId({mapId:uniqueMapId, state:'map'});
	},

	setNewMap: function(uniqueMapId)
	{
		_setupRoute = true;
		$('#app').empty();
		this.setFromUniqueMapId({mapId:uniqueMapId, state:'map'});
	},

	setUniqueGlobe: function(uniqueMapId)
	{
		this.setFromUniqueMapId({mapId:uniqueMapId, state:'mapgl'});
	},

	setFromUniqueMapId: function(options)
	{
		var self = this;
		mapIdLength = options.mapId.length;

		if(mapIdLength == 10) // Viewer Route
		{
			$.ajax({
				type: 'GET',
				url: '/api/map/' + options.mapId,
				success: function(data) {
					_admin = false;
					_mapName = data[0].name;
					_mapId = options.mapId;
					if(options.state == 'map')
					{
						self.map();
					}
					else
					{
						self.mapGL();
					}

					if(!self.sideBarView)
						self.render(options.state);

				},
				error: function() {
					console.error('failed to fetch unique map');
				}
			});

		} else if(mapIdLength == 15) // Admin Route
		{
			$.ajax({
				type: 'GET',
				url: '/api/map/admin/' + options.mapId,
				success: function(data) {
					_admin = true;
					_mapName = data[0].name;
					_mapId = data[0].mapid;
					_mapAdminId = data[0].mapadminid;
					console.log(data);
					if(options.state == 'map')
					{
						self.map();
					}
					else
					{
						self.mapGL();
					}

					if(!self.sideBarView)
						self.render(options.state);

				},
				error: function() {
					console.error('failed to fetch unique map');
				}
			});
		}
	},

	home:function () {

		if(_firstLoad)
		{
			_firstLoad = false;
			this.homepageView = new HomepageView();
	        $('#home').append(this.homepageView.render().el);
		} else
		{
			window.location.reload(true);
		}
	},

    map:function () {
		var self = this;

		if(this.mapView)
		{
			this.mapView.remove();
			this.mapView = null;
		}

	    if (!this.mapView)
		{
            this.mapView = new MapOLView({
				vent: self.vent
			});
			$('#app').append(this.mapView.render().el);
			this.mapView.start();
        }

		this.fetchCollections('mapdata');
    },

	mapGL:function () {
		var self = this;

		if(this.mapView)
		{
			this.mapView.remove();
			this.mapView = null;
		}

	    if (!this.mapView)
		{
            this.mapView = new MapGLView({
				vent: self.vent
			});
			$('#app').append(this.mapView.render().el);
			this.mapView.start();
        }

		this.fetchCollections('mapdata');
    },

	fetchCollections: function(type)
	{
		var self = this;
		var collectionObject = ["Hello","World"];
		$.ajax({
			type: 'GET',
			url: '/api/map/' + _mapId,
			success: function(data) {

				if(data[0].collections)
				{
					_mapCollections = data[0].collections;

					for(var i = 0; i < _mapCollections.length; ++i)
					{
						$.ajax({
							type: 'GET',
							url: '/api/pointcollection/' + _mapCollections[i],
							success: function(data) {
								self.addExistingDataSource(data[0].collectionid, type)
							},
							error: function() {
								console.error('failed to fetch distinct collections');
							}
						});
					}
					//Save the distinct collection Id(s) to app scope
					_num_data_sources = _mapCollections.length;
				}
			},
			error: function() {
				console.error('failed to fetch distinct collections');
			}
		});
	},

	addExistingDataSource: function(index,type)
	{
		var self = this;

		$.ajax({
			type: 'GET',
			url: '/api/pointcollection/' + index,
			success: function(data) {

				self.vent.trigger("setStateType", 'loading');

				var mapId = data[0].mapid;
				var maxVal = data[0].maxval;
				var minVal = data[0].minval;
				var name = data[0].name;

				pointCollection[index] = new PointCollection({collectionId:index, mapId:mapId, maxVal:maxVal, minVal:minVal, name:name, newData:false});

				pointCollection[index].fetch({success: function(data) {

					self.vent.trigger("setStateType", 'complete');

					if(_firstLoad == true || type == 'newData' || type == 'dataLibrary')
					{
			 			self.addSideBarDataView({collectionId:index,dataLength:data.length,title:name});
					}

					self.addMapCollection(index, pointCollection[index]);

					self.addGraphCollection(index, pointCollection[index]);

					_loaded_data_sources += 1;
					if(_loaded_data_sources == _num_data_sources)
						_firstLoad = false;

				}});

			},
			error: function() {
				console.error('failed to fetch existing data source');
			}
		});
	},

	addFromDataLibrary: function(collectionId)
	{
		this.bindCollectionToMap(collectionId);
		_num_data_sources+=1;
		app.addExistingDataSource(collectionId, 'dataLibrary')

	},

	bindCollectionToMap: function(collectionId)
	{
		$.ajax({
			type: 'POST',
			url: '/api/bindmapcollection/'+_mapId+'/' + collectionId,
			success: function(data) {
			},
			error: function() {
				console.error('failed to join map with collection');
			}
		});
	},

	addData:function (options)
	{
		var self = this;
		var uniqid = this.uniqId();
		var uniqueMapId = _mapId;
		var title = options.title
		var data = options.data;
		var colorLow = options.colorLow;
		var colorHigh = options.colorHigh;
		var dataSet = [];
		var maxVal = 0;
		var minVal;

		for(var i = 0; i < data.length; ++i)
		{
			var location = '';
			var lat = '';
			var lng = '';
			var intensity = '';
			var name = '';
			var val = '';
			var date = '';
			var day = '';
			var month = '';
			var year = '';

			$.each(data[i], function(key, val) {

				if(key == 'Location')
				{
					location = val;
				}
				if(key == 'location')
				{
					location = val;
				}
				else if (key == 'lat')
				{
					lat = val;
				}
				else if (key == 'lng')
				{
					lng = val;
				}
				else if (key == 'lon')
				{
					lng = val;
				}
				else if (key == 'intensity' || key == 'value')
				{
					intensity = val;
				}
				else if (key == 'name' || key == 'title')
				{
					name = val;
				}
				else if (key == 'color')
				{
					color = val;
				}
				else if (key == 'date')
				{
					date = val;
				}
				else if (key == 'day')
				{
					day = val;
				}
				else if (key == 'month')
				{
					month = val;
				}
				else if (key == 'year')
				{
					year = val;
				}

			});

			//Format date
			if(date == '')
			{
				if(day != '' && month != '' & year != '')
				{
					var d = Date.UTC(year,month,day);
					date =  d;
				}
			}

			//Check for lat/lng location
			if(location == '')
				location = lat + ',' + lng;

			if(lat == '' && lng == '')
			{
				var latlngStr = location.split(/[, ]/, 2);
				lat = parseFloat(latlngStr[0]);
				lng = parseFloat(latlngStr[1]);
			}

			//Substitute intensity for val
			if(val == '')
				val = intensity;

			if(val >= maxVal)
				maxVal = val;

			if(minVal == undefined)
				minVal = val;

			if(val <= minVal)
				minVal = val;

			//Substitute intensity for val
			if(val == '')
				val = 10;

			dataSet.push({'name':name,'location':location,'lat':lat,'lon':lng,'val':val, 'date':date, 'colorlow':colorLow, 'colorhigh':colorHigh});
		}

		//First increment total number of data sources
		_num_data_sources +=1;

		if(maxVal == '')
			maxVal = 1;

		if(minVal == '')
			minVal = 0;

		//Create collection
		pointCollection[_num_data_sources] = new PointCollection({
			collectionId:uniqid,
			mapId:uniqueMapId,
			title:title,
			maxVal: maxVal,
			minVal: minVal,
			newData:true,
		});

		//Create Points
		pointCollection[_num_data_sources].addData(dataSet, function(){
			app.addExistingDataSource(uniqid, 'newData');
		});

		this.bindCollectionToMap(uniqid);

		$('#addDataModal').modal('hide');
		this.vent.trigger("setStateType", 'post');
	},

	addCommentData: function(options)
	{
		this.commentCollection = new CommentCollection({});
		this.mapView.addCommentCollection(this.commentCollection);
	},

	addTwitterData: function (options)
	{
		console.log('adding tweets');
	},

	addSideBarDataView:function (options) {
		this.sideBarDataView = new SideBarDataView({vent: this.vent,collection:pointCollection[options.collectionId], collectionId: options.collectionId, title:options.title, dataLength:options.dataLength});
		$('#accordion').append(this.sideBarDataView.render().el);
	},

	addMapCollection: function(id, collection)
	{
		this.mapView.addCollection(id, collection);
	},

	addGraphCollection: function(id, collection)
	{
		this.graphView.addCollection(id, collection);
	},

	uniqId: function ()
	{
	    var newDate = new Date;
	    return newDate.getTime();
	},

});

tpl.loadTemplates(['homepage', 'graph', 'setup', 'map', 'map-gl', 'header','sidebar','sidebar-data', 'chat', 'modal', 'add-data', 'edit-data', 'data-library'],
    function () {
        app = new AppRouter();
        Backbone.history.start({ pushState: true });
});<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 * Copyright (c) 2015-2016 NetIQ Corporation, a Micro Focus company
 *
 ******************************************************************************/
 'use strict';

/*
 * The requests array holds onto requests which are pending while the login
 * process completes.
 */
gromit.reqs = [];

/*
 * The token and the token type are populated once the login process is complete
 */
gromit.token = null;
gromit.tokenType = null;

/**
 * @private
 *
 * This function prepares a request by adding it to the request queue or making
 * the request directly.
 */
gromit.doRequest = function(/*Object*/ req) {
    if (gromit.reqs.length > 0) {
        /*
         * This means we are already in the process of logging in.  We don't want to
         * fire off this request just to start the login process all over again.  We
         * just want to hold onto this request until we can replay it.
         */
        gromit.reqs.push(req);
    } else {
        gromit.request(req);
    }
};

/**
 * @private
 *
 * This function does the actual request to the server based on the request object
 * with configured parameters.
 */
gromit.request = function(/*Object*/ req) {
    if (gromit.token) {
        req.headers.Authorization = gromit.tokenType + ' ' + gromit.token;
    }

    if (!req.errorCallback) {
        /*
         * If there's no error callback then we want to handle errors in the generic way
         */
        req.errorCallback = function(code, subcode, reason) {
            gromit.println('errorCallback(' + code + ', ' + subcode + ', ' + reason + ')');
            if (subcode === 'NotFound') {
                gromit.showFatalError(gromit.i18n.getI18n_general_error_notfound(req.url));
            } else {
                gromit.showGeneralError(code, subcode, reason);
            }
        };
    }

    if (!_.isFunction(req.http)) {
        throw 'The http object in the request was not a function.  This normally happens when you haven\'t ' +
        'declared $http in the definition of your controller.';
    }

    var validateTime = function() {
        if (!$.cookie('ar-time')) {
            /*
             * This means we aren't supporting cookies and this check won't work
             */
            return true;
        }

        /*
         * There are some very strange bugs, especially on IE, when the client time gets very far off
         * from the server time.  It can also cause issues with SSL certificates.  This code checks to
         * see if the server time and the client time are more than one week different.  If they are
         * then we will show an error and the user won't be able to access the application.
         */
        var serverTime = parseInt($.cookie('ar-time'), 10);
        var clientTime = new Date().getTime();

        if (Math.abs(clientTime - serverTime) < 604800000) {
            return true;
        }

        setTimeout(function() {
            $('div.pageloading').hide();
            $('div.invalidTime').show();

            if (clientTime > serverTime) {
                $('div.invalidTime').children('h1').text(gromit.i18n.invalid_client_time_ahead);
            } else {
                $('div.invalidTime').children('h1').text(gromit.i18n.invalid_client_time_behind);
            }

            $('div.invalidTime').children('p').text(gromit.i18n.getI18n_invalid_client_time_error(gromit.fullDateTimeFormat(clientTime)));
        }, 3000);

        return false;

    };

    var handle401 = function(req) {
        if (!validateTime()) {
            gromit.println('the time was not valid');
            return;
        }

        /*
         * This means they haven't logged in yet and we need to add this request to the
         * request stack and prompt them to log in
         */
        gromit.token = null;
        gromit.tokenType = null;
        gromit.reqs.push(req);
        if (gromit.reqs.length === 1) {
            gromit.doLogin(req);
        }
    };

    var responsePromise = req.http(req);

    responsePromise.then(function(response) {
        /*
         * This is the success callback
         */
        if (req.successCallback) {
            req.successCallback(response.data, response.status, response.headers, response.config);
        }
    }, function(response) {
        /*
         * This is the error callback
         */
        if (response.status === 0) {
            /*
             * This means we weren't able to contact the server at all
             */
            gromit.showFatalError('Unable to contact server at ' + req.url);
        } else if (response.data && response.data.Fault) {
            /*
             * This means the server returned a RESTException
             */
            if (response.status === 401 &&
                (response.data.Fault.Code.Subcode.Value === 'NoCredentials' ||
                    response.data.Fault.Code.Subcode.Value === 'Expired')) {
                handle401(req);
            } else if (req.errorCallback) {
                /*
                 * This means it was just a normal RESTException and we want to pass it back
                 * to the calling code.
                 */
                req.errorCallback(response.data.Fault.Code.Value, response.data.Fault.Code.Subcode.Value, response.data.Fault.Reason.Text);
            }
        } else {
            /*
             * This means we got a response from the server which didn't have JSON data
             */
            if (response.status === 404) {
                /*
                 * If the item wasn't found then we want to send that to the calling code
                 */
                req.errorCallback('Sender', 'NotFound', '');
            } else if (response.status === 401) {
                handle401(req);
            } else if (req.unknownErrorCallback) {
                /*
                 * This means they gave us a special handler for generic exceptions
                 */
                req.unknownErrorCallback(response.data, response.status, response.headers);
            } else {
                if (response.data) {
                    gromit.showFatalError(gromit.i18n.getI18n_fatal_request_error(req.url, response.status, response.data));
                } else {
                    gromit.showFatalError(gromit.i18n.getI18n_fatal_request_error(req.url, response.status, ''));
                }
                if (window.console) {
                    console.error(gromit.showFatalError(gromit.i18n.getI18n_fatal_request_error(req.url, response.status, response.data)));
                }
            }
        }
    });

    return responsePromise;
};

/**
 * Get the current authentication token
 */
gromit.getAuthToken = function() {
    return gromit.tokenType + ' ' + gromit.token;
};

/**
 * @private
 */
gromit.requestPromise = function(/*Object*/ req) {
    return gromit.request(req);
};

/**
 * @private
 *
 * This function kicks off the actual login process which shows the iFrame and
 * redirects to the OAuth page.
 */
gromit.doLogin = function(/*Object*/ req) {
    if (gromit.isEmpty(gromit.AuthUrl)) {
        throw 'Unable to log in without gromit.AuthUrl';
    }

    gromit.oAuthAuthenticate(gromit.AuthUrl, function(/*String*/ token, /*String*/ type) {
        gromit.token = token;
        $.cookie('gromitTokenCookie', token, { path: '/' });

        gromit.tokenType = type;
        $.cookie('gromitTokenTypeCookie', type, { path: '/' });

        /*
         * Now we want to replay all of the existing requests which have come in while
         * we're trying to log in.
         */
        var reqs = gromit.reqs.slice(0);
        gromit.reqs = [];

        while (reqs.length > 0) {
            gromit.request(reqs.pop());
        }
    }, req.isBackground);
};

/**
 * Logout by going to the logout url and removing cookies that were set in doLogin
 */
gromit.doLogout = function() {
    var redirectTo = window.location.protocol + '//' + window.location.host + window.location.pathname;
    $.cookie('gromitTokenCookie', null, { path: '/' });
    $.cookie('gromitTokenTypeCookie', null, { path: '/' });

    if (gromit.isEmpty(gromit.AuthLogoutUrl)) {
        throw 'Unable to log out without gromit.AuthLogoutUrl';
    }

    window.location.assign(gromit.AuthLogoutUrl + '?target=' + redirectTo);
};

/**
 * This method is a little tricky.  It needs to get the current URL of the application
 * so we can build the right location to the oauth.html file for OAuth redirection.  To
 * do that we combine the current protocol, host, and path with the relative URL for the
 * nocache.js file so we can get the right location of where GWT will put the oauth.html
 * file instead of where the GWT application front page is loaded from.
 */
gromit.getCurrentUrl = function() {
    var url = window.location.protocol + '//' + window.location.host + window.location.pathname;

    if (window.location.pathname.length > 0 && url.substring(url.length - 1) !== '/') {
        /*
         * Then the URL ends with something like index.html.
         */
        url = url.substring(0, url.lastIndexOf('/') + 1);
    }

    if (url.substring(url.length - 1) !== '/') {
        url += '/';
    }

    return url;
};

/**
 * @private
 *
 * This function does the actual redirection and creation of the iFrame for the OAuth
 * login function.  It also creates the URL and manages the parameters that we need to
 * pass to the OAuth server.
 */
gromit.oAuthAuthenticate = function(/*String*/ url, /*function*/ callback, /*boolean*/ isBackground) {
    window.addEventListener('message', gromit.oAuthAuthenticateCompleteEventListener, false);

    gromit.oauthCallback = callback;

    if (gromit.isEmpty(gromit.ClientId)) {
        throw 'Unable to log in without client ID';
    }

    url += '?response_type=token';
    url += '&redirect_uri=' + gromit.getCurrentUrl() + 'oauth.html';
    url += '&client_id=' + gromit.ClientId;

    if (typeof gromit.AuthParams !== 'undefined') {
        for (var i = 0; i < gromit.AuthParams.length; i++) {
            url += '&' + gromit.AuthParams[i].name;
            if (gromit.AuthParams[i].value !== 'null') {
                url += '=' + gromit.AuthParams[i].value;
            }
        }
    }

    if (isBackground) {
        url += '&bgr=true';
    }

    gromit.oauthstate = 'gromitstate' + Math.random();
    url += '&state=' + gromit.oauthstate;

    var frame = $('<iframe id="gromitoauthframe" seamless="true" src="' + url + '"></iframe>');
    frame.css({
        'position': 'fixed',
        'left': '0px',
        'top': '0px',
        'z-index': '99999',
        'width': '100%',
        'height': '100%'
    });

    if (navigator.userAgent.match(/iPhone/i)) {
        /*
         * We show the OAuth login dialog with an iFrame and we use
         * fixed positioning so the frame stays over the main screen.
         * This works well almost everywhere, but iPhone doesn't allow
         * you to scroll fixed position items so we use absolute
         * positioning on iPhone.
         */
        frame.css('position', 'absolute');
    }

    $('body').append(frame);
};

/**
 * @private
 *
 * This function is the callback which gets called when the OAuth login has completed and
 * the OAuth server redirects back to our page.  In this case the iFrame will show the oauth.html
 * file and that will call back to the parent frame running this function.  When this function
 * completes it calls to the oAuthAuthenticateComplete function.
 */
gromit.oAuthAuthenticateCompleteEventListener = function(event) {
    window.removeEventListener('message', gromit.oAuthAuthenticateCompleteEventListener, false);
    gromit.oAuthAuthenticateComplete(event.data);
};

/**
 * @private
 *
 * This function handles completion of the OAuth authentication process.  It takes the response
 * from the OAuth server, parses that response, and makes all of the values available for future requests.
 */
gromit.oAuthAuthenticateComplete = function(/*String*/ response) {
    var callback = gromit.oauthCallback;
    gromit.oauthCallback = null;

    $('#gromitoauthframe').remove();

    // First, parse the query string
    var params = {};
    var queryString = response.substring(1);
    var regex = /([^&=]+)=([^&]*)/g;
    var m = regex.exec(queryString);
    while (m) {
        params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
        m = regex.exec(queryString);
    }

    if (gromit.oauthstate !== params.state) {
        gromit.oauthstate = null;
        throw ('The client side state (' + gromit.oauthstate + ') did not match the server-side state (' + params.state + ')');
    } else {
        gromit.oauthstate = null;
        gromit.fireLoginEvent();
        callback(params.access_token, params.token_type);
    }
};

/**
 * @private
 *
 * This function gets the root scope and fires the event to indicate that the login has completed.
 * We need this event so the UI can update if the user is prompted to log in when their session
 * expires and they log in as a different user.
 *
 * Accessing the root scope outside of the Angular application is generally a really bad thing to
 * do, but there's no better way to access it from here since this can't be a service since it
 * gets called back from the iFrame.
 *
 */
gromit.fireLoginEvent = function() {
    var $body = angular.element(document.body);
    var $rootScope = $body.scope().$root;
    $rootScope.$apply(function () {
        $rootScope.$broadcast('loginCompleted');
    });
};<commit_msg>Incorporate Zack's suggestion for testing gromit.authParams.<commit_after>/*******************************************************************************
 *
 * MIT License
 * Copyright (c) 2015-2016 NetIQ Corporation, a Micro Focus company
 *
 ******************************************************************************/
 'use strict';

/*
 * The requests array holds onto requests which are pending while the login
 * process completes.
 */
gromit.reqs = [];

/*
 * The token and the token type are populated once the login process is complete
 */
gromit.token = null;
gromit.tokenType = null;

/**
 * @private
 *
 * This function prepares a request by adding it to the request queue or making
 * the request directly.
 */
gromit.doRequest = function(/*Object*/ req) {
    if (gromit.reqs.length > 0) {
        /*
         * This means we are already in the process of logging in.  We don't want to
         * fire off this request just to start the login process all over again.  We
         * just want to hold onto this request until we can replay it.
         */
        gromit.reqs.push(req);
    } else {
        gromit.request(req);
    }
};

/**
 * @private
 *
 * This function does the actual request to the server based on the request object
 * with configured parameters.
 */
gromit.request = function(/*Object*/ req) {
    if (gromit.token) {
        req.headers.Authorization = gromit.tokenType + ' ' + gromit.token;
    }

    if (!req.errorCallback) {
        /*
         * If there's no error callback then we want to handle errors in the generic way
         */
        req.errorCallback = function(code, subcode, reason) {
            gromit.println('errorCallback(' + code + ', ' + subcode + ', ' + reason + ')');
            if (subcode === 'NotFound') {
                gromit.showFatalError(gromit.i18n.getI18n_general_error_notfound(req.url));
            } else {
                gromit.showGeneralError(code, subcode, reason);
            }
        };
    }

    if (!_.isFunction(req.http)) {
        throw 'The http object in the request was not a function.  This normally happens when you haven\'t ' +
        'declared $http in the definition of your controller.';
    }

    var validateTime = function() {
        if (!$.cookie('ar-time')) {
            /*
             * This means we aren't supporting cookies and this check won't work
             */
            return true;
        }

        /*
         * There are some very strange bugs, especially on IE, when the client time gets very far off
         * from the server time.  It can also cause issues with SSL certificates.  This code checks to
         * see if the server time and the client time are more than one week different.  If they are
         * then we will show an error and the user won't be able to access the application.
         */
        var serverTime = parseInt($.cookie('ar-time'), 10);
        var clientTime = new Date().getTime();

        if (Math.abs(clientTime - serverTime) < 604800000) {
            return true;
        }

        setTimeout(function() {
            $('div.pageloading').hide();
            $('div.invalidTime').show();

            if (clientTime > serverTime) {
                $('div.invalidTime').children('h1').text(gromit.i18n.invalid_client_time_ahead);
            } else {
                $('div.invalidTime').children('h1').text(gromit.i18n.invalid_client_time_behind);
            }

            $('div.invalidTime').children('p').text(gromit.i18n.getI18n_invalid_client_time_error(gromit.fullDateTimeFormat(clientTime)));
        }, 3000);

        return false;

    };

    var handle401 = function(req) {
        if (!validateTime()) {
            gromit.println('the time was not valid');
            return;
        }

        /*
         * This means they haven't logged in yet and we need to add this request to the
         * request stack and prompt them to log in
         */
        gromit.token = null;
        gromit.tokenType = null;
        gromit.reqs.push(req);
        if (gromit.reqs.length === 1) {
            gromit.doLogin(req);
        }
    };

    var responsePromise = req.http(req);

    responsePromise.then(function(response) {
        /*
         * This is the success callback
         */
        if (req.successCallback) {
            req.successCallback(response.data, response.status, response.headers, response.config);
        }
    }, function(response) {
        /*
         * This is the error callback
         */
        if (response.status === 0) {
            /*
             * This means we weren't able to contact the server at all
             */
            gromit.showFatalError('Unable to contact server at ' + req.url);
        } else if (response.data && response.data.Fault) {
            /*
             * This means the server returned a RESTException
             */
            if (response.status === 401 &&
                (response.data.Fault.Code.Subcode.Value === 'NoCredentials' ||
                    response.data.Fault.Code.Subcode.Value === 'Expired')) {
                handle401(req);
            } else if (req.errorCallback) {
                /*
                 * This means it was just a normal RESTException and we want to pass it back
                 * to the calling code.
                 */
                req.errorCallback(response.data.Fault.Code.Value, response.data.Fault.Code.Subcode.Value, response.data.Fault.Reason.Text);
            }
        } else {
            /*
             * This means we got a response from the server which didn't have JSON data
             */
            if (response.status === 404) {
                /*
                 * If the item wasn't found then we want to send that to the calling code
                 */
                req.errorCallback('Sender', 'NotFound', '');
            } else if (response.status === 401) {
                handle401(req);
            } else if (req.unknownErrorCallback) {
                /*
                 * This means they gave us a special handler for generic exceptions
                 */
                req.unknownErrorCallback(response.data, response.status, response.headers);
            } else {
                if (response.data) {
                    gromit.showFatalError(gromit.i18n.getI18n_fatal_request_error(req.url, response.status, response.data));
                } else {
                    gromit.showFatalError(gromit.i18n.getI18n_fatal_request_error(req.url, response.status, ''));
                }
                if (window.console) {
                    console.error(gromit.showFatalError(gromit.i18n.getI18n_fatal_request_error(req.url, response.status, response.data)));
                }
            }
        }
    });

    return responsePromise;
};

/**
 * Get the current authentication token
 */
gromit.getAuthToken = function() {
    return gromit.tokenType + ' ' + gromit.token;
};

/**
 * @private
 */
gromit.requestPromise = function(/*Object*/ req) {
    return gromit.request(req);
};

/**
 * @private
 *
 * This function kicks off the actual login process which shows the iFrame and
 * redirects to the OAuth page.
 */
gromit.doLogin = function(/*Object*/ req) {
    if (gromit.isEmpty(gromit.AuthUrl)) {
        throw 'Unable to log in without gromit.AuthUrl';
    }

    gromit.oAuthAuthenticate(gromit.AuthUrl, function(/*String*/ token, /*String*/ type) {
        gromit.token = token;
        $.cookie('gromitTokenCookie', token, { path: '/' });

        gromit.tokenType = type;
        $.cookie('gromitTokenTypeCookie', type, { path: '/' });

        /*
         * Now we want to replay all of the existing requests which have come in while
         * we're trying to log in.
         */
        var reqs = gromit.reqs.slice(0);
        gromit.reqs = [];

        while (reqs.length > 0) {
            gromit.request(reqs.pop());
        }
    }, req.isBackground);
};

/**
 * Logout by going to the logout url and removing cookies that were set in doLogin
 */
gromit.doLogout = function() {
    var redirectTo = window.location.protocol + '//' + window.location.host + window.location.pathname;
    $.cookie('gromitTokenCookie', null, { path: '/' });
    $.cookie('gromitTokenTypeCookie', null, { path: '/' });

    if (gromit.isEmpty(gromit.AuthLogoutUrl)) {
        throw 'Unable to log out without gromit.AuthLogoutUrl';
    }

    window.location.assign(gromit.AuthLogoutUrl + '?target=' + redirectTo);
};

/**
 * This method is a little tricky.  It needs to get the current URL of the application
 * so we can build the right location to the oauth.html file for OAuth redirection.  To
 * do that we combine the current protocol, host, and path with the relative URL for the
 * nocache.js file so we can get the right location of where GWT will put the oauth.html
 * file instead of where the GWT application front page is loaded from.
 */
gromit.getCurrentUrl = function() {
    var url = window.location.protocol + '//' + window.location.host + window.location.pathname;

    if (window.location.pathname.length > 0 && url.substring(url.length - 1) !== '/') {
        /*
         * Then the URL ends with something like index.html.
         */
        url = url.substring(0, url.lastIndexOf('/') + 1);
    }

    if (url.substring(url.length - 1) !== '/') {
        url += '/';
    }

    return url;
};

/**
 * @private
 *
 * This function does the actual redirection and creation of the iFrame for the OAuth
 * login function.  It also creates the URL and manages the parameters that we need to
 * pass to the OAuth server.
 */
gromit.oAuthAuthenticate = function(/*String*/ url, /*function*/ callback, /*boolean*/ isBackground) {
    window.addEventListener('message', gromit.oAuthAuthenticateCompleteEventListener, false);

    gromit.oauthCallback = callback;

    if (gromit.isEmpty(gromit.ClientId)) {
        throw 'Unable to log in without client ID';
    }

    url += '?response_type=token';
    url += '&redirect_uri=' + gromit.getCurrentUrl() + 'oauth.html';
    url += '&client_id=' + gromit.ClientId;

    if (gromit.AuthParams) {
        for (var i = 0; i < gromit.AuthParams.length; i++) {
            url += '&' + gromit.AuthParams[i].name;
            if (gromit.AuthParams[i].value !== 'null') {
                url += '=' + gromit.AuthParams[i].value;
            }
        }
    }

    if (isBackground) {
        url += '&bgr=true';
    }

    gromit.oauthstate = 'gromitstate' + Math.random();
    url += '&state=' + gromit.oauthstate;

    var frame = $('<iframe id="gromitoauthframe" seamless="true" src="' + url + '"></iframe>');
    frame.css({
        'position': 'fixed',
        'left': '0px',
        'top': '0px',
        'z-index': '99999',
        'width': '100%',
        'height': '100%'
    });

    if (navigator.userAgent.match(/iPhone/i)) {
        /*
         * We show the OAuth login dialog with an iFrame and we use
         * fixed positioning so the frame stays over the main screen.
         * This works well almost everywhere, but iPhone doesn't allow
         * you to scroll fixed position items so we use absolute
         * positioning on iPhone.
         */
        frame.css('position', 'absolute');
    }

    $('body').append(frame);
};

/**
 * @private
 *
 * This function is the callback which gets called when the OAuth login has completed and
 * the OAuth server redirects back to our page.  In this case the iFrame will show the oauth.html
 * file and that will call back to the parent frame running this function.  When this function
 * completes it calls to the oAuthAuthenticateComplete function.
 */
gromit.oAuthAuthenticateCompleteEventListener = function(event) {
    window.removeEventListener('message', gromit.oAuthAuthenticateCompleteEventListener, false);
    gromit.oAuthAuthenticateComplete(event.data);
};

/**
 * @private
 *
 * This function handles completion of the OAuth authentication process.  It takes the response
 * from the OAuth server, parses that response, and makes all of the values available for future requests.
 */
gromit.oAuthAuthenticateComplete = function(/*String*/ response) {
    var callback = gromit.oauthCallback;
    gromit.oauthCallback = null;

    $('#gromitoauthframe').remove();

    // First, parse the query string
    var params = {};
    var queryString = response.substring(1);
    var regex = /([^&=]+)=([^&]*)/g;
    var m = regex.exec(queryString);
    while (m) {
        params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
        m = regex.exec(queryString);
    }

    if (gromit.oauthstate !== params.state) {
        gromit.oauthstate = null;
        throw ('The client side state (' + gromit.oauthstate + ') did not match the server-side state (' + params.state + ')');
    } else {
        gromit.oauthstate = null;
        gromit.fireLoginEvent();
        callback(params.access_token, params.token_type);
    }
};

/**
 * @private
 *
 * This function gets the root scope and fires the event to indicate that the login has completed.
 * We need this event so the UI can update if the user is prompted to log in when their session
 * expires and they log in as a different user.
 *
 * Accessing the root scope outside of the Angular application is generally a really bad thing to
 * do, but there's no better way to access it from here since this can't be a service since it
 * gets called back from the iFrame.
 *
 */
gromit.fireLoginEvent = function() {
    var $body = angular.element(document.body);
    var $rootScope = $body.scope().$root;
    $rootScope.$apply(function () {
        $rootScope.$broadcast('loginCompleted');
    });
};<|endoftext|>


<commit_before>var request = require('request')
var crypto		= require('crypto');
var querystring	= require('querystring');
var nonce = (new Date).getTime();

function LBCClient(key, secret, otp) {
	var self = this;

	var config = {
		url: 'https://localbitcoins.com/api',
		key: key,
		secret: secret,
		otp: otp,
		timeoutMS: 5000
	};

	/**
	 * This method makes a public or private API request.
	 * @param  {String}   method   The API method (public or private)
	 * @param  {Object}   params   Arguments to pass to the api call
	 * @param  {Function} callback A callback function to be executed when the request is complete
	 * @return {Object}            The request object
	 */
	function api(method, params, callback) {
		var methods = {
			public: [],
			private: ['ad-get', 'ad-get/ad_id', 'myself',
			'dashboard', 'dashboard/released', 'dashboard/canceled', 'dashboard/closed',
			'dashboard/released/buyer', 'dashboard/canceled/buyer', 'dashboard/closed/buyer',
			'dashboard/released/seller', 'dashboard/canceled/seller', 'dashboard/closed/seller',
			'wallet-send'
			]
		};
		console.log(params);
		if(methods.public.indexOf(method) !== -1) {
			return publicMethod(method, params, callback);
		}
		else if(methods.private.indexOf(method) !== -1) {
			return privateMethod(method, params, callback);
		}
		else {
			throw new Error(method + ' is not a valid API method.');
		}
	}

	/**
	 * This method makes a public API request.
	 * @param  {String}   method   The API method (public or private)
	 * @param  {Object}   params   Arguments to pass to the api call
	 * @param  {Function} callback A callback function to be executed when the request is complete
	 * @return {Object}            The request object
	 */
	function publicMethod(method, params, callback) {
		params = params || {};

		var path	= '/' + method;
		var url		= config.url + path;

		return rawRequest(url, {}, params, callback);
	}

	/**
	 * This method makes a private API request.
	 * @param  {String}   method   The API method (public or private)
	 * @param  {Object}   params   Arguments to pass to the api call
	 * @param  {Function} callback A callback function to be executed when the request is complete
	 * @return {Object}            The request object
	 */
	function privateMethod(method, params, callback) {
		params = params || {};

		var path	= '/' + method;
		var url		= config.url + path;

		var signature = getMessageSignature(path, params, nonce);

		var headers = {
			'Content-Type': 'application/x-www-form-urlencoded',
			'Apiauth-Key': config.key,
			'Apiauth-Nonce': nonce,
			'Apiauth-Signature': signature
		};

		return rawRequest(url, headers, params, callback);
	}

	/**
	 * This method returns a signature for a request as a Base64-encoded string
	 * @param  {String}  path    The relative URL path for the request
	 * @param  {Object}  request The POST body
	 * @param  {Integer} nonce   A unique, incrementing integer
	 * @return {String}          The request signature
	 */
	function getMessageSignature(path, params, nonce) {
		var postParameters	= querystring.stringify(params);
		var path = '/api' + path + '/';
		var message = nonce + config.key + path + postParameters;
		var auth_hash = crypto.createHmac("sha256", config.secret).update(message).digest('hex').toUpperCase();
		return auth_hash;
	}

	/**
	 * This method sends the actual HTTP request
	 * @param  {String}   url      The URL to make the request
	 * @param  {Object}   headers  Request headers
	 * @param  {Object}   params   POST body
	 * @param  {Function} callback A callback function to call when the request is complete
	 * @return {Object}            The request object
	 */
	function rawRequest(url, headers, params, callback) {

		var options = {
			url: url + '/',
			headers: headers,
			form: params,
		};

		console.log(options);

		var req = request.post(options, function(error, response, body) {
			if(typeof callback === 'function') {
				var data;

				if(error) {
					callback.call(self, new Error('Error in server response: ' + JSON.stringify(error)), null);
					return;
				}

				try {
					data = JSON.parse(body);
				}
				catch(e) {
					callback.call(self, new Error('Could not understand response from server: ' + body), null);
					return;
				}

				if(data.error && data.error.length) {
					callback.call(self, data.error, null);
				}
				else {
					callback.call(self, null, data);
				}
			}
		});

		return req;
	}

	self.api			= api;
	self.publicMethod	= publicMethod;
	self.privateMethod	= privateMethod;
}

module.exports = LBCClient;
<commit_msg>Adding a route for routes that don't start with api<commit_after>var request = require('request')
var crypto		= require('crypto');
var querystring	= require('querystring');
var nonce = (new Date).getTime();

function LBCClient(key, secret, otp) {
	var self = this;

	var config = {
		url: 'https://localbitcoins.com/api',
		key: key,
		secret: secret,
		otp: otp,
		timeoutMS: 5000
	};

	/**
	 * This method makes a public or private API request.
	 * @param  {String}   method   The API method (public or private)
	 * @param  {Object}   params   Arguments to pass to the api call
	 * @param  {Function} callback A callback function to be executed when the request is complete
	 * @return {Object}            The request object
	 */
	function api(method, params, callback) {
		var methods = {
			onlineAds: ['buy-bitcoins-online'],
			public: ['countrycodes'],
			private: ['ad-get', 'ad-get/ad_id', 'myself', 'ads',
			'dashboard', 'dashboard/released', 'dashboard/canceled', 'dashboard/closed',
			'dashboard/released/buyer', 'dashboard/canceled/buyer', 'dashboard/closed/buyer',
			'dashboard/released/seller', 'dashboard/canceled/seller', 'dashboard/closed/seller',
			'wallet-send'
			]
		};
		if(methods.public.indexOf(method) !== -1) {
			return publicMethod(method, params, callback);
		}
		else if(methods.private.indexOf(method) !== -1) {
			return privateMethod(method, params, callback);
		}
		else {
			throw new Error(method + ' is not a valid API method.');
		}
	}

	/**
	 * This method makes a public API request.
	 * @param  {String}   method   The API method (public or private)
	 * @param  {Object}   params   Arguments to pass to the api call
	 * @param  {Function} callback A callback function to be executed when the request is complete
	 * @return {Object}            The request object
	 */
	function publicMethod(method, params, callback) {
		params = params || {};

		var path	= '/' + method;
		var url		= config.url + path;

		return rawRequest(url, {}, params, callback);
	}

	/**
	 * This method makes a private API request.
	 * @param  {String}   method   The API method (public or private)
	 * @param  {Object}   params   Arguments to pass to the api call
	 * @param  {Function} callback A callback function to be executed when the request is complete
	 * @return {Object}            The request object
	 */
	function privateMethod(method, params, callback) {
		params = params || {};

		var path	= '/' + method;
		var url		= config.url + path;

		var signature = getMessageSignature(path, params, nonce);

		var headers = {
			'Content-Type': 'application/x-www-form-urlencoded',
			'Apiauth-Key': config.key,
			'Apiauth-Nonce': nonce,
			'Apiauth-Signature': signature
		};

		return rawRequest(url, headers, params, callback);
	}

	/**
	 * This method returns a signature for a request as a Base64-encoded string
	 * @param  {String}  path    The relative URL path for the request
	 * @param  {Object}  request The POST body
	 * @param  {Integer} nonce   A unique, incrementing integer
	 * @return {String}          The request signature
	 */
	function getMessageSignature(path, params, nonce) {
		var postParameters	= querystring.stringify(params);
		var path = '/api' + path + '/';
		var message = nonce + config.key + path + postParameters;
		var auth_hash = crypto.createHmac("sha256", config.secret).update(message).digest('hex').toUpperCase();
		return auth_hash;
	}

	/**
	 * This method sends the actual HTTP request
	 * @param  {String}   url      The URL to make the request
	 * @param  {Object}   headers  Request headers
	 * @param  {Object}   params   POST body
	 * @param  {Function} callback A callback function to call when the request is complete
	 * @return {Object}            The request object
	 */
	function rawRequest(url, headers, params, callback) {

		var options = {
			url: url + '/',
			headers: headers,
			form: params,
		};

		var req = request.post(options, function(error, response, body) {
			if(typeof callback === 'function') {
				var data;

				if(error) {
					callback.call(self, new Error('Error in server response: ' + JSON.stringify(error)), null);
					return;
				}

				try {
					data = JSON.parse(body);
				}
				catch(e) {
					callback.call(self, new Error('Could not understand response from server: ' + body), null);
					return;
				}

				if(data.error && data.error.length) {
					callback.call(self, data.error, null);
				}
				else {
					callback.call(self, null, data);
				}
			}
		});

		return req;
	}

	self.api			= api;
	self.publicMethod	= publicMethod;
	self.privateMethod	= privateMethod;
}

module.exports = LBCClient;
<|endoftext|>


<commit_before>/**
 * Parse name identifiers in entity identifier name format.
 *
 * For details regarding this format, refer to SAML Core, section 8.3.6.
 *
 * References:
 *   - [Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0](http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf)
 *
 * @return {Function}
 * @api public
 */
module.exports = function() {

  return function(nid) {
    var name = {
      format: 'entity',
      formatURI: 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
    };
    var val = nid.text();

    name.entity =
    name.value = val;
    return name;
  };
};
<commit_msg>Clarify comment.<commit_after>/**
 * Parse name identifiers in entity identifier format.
 *
 * For details regarding this format, refer to SAML Core, section 8.3.6.
 *
 * References:
 *   - [Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0](http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf)
 *
 * @return {Function}
 * @api public
 */
module.exports = function() {

  return function(nid) {
    var name = {
      format: 'entity',
      formatURI: 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
    };
    var val = nid.text();

    name.entity =
    name.value = val;
    return name;
  };
};
<|endoftext|>


<commit_before>function something()
	{
		// получаем значение из localStorage
		var x = window.localStorage.getItem('b'); // x = hh['b']
		// уеличиваем это значение на 1 (x - переменная типа string)
		// для того, чтобы сделать ее int, надо умножить ее на 1
		// возвращает объект типа string, поэтому мы используем умножение
		// как самый простой способ преобразование строки в int
		x = x * 1 + 1; // x = x + 1
		// устанавливаем значение ключа b равным x
		window.localStorage.setItem('b', x); // hh['b'] = x
		alert(x);

	}

function add_to_cart(id)
	{
		var key = 'product_' + id;
		var x = window.localStorage.getItem(key);
		// т.е. id хеша будет выглядеть "product_1"
		// чтобы можно было различать объекты, которые хранятся в localStorage
		x = x * 1 + 1;
		window.localStorage.setItem(key, x);
	}<commit_msg>Add cart_get_number_of_items function<commit_after>function something()
	{
		// получаем значение из localStorage
		var x = window.localStorage.getItem('b'); // x = hh['b']
		// уеличиваем это значение на 1 (x - переменная типа string)
		// для того, чтобы сделать ее int, надо умножить ее на 1
		// возвращает объект типа string, поэтому мы используем умножение
		// как самый простой способ преобразование строки в int
		x = x * 1 + 1; // x = x + 1
		// устанавливаем значение ключа b равным x
		window.localStorage.setItem('b', x); // hh['b'] = x
		alert(x);

	}

function add_to_cart(id)
	{
		var key = 'product_' + id;
		// выделение переменной = extract variable
		var x = window.localStorage.getItem(key);
		// т.е. id хеша будет выглядеть "product_1"
		// чтобы можно было различать объекты, которые хранятся в localStorage
		x = x * 1 + 1;
		window.localStorage.setItem(key, x);

// вывод кол-ва пицц в корзине
		alert('Items in your cart: ' + cart_get_number_of_items());
	}

function cart_get_number_of_items()
{
	var cnt = 0;

	for(var i = 0; i < window.localStorage.length; i++)
	{
		var key = window.localStorage.key(i); //получаем ключ
		var value = window.localStorage.getItem(key); //получаем значение
		// аналог в ruby:
		// hh[key] = x

		// теперь надо найти ключи, начинающиеся c "product_"
		if(key.indexOf('product_') == 0);
		{
			cnt = cnt + value * 1;
		}
	}

	return cnt;
}<|endoftext|>