<commit_before>var logger = require('./logger')
var transport = require('./transport')
var utils = require('./utils')
var stacktraceGps = require('stacktrace-gps')
var StackTrace = require('stacktrace-js')

var sourceCache = {}

module.exports = {
  processWindowError: function (msg, file, line, col, error, options) {
    StackTrace.fromError(error, {
      sourceCache: sourceCache
    }).then(function (stackFrames) {
      var exception = {
        'message': error.message,
        'type': error.name,
        'fileurl': file,
        'lineno': line,
        'colno': col,
        'stack': stackFrames
      }

      this.stackInfoToOpbeatException(exception, options).then(function (exception) {
        this.processException(exception, options)
      }.bind(this))

    }.bind(this))

  },

  buildOpbeatFrame: function buildOpbeatFrame (stack, options) {
    options = options || {}

    return new Promise(function (resolve, reject) {

      // normalize the frames data
      var frame = {
        'filename': this.cleanFileUrl(stack.fileName),
        'lineno': stack.lineNumber,
        'colno': stack.columnNumber,
        'function': stack.functionName || '[anonymous]'
      }

      // Contexts
      this.getExceptionContexts(stack.fileName, stack.lineNumber).then(function (contexts) {
        frame.pre_context = contexts.preContext
        frame.context_line = contexts.contextLine
        frame.post_context = contexts.postContext

        resolve(frame)
      })

    }.bind(this))

  },

  stackInfoToOpbeatException: function (stackInfo, options) {
    options = options || {}

    return new Promise(function (resolve, reject) {
      if (stackInfo.stack && stackInfo.stack.length) {
        var framesPromises = stackInfo.stack.map(function (stack, i) {
          return this.buildOpbeatFrame(stack)
        }.bind(this))

        Promise.all(framesPromises).then(function (frames) {
          stackInfo.frames = frames
          stackInfo.stack = null
          resolve(stackInfo)
        })
      }

    }.bind(this))

    stackInfo.frames = []

    return stackInfo

  },

  cleanFileUrl: function (fileUrl) {
    if (!fileUrl) {
      fileUrl = ''
    }

    var origin = window.location.origin || window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port: '')

    if (fileUrl.indexOf(origin) > -1) {
      fileUrl = fileUrl.replace(origin + '/', '')
    }

    return fileUrl
  },

  processException: function processException (exception, options) {
    options = options || {}

    var stacktrace

    var type = exception.type
    var message = String(exception.message) || 'Script error'
    var fileUrl = this.cleanFileUrl(exception.fileurl)
    var frames = exception.frames || []

    if (frames && frames.length) {
      // Opbeat.com expects frames oldest to newest and JS sends them as newest to oldest
      frames.reverse()
    } else if (fileUrl) {
      frames.push({
        filename: fileUrl,
        lineno: exception.lineno
      })
    }

    stacktrace = {
      frames: frames
    }

    // Set fileUrl from last frame, if filename is missing
    if (!fileUrl && frames.length) {
      var lastFrame = frames[frames.length - 1]
      if (lastFrame.filename) {
        fileUrl = lastFrame.filename
      } else {
        // If filename empty, use location path and assume inline script
        fileUrl = window.location.pathname + ' (inline script)'
      }
    }

    var culprit = fileUrl

    var data = {
      message: type + ': ' + message,
      culprit: culprit,
      exception: {
        type: type,
        value: message
      },
      stacktrace: stacktrace,
      user: options.context ? options.context.user : null,
      timestamp: parseInt((new Date).getTime() / 1000, 10),
      level: null,
      logger: null,
      machine: null
    }

    data.extra = this.getBrowserSpecificMetadata()

    if (options.context && options.context.extra) {
      data.extra = utils.mergeObject(data.extra, options.context.extra)
    }

    logger.log('opbeat.exceptionst.processException', data)
    transport.sendToOpbeat(data, options)

  },

  getFileSourceMapUrl: function (fileUrl) {
    function _findSourceMappingURL (source) {
      var m = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)$/.exec(source)
      if (m && m[1]) {
        return m[1]
      }
      return null
    }

    if(fileUrl.split('/').length >1) {
      fileBasePath = fileUrl.split('/').slice(0, -1).join('/') + '/'
    } else {
      fileBasePath = '/'
    }

    return new Promise(function (resolve, reject) {
      var gps = new stacktraceGps({
        sourceCache: sourceCache
      })

      gps._get(fileUrl).then(function (source) {
        var sourceMapUrl = _findSourceMappingURL(source)
        if (sourceMapUrl) {
          sourceMapUrl = fileBasePath + sourceMapUrl
          resolve(sourceMapUrl)
        } else {
          reject(null)
        }
      }).catch(function(e) {
        console.error('e', e);
      })

    })
  },

  getExceptionContexts: function (url, line) {
    return new Promise(function (resolve, reject ) {
      var gps = new stacktraceGps({
      sourceCache})

      gps._get(url).then(function (source) {
        source = source.split('\n')
        line -= 1; // convert line to 0-based index

        var linesBefore = 5
        var linesAfter = 5

        var contexts = {
          preContext: [],
          contextLine: null,
          postContext: []
        }

        if (source.length) {
          // Pre context
          var preStartIndex = Math.max(0, line - linesBefore - 1)
          var preEndIndex = Math.min(source.length, line - 1)
          for (var i = preStartIndex; i <= preEndIndex; ++i) {
            if (!utils.isUndefined(source[i])) {
              contexts.preContext.push(source[i])
            }
          }

          // Line context
          contexts.contextLine = source[line]

          // Post context
          var postStartIndex = Math.min(source.length, line + 1)
          var postEndIndex = Math.min(source.length, line + linesAfter)
          for (var i = postStartIndex; i <= postEndIndex; ++i) {
            if (!utils.isUndefined(source[i])) {
              contexts.postContext.push(source[i])
            }
          }
        }

        logger.log('Opbeat.getExceptionContexts', contexts)
        resolve(contexts)
      })

    })

  },

  getBrowserSpecificMetadata: function () {
    var viewportInfo = utils.getViewPortInfo()
    var extra = {
      'environment': {
        'utcOffset': new Date().getTimezoneOffset() / -60.0,
        'browserWidth': viewportInfo.width,
        'browserHeight': viewportInfo.height,
        'screenWidth': window.screen.width,
        'screenHeight': window.screen.height,
        'language': navigator.language,
        'userAgent': navigator.userAgent,
        'platform': navigator.platform
      },
      'page': {
        'referer': document.referrer,
        'host': document.domain,
        'location': window.location.href
      }
    }

    return extra
  }

}
<commit_msg>Fix missing sourceCache for GPS<commit_after>var logger = require('./logger')
var transport = require('./transport')
var utils = require('./utils')
var stacktraceGps = require('stacktrace-gps')
var StackTrace = require('stacktrace-js')

var sourceCache = {}

module.exports = {
  processWindowError: function (msg, file, line, col, error, options) {
    StackTrace.fromError(error, {
      sourceCache: sourceCache
    }).then(function (stackFrames) {
      var exception = {
        'message': error.message,
        'type': error.name,
        'fileurl': file,
        'lineno': line,
        'colno': col,
        'stack': stackFrames
      }

      this.stackInfoToOpbeatException(exception, options).then(function (exception) {
        this.processException(exception, options)
      }.bind(this))

    }.bind(this))

  },

  buildOpbeatFrame: function buildOpbeatFrame (stack, options) {
    options = options || {}

    return new Promise(function (resolve, reject) {

      // normalize the frames data
      var frame = {
        'filename': this.cleanFileUrl(stack.fileName),
        'lineno': stack.lineNumber,
        'colno': stack.columnNumber,
        'function': stack.functionName || '[anonymous]'
      }

      // Contexts
      this.getExceptionContexts(stack.fileName, stack.lineNumber).then(function (contexts) {
        frame.pre_context = contexts.preContext
        frame.context_line = contexts.contextLine
        frame.post_context = contexts.postContext

        resolve(frame)
      })

    }.bind(this))

  },

  stackInfoToOpbeatException: function (stackInfo, options) {
    options = options || {}

    return new Promise(function (resolve, reject) {
      if (stackInfo.stack && stackInfo.stack.length) {
        var framesPromises = stackInfo.stack.map(function (stack, i) {
          return this.buildOpbeatFrame(stack)
        }.bind(this))

        Promise.all(framesPromises).then(function (frames) {
          stackInfo.frames = frames
          stackInfo.stack = null
          resolve(stackInfo)
        })
      }

    }.bind(this))

    stackInfo.frames = []

    return stackInfo

  },

  cleanFileUrl: function (fileUrl) {
    if (!fileUrl) {
      fileUrl = ''
    }

    var origin = window.location.origin || window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port: '')

    if (fileUrl.indexOf(origin) > -1) {
      fileUrl = fileUrl.replace(origin + '/', '')
    }

    return fileUrl
  },

  processException: function processException (exception, options) {
    options = options || {}

    var stacktrace

    var type = exception.type
    var message = String(exception.message) || 'Script error'
    var fileUrl = this.cleanFileUrl(exception.fileurl)
    var frames = exception.frames || []

    if (frames && frames.length) {
      // Opbeat.com expects frames oldest to newest and JS sends them as newest to oldest
      frames.reverse()
    } else if (fileUrl) {
      frames.push({
        filename: fileUrl,
        lineno: exception.lineno
      })
    }

    stacktrace = {
      frames: frames
    }

    // Set fileUrl from last frame, if filename is missing
    if (!fileUrl && frames.length) {
      var lastFrame = frames[frames.length - 1]
      if (lastFrame.filename) {
        fileUrl = lastFrame.filename
      } else {
        // If filename empty, use location path and assume inline script
        fileUrl = window.location.pathname + ' (inline script)'
      }
    }

    var culprit = fileUrl

    var data = {
      message: type + ': ' + message,
      culprit: culprit,
      exception: {
        type: type,
        value: message
      },
      stacktrace: stacktrace,
      user: options.context ? options.context.user : null,
      timestamp: parseInt((new Date).getTime() / 1000, 10),
      level: null,
      logger: null,
      machine: null
    }

    data.extra = this.getBrowserSpecificMetadata()

    if (options.context && options.context.extra) {
      data.extra = utils.mergeObject(data.extra, options.context.extra)
    }

    logger.log('opbeat.exceptionst.processException', data)
    transport.sendToOpbeat(data, options)

  },

  getFileSourceMapUrl: function (fileUrl) {
    function _findSourceMappingURL (source) {
      var m = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)$/.exec(source)
      if (m && m[1]) {
        return m[1]
      }
      return null
    }

    if(fileUrl.split('/').length >1) {
      fileBasePath = fileUrl.split('/').slice(0, -1).join('/') + '/'
    } else {
      fileBasePath = '/'
    }

    return new Promise(function (resolve, reject) {
      var gps = new stacktraceGps({
        sourceCache: sourceCache
      })

      gps._get(fileUrl).then(function (source) {
        var sourceMapUrl = _findSourceMappingURL(source)
        if (sourceMapUrl) {
          sourceMapUrl = fileBasePath + sourceMapUrl
          resolve(sourceMapUrl)
        } else {
          reject(null)
        }
      }).catch(function(e) {
        console.error('e', e);
      })

    })
  },

  getExceptionContexts: function (url, line) {
    return new Promise(function (resolve, reject ) {
      var gps = new stacktraceGps({
        sourceCache: sourceCache
      })

      gps._get(url).then(function (source) {
        source = source.split('\n')
        line -= 1; // convert line to 0-based index

        var linesBefore = 5
        var linesAfter = 5

        var contexts = {
          preContext: [],
          contextLine: null,
          postContext: []
        }

        if (source.length) {
          // Pre context
          var preStartIndex = Math.max(0, line - linesBefore - 1)
          var preEndIndex = Math.min(source.length, line - 1)
          for (var i = preStartIndex; i <= preEndIndex; ++i) {
            if (!utils.isUndefined(source[i])) {
              contexts.preContext.push(source[i])
            }
          }

          // Line context
          contexts.contextLine = source[line]

          // Post context
          var postStartIndex = Math.min(source.length, line + 1)
          var postEndIndex = Math.min(source.length, line + linesAfter)
          for (var i = postStartIndex; i <= postEndIndex; ++i) {
            if (!utils.isUndefined(source[i])) {
              contexts.postContext.push(source[i])
            }
          }
        }

        logger.log('Opbeat.getExceptionContexts', contexts)
        resolve(contexts)
      })

    })

  },

  getBrowserSpecificMetadata: function () {
    var viewportInfo = utils.getViewPortInfo()
    var extra = {
      'environment': {
        'utcOffset': new Date().getTimezoneOffset() / -60.0,
        'browserWidth': viewportInfo.width,
        'browserHeight': viewportInfo.height,
        'screenWidth': window.screen.width,
        'screenHeight': window.screen.height,
        'language': navigator.language,
        'userAgent': navigator.userAgent,
        'platform': navigator.platform
      },
      'page': {
        'referer': document.referrer,
        'host': document.domain,
        'location': window.location.href
      }
    }

    return extra
  }

}
<|endoftext|>


<commit_before>function in_array(array, element){
	try{
		if (array.indexOf(element) >= 0){
			return true;
		}
		return false;
	} catch (e){
		console.log(e);
	}
}

function extract(data, where) {
    for (var key in data) {
        where[key] = data[key];
    }
}

local_storage = function(database_name, database_object){
	try{
		var local_storage_prefix = 'WyvernDB-';
		if (database_object){
			localStorage.setItem(local_storage_prefix + database_name, JSON.stringify(database_object));
		} else {
			return JSON.parse( localStorage.getItem(local_storage_prefix + database_name) );
		}
	} catch (e){
		console.log(e);
	}
}

function WyvernDB (name){
	var tables = local_storage(name);
	if (tables){
		this.name = name;
		this.tables = tables;

		console.log('Database ' + name + ' imported.')
	} else {
		this.name = name;
		this.tables = {};
		console.log('Database ' + name + ' created.')
		local_storage(name, this.tables);
	}

	var database = this;

	this.add_table = function (name, columns){
		if (!database.tables){
			database.tables = {};
		}
		if (database.tables[name]){
			throw 'Table ' + name + ' already exists.';
			return null;
		}

		database.tables[name] = {
			columns : columns,
			rows : [],
		};
		console.log('Table ' + name + ' created.');
		local_storage(database.name, database.tables)
	}

	this.insert = function (table, rows){
		var columns = [];
		var index_columns = [];

		if (typeof rows != 'array'){
			rows = [rows]
		}

		for (var i = 0; i < database.tables[table]['columns'].length; i++){
			columns.push(database.tables[table]['columns'][i]['name']);

			if (database.tables[table]['columns'][i]['unique']){
				index_columns.push(database.tables[table]['columns'][i]['name'])
			}
		}

		for (var i = 0; i < rows.length; i++){
			var row = rows[i];
			for (var key in row){
				if (!in_array(columns, key)){
					throw 'Key ' + key + ' not in set of columns ' + columns + ' for table ' + table;
					return null;
				}

				if (in_array(index_columns, key)){
					var exists = database.tables[table].rows.filter(function (elem){
						if (elem[key] === row[key]){
							throw 'Row with indexed column ' + key +' already exists. Try update instead.';
							return null;
						}
					})
				}
			}
		}

		database.tables[table].rows = database.tables[table].rows.concat(rows);
		local_storage(database.name, database.tables);
		return (true, rows);
	}

	this.select = function (table, where){
		var results = database.tables[table].rows.filter(function (row){
			extract(row, this)
			if (eval(where)){
				return row;
			}
		})

		return results;
	}

	this.remove = function (table, where){
		var results = [];
		database.tables[table].rows.forEach(function (row, i){
			extract(row, this);
			if (eval(where)){
				database.tables[table].rows.splice(i, 1);
				results.push(row);
			}
		})
		local_storage(database.name, database.tables)
		return results;
	}

	this.update = function (table, rows){
		var columns = [];
		var index_columns = [];

		if (typeof rows != 'array'){
			rows = [rows]
		}
		for (var i = 0; i < database.tables[table]['columns'].length; i++){
			columns.push(database.tables[table]['columns'][i]['name']);

			if (database.tables[table]['columns'][i]['unique']){
				index_columns.push(database.tables[table]['columns'][i]['name'])
			}
		}

		for (var i = 0; i < rows.length; i++){
			var row = rows[i];
			for (var key in row){
				if (!in_array(columns, key)){
					throw 'Key ' + key + ' not in set of columns ' + columns + ' for table ' + table;
					return null;
				}

				if (in_array(index_columns, key)){
					for (var i = 0; i < database.tables[table].rows.length; i++){
						var elem = database.tables[table].rows[i];
						if (elem[key] === row[key]){
							database.tables[table].rows[i] = row;
						}
					}
				}
			}
		}

		local_storage(database.name, database.tables);
		return (true, rows);
	}

	return this;
}<commit_msg>Added support for autoincrement indexes Added random guid for indexes Added timestamps for creation and modification to each row<commit_after>function in_array(array, element){
	try{
		if (array.indexOf(element) >= 0){
			return true;
		}
		return false;
	} catch (e){
		console.log(e);
	}
}

function extract(data, where) {
    for (var key in data) {
        where[key] = data[key];
    }
}

local_storage = function(database_name, database_object){
	try{
		var local_storage_prefix = 'WyvernDB-';
		if (database_object){
			localStorage.setItem(local_storage_prefix + database_name, JSON.stringify(database_object));
		} else {
			return JSON.parse( localStorage.getItem(local_storage_prefix + database_name) );
		}
	} catch (e){
		console.log(e);
	}
}

function WyvernDB (name){
	var database = this;

	this.guid = function() {
		function s4(){
			return Math.floor((1 + Math.random()) * 0x100000).toString(16).substring(1);
		}
		return s4() + s4() + '-' + s4() + s4() + '-' + s4() + s4() + '-' + s4() + s4()
	}

	this.size = function (){
		var result = {
			wyvern_total_count : 0,
		}
		for (var table in database.tables){
			result[table] = JSON.stringify(database.tables[table]).length;
			result['wyvern_total_count'] += result[table]
		}

		return result;
	}

	this.create_table = function (name, columns, options){
		if (!database.tables){
			database.tables = {};
		}
		if (database.tables[name]){
			throw 'Table ' + name + ' already exists.';
			return null;
		}

		if (!options.autoincrement_index){
			options.autoincrement_index = 0;
		}

		database.tables[name] = {
			columns : columns,
			rows : [],
			options : options,
		};
		console.log('Table ' + name + ' created.');
		local_storage(database.name, database.tables)
	}

	this.insert = function (table, rows){
		var columns = database.tables[table]['columns'];
		var index_columns = [];

		if (typeof rows != 'array'){
			rows = [rows]
		}

		if (database.tables[table]['unique']){
			index_columns = database.tables[table]['unique']
		}

		for (var i = 0; i < rows.length; i++){
			var row = rows[i];
			for (var key in row){
				if (!in_array(columns, key)){
					throw 'Key ' + key + ' not in set of columns ' + columns + ' for table ' + table;
					return null;
				}

				if (in_array(index_columns, key)){
					var exists = database.tables[table].rows.filter(function (elem){
						if (elem[key] === row[key]){
							throw 'Row with indexed column ' + key +' already exists. Try update instead.';
							return null;
						}
					})
				}

				rows[i]['create_timestamp'] = new Date().getTime();
				rows[i]['last_modified_timestamp'] = new Date().getTime();

				if (database.tables[table]['options']['guid']){
					for (var j = 0; j < database.tables[table]['options']['guid'].length; j++){
						row[database.tables[table]['options']['guid'][j]] = database.guid();
					}
				}

				if (database.tables[table]['options']['autoincrement']){
					for (var j = 0; j < database.tables[table]['options']['autoincrement'].length; j++){
						row[database.tables[table]['options']['autoincrement'][j]] = database.tables[table]['options']['autoincrement_index'];
					}

				}
			}

			if (database.tables[table]['options']['autoincrement']){
				database.tables[table]['options']['autoincrement_index']++;
			}
		}

		database.tables[table].rows = database.tables[table].rows.concat(rows);
		local_storage(database.name, database.tables);
		return (true, rows);
	}

	this.select = function (table, where){

		var results = database.tables[table].rows.filter(function (row){
			extract(row, this)
			if (typeof eval(where) === 'boolean'){
				if (eval(where)){
					return row;
				}
			}
		})

		return results;
	}

	this.remove = function (table, where){
		var results = [];
		database.tables[table].rows.forEach(function (row, i){
			extract(row, this);
			if (eval(where)){
				database.tables[table].rows.splice(i, 1);
				results.push(row);
			}
		})
		local_storage(database.name, database.tables)
		return results;
	}

	this.update = function (table, rows){
		var columns = [];
		var index_columns = [];

		if (typeof rows != 'array'){
			rows = [rows]
		}
		for (var i = 0; i < database.tables[table]['columns'].length; i++){
			columns.push(database.tables[table]['columns'][i]['name']);

			if (database.tables[table]['columns'][i]['unique']){
				index_columns.push(database.tables[table]['columns'][i]['name'])
			}
		}

		for (var i = 0; i < rows.length; i++){
			var row = rows[i];
			for (var key in row){
				if (!in_array(columns, key)){
					throw 'Key ' + key + ' not in set of columns ' + columns + ' for table ' + table;
					return null;
				}

				if (in_array(index_columns, key)){
					for (var i = 0; i < database.tables[table].rows.length; i++){
						var elem = database.tables[table].rows[i];
						if (elem[key] === row[key]){
							database.tables[table].rows[i] = row;
						}
					}
				}
			}
			row[i]['last_modified_timestamp'] = new Date().getTime();
		}

		local_storage(database.name, database.tables);
		return (true, rows);
	}

	return this;
}<|endoftext|>


<commit_before>var ANIM = (function() {

  /* SETTING INCREMENTAL TIMING ------------------------------ */

  // HOW TO USE
  // 1.) Set a parent element with with a class onto which to hook (commonly set to a class like 'set-timing')
  // There are two ways to proceed from here -- set attributes or pass explicit timing delays and increments. The process for adding attributes is
  // detailed below -- if you would prefer to pass them explicitly, simply pass them along with your selector into the 'setTiming' function.
  // 2.) Set the timing-delay attribute of the parent element. This will determine when the fade-ins START. For example, setting a
  // timing-delay like this -- timing-delay="2000" -- will have the first fade-in start at 2000ms after the animation is initiated.
  // NOTE: The default is 0ms.
  // 3.) Set the timing-increment attribute of the parent element. This will determine the amount of time between each individual fade-* animation.
  // NOTE: The default is set to 40ms.
  // 4.) Set children elements with a class to hook onto. The default is set to all of the fade-* classes (fade-in, fade-up, fade-down, fade-left, fade-right)

  // Setting timing delays & increments of children
  function setTiming(arg) {

    // defaults
    var opt = {
      parent: arg && arg.parent ? arg.parent : 'set-timing',
      child: arg && arg.child ? arg.child : '.fade-in, .fade-up, .fade-right, .fade-down, .fade-left',
      delay: 0,
      increment: 40,
      type: arg && arg.type ? arg.type : 'transition'
    }

    $(opt.parent).each(function(el) {
      if (!arg && !arg.delay && getTimingDelay($(this)) !== null) {
        opt.delay = getTimingDelay($(this));
      } else if (arg && arg.delay) {
        opt.delay = arg.delay;
      }
      if (!arg && !arg.increment && getTimingIncrement($(this)) !== null) {
        opt.increment = getTimingIncrement($(this));
      } else if (arg && arg.increment) {
        opt.increment = arg.increment;
      }
      setChildTiming($(this).find(opt.child), opt.delay, opt.increment, opt.type);
    });
  }

  // Utility function to get the timing delay from the 'timing-delay' attribute
  function getTimingDelay(el) {
    var timingDelayAttr = parseInt($(el).attr('timing-delay')),
        timingDelay = isNaN(timingDelayAttr) ? null : timingDelayAttr;
    return timingDelay;
  }

  // Utility function to get the timing increment from the 'timing-increment' attribute
  function getTimingIncrement(el) {
    var timingIncrementAttr = parseInt($(el).attr('timing-increment')),
        timingIncrement = isNaN(timingIncrementAttr) ? null : timingIncrementAttr;
    return timingIncrement;
  }

  // Utility function to increment timing delays on passed el, starting from the start argument,
  // and incrementing by the increment argument
  function setChildTiming(el, start, increment, type) {
    var timingDelay = start,
        realIncrement = increment === undefined ? 0 : increment;
    $(el).each(function() {
      if (type === 'transition') $(this).css('transition-delay', timingDelay + 'ms');
      if (type === 'animation') $(this).css('animation-delay', timingDelay + 'ms');
      timingDelay += realIncrement;
    });
  }

  // Progressively fade-in letters. This function takes letters in an element and wraps them in spans with the given fade-* class
  // as well as the given start and increment. You can also set the 'timing-delay' and 'timing-increment' on the passed element,
  // otherwise you can pass it explicitly as an argument.
  //
  // This can handle nested HTML elements (like span), but I would recommend keeping this as deep as possible in the node tree
  function letterFadeIn(selector, fadeInClass, start, increment) {
    var inHTML = false;

    // room for improvement -- scope the incremental delay to slides. Right now, it considers the entire carousel

    $(selector).each(function() {
      var split = $(this).html().match(/[a-zA-Z\d&;<\/="\->\s\n]/g),
          htmlEntity = false,
          htmlEntityContainer;
      var mappedSplit = split.map(function(el) {

        // Keeping track of any nested html tags
        if (el === '<') {
          inHTML = true;
          return el;
        } else if (el === '>') {
          inHTML = false;
          return el;
        } else if (inHTML) {
          return el;

        // collecting html entities for proper rendering
        } else if (!inHTML && !htmlEntity && el === '&') {
          htmlEntity = true;
          htmlEntityContainer = el;
        } else if (!inHTML && htmlEntity && el === ';') {
          htmlEntity = false;
          htmlEntityContainer += el;
          return '' + htmlEntityContainer + '';
        } else if (!inHTML && htmlEntity) {
          htmlEntityContainer += el;

        // collecting regular letters & numbers & wrapping them in spans with fade-in class
        } else if (!inHTML && /[a-zA-Z\d]/.test(el)) {
          return '' + el + '';
        } else if (!inHTML && /[\s|\n]/.test(el)) {
          return el;
        }
      });
      joinedMappedSplit = mappedSplit.join('');
      $(this).html(joinedMappedSplit);
    });

    var timingDelay = start ? start : getTimingDelay(selector),
        timingIncrement = increment ? increment : getTimingIncrement(selector);

    setChildTiming(selector + ' span.' + fadeInClass, timingDelay, timingIncrement);
  }

  return {
    setTiming: setTiming,
    letterFadeIn: letterFadeIn
  }
})();
<commit_msg>fixed arg checkers<commit_after>var ANIM = (function() {

  /* SETTING INCREMENTAL TIMING ------------------------------ */

  // HOW TO USE
  // 1.) Set a parent element with with a class onto which to hook (commonly set to a class like 'set-timing')
  // There are two ways to proceed from here -- set attributes or pass explicit timing delays and increments. The process for adding attributes is
  // detailed below -- if you would prefer to pass them explicitly, simply pass them along with your selector into the 'setTiming' function.
  // 2.) Set the timing-delay attribute of the parent element. This will determine when the fade-ins START. For example, setting a
  // timing-delay like this -- timing-delay="2000" -- will have the first fade-in start at 2000ms after the animation is initiated.
  // NOTE: The default is 0ms.
  // 3.) Set the timing-increment attribute of the parent element. This will determine the amount of time between each individual fade-* animation.
  // NOTE: The default is set to 40ms.
  // 4.) Set children elements with a class to hook onto. The default is set to all of the fade-* classes (fade-in, fade-up, fade-down, fade-left, fade-right)

  // Setting timing delays & increments of children
  function setTiming(arg) {

    // defaults
    var opt = {
      parent: arg && arg.parent ? arg.parent : 'set-timing',
      child: arg && arg.child ? arg.child : '.fade-in, .fade-up, .fade-right, .fade-down, .fade-left',
      delay: 0,
      increment: 40,
      type: arg && arg.type ? arg.type : 'transition'
    }

    $(opt.parent).each(function(el) {
      if ((!arg || !arg.delay) && getTimingDelay($(this)) !== null) {
        opt.delay = getTimingDelay($(this));
      } else if (arg && arg.delay) {
        opt.delay = arg.delay;
      }
      if ((!arg || !arg.increment) && getTimingIncrement($(this)) !== null) {
        opt.increment = getTimingIncrement($(this));
      } else if (arg && arg.increment) {
        opt.increment = arg.increment;
      }
      setChildTiming($(this).find(opt.child), opt.delay, opt.increment, opt.type);
    });
  }

  // Utility function to get the timing delay from the 'timing-delay' attribute
  function getTimingDelay(el) {
    var timingDelayAttr = parseInt($(el).attr('timing-delay')),
        timingDelay = isNaN(timingDelayAttr) ? null : timingDelayAttr;
    return timingDelay;
  }

  // Utility function to get the timing increment from the 'timing-increment' attribute
  function getTimingIncrement(el) {
    var timingIncrementAttr = parseInt($(el).attr('timing-increment')),
        timingIncrement = isNaN(timingIncrementAttr) ? null : timingIncrementAttr;
    return timingIncrement;
  }

  // Utility function to increment timing delays on passed el, starting from the start argument,
  // and incrementing by the increment argument
  function setChildTiming(el, start, increment, type) {
    var timingDelay = start,
        realIncrement = increment === undefined ? 0 : increment;
    $(el).each(function() {
      if (type === 'transition') $(this).css('transition-delay', timingDelay + 'ms');
      if (type === 'animation') $(this).css('animation-delay', timingDelay + 'ms');
      timingDelay += realIncrement;
    });
  }

  // Progressively fade-in letters. This function takes letters in an element and wraps them in spans with the given fade-* class
  // as well as the given start and increment. You can also set the 'timing-delay' and 'timing-increment' on the passed element,
  // otherwise you can pass it explicitly as an argument.
  //
  // This can handle nested HTML elements (like span), but I would recommend keeping this as deep as possible in the node tree
  function letterFadeIn(selector, fadeInClass, start, increment) {
    var inHTML = false;

    // room for improvement -- scope the incremental delay to slides. Right now, it considers the entire carousel

    $(selector).each(function() {
      var split = $(this).html().match(/[a-zA-Z\d&;<\/="\->\s\n]/g),
          htmlEntity = false,
          htmlEntityContainer;
      var mappedSplit = split.map(function(el) {

        // Keeping track of any nested html tags
        if (el === '<') {
          inHTML = true;
          return el;
        } else if (el === '>') {
          inHTML = false;
          return el;
        } else if (inHTML) {
          return el;

        // collecting html entities for proper rendering
        } else if (!inHTML && !htmlEntity && el === '&') {
          htmlEntity = true;
          htmlEntityContainer = el;
        } else if (!inHTML && htmlEntity && el === ';') {
          htmlEntity = false;
          htmlEntityContainer += el;
          return '' + htmlEntityContainer + '';
        } else if (!inHTML && htmlEntity) {
          htmlEntityContainer += el;

        // collecting regular letters & numbers & wrapping them in spans with fade-in class
        } else if (!inHTML && /[a-zA-Z\d]/.test(el)) {
          return '' + el + '';
        } else if (!inHTML && /[\s|\n]/.test(el)) {
          return el;
        }
      });
      joinedMappedSplit = mappedSplit.join('');
      $(this).html(joinedMappedSplit);
    });

    var timingDelay = start ? start : getTimingDelay(selector),
        timingIncrement = increment ? increment : getTimingIncrement(selector);

    setChildTiming(selector + ' span.' + fadeInClass, timingDelay, timingIncrement);
  }

  return {
    setTiming: setTiming,
    letterFadeIn: letterFadeIn
  }
})();
<|endoftext|>


<commit_before>var ANIM = (function() {

  /* GRADUAL FADE-INS ------------------------------ */

  // HOW TO USE
  // 1.) Set a parent element with with a class onto which to hook (commonly set to a class like 'fade-in-gradual')
  // There are two ways to proceed from here -- set attributes or pass explicit timing delays and increments. The process for adding attributes is
  // detailed below -- if you would prefer to pass them explicitly, simply pass them along with your selector into the 'gradualFadeIn' function.
  // 2.) Set the timing-delay attribute of the parent element. This will determine when the fade-ins START. For example, setting a
  // timing-delay like this -- timing-delay="2000" -- will have the first fade-in start at 2000ms after the animation is initiated.
  // NOTE: The default is 0ms.
  // 3.) Set the timing-increment attribute of the parent element. This will determine the amount of time between each individual fade-* animation.
  // NOTE: The default is set to 40ms.
  // 4.) Set children elements with any of the fade-* classes (fade-in, fade-up, fade-down, fade-left, fade-right)
  // 3.) Initiate the animation by adding the 'anim-init' class to either the parent element, or an element further up the chain (both work).

  var fades = '.fade-in, .fade-up, .fade-right, .fade-down, .fade-left',
      defaultTimingDelay = 0,
      defaultTimingIncrement = 40;

  // Setting fade-in delays of children of gradualFadeInSelector with any of the fade-* classes
  function gradualFadeIn(selector, start, increment) {
    $(selector).each(function(el) {
      var timingDelay = start ? start : getTimingDelay($(this)), // start value
          timingIncrement = increment ? increment : getTimingIncrement($(this));
      setTimingIncrement($(this).find(fades), timingDelay, timingIncrement);
    });
  }

  // Utility function to get the timing delay from the 'timing-delay' attribute
  function getTimingDelay(el) {
    var timingDelayAttr = parseInt($(el).attr('timing-delay')),
        timingDelay = isNaN(timingDelayAttr) ? defaultTimingDelay : timingDelayAttr;
    return timingDelay;
  }

  // Utility function to get the timing increment from the 'timing-increment' attribute
  function getTimingIncrement(el) {
    var timingIncrementAttr = parseInt($(el).attr('timing-increment')),
        timingIncrement = isNaN(timingIncrementAttr) ? defaultTimingIncrement : timingIncrementAttr;
    return timingIncrement;
  }

  // Utility function to increment timing delays on passed el, starting from the start argument,
  // and incrementing by the increment argument
  function setTimingIncrement(el, start, increment) {
    var timingDelay = start,
        realIncrement = increment === undefined ? 0 : increment;
    $(el).each(function() {
      $(this).css('transition-delay', timingDelay + 'ms');
      timingDelay += realIncrement;
    });
  }

  // Progressively fade-in letters. This function takes letters in an element and wraps them in spans with the given fade-* class
  // as well as the given start and increment. You can also set the 'timing-delay' and 'timing-increment' on the passed element,
  // otherwise you can pass it explicitly as an argument.
  //
  // This can handle nested HTML elements (like span), but I would recommend keeping this as deep as possible in the node tree
  function letterFadeIn(selector, fadeInClass, start, increment) {
    var inHTML = false;

    // room for improvement -- scope the incremental delay to slides. Right now, it considers the entire carousel

    $(selector).each(function() {
      var split = $(this).html().match(/[a-zA-Z\d&;<\/="\->\s\n]/g),
          htmlEntity = false,
          htmlEntityContainer;
      var mappedSplit = split.map(function(el) {

        // Keeping track of any nested html tags
        if (el === '<') {
          inHTML = true;
          return el;
        } else if (el === '>') {
          inHTML = false;
          return el;
        } else if (inHTML) {
          return el;

        // collecting html entities for proper rendering
        } else if (!inHTML && !htmlEntity && el === '&') {
          htmlEntity = true;
          htmlEntityContainer = el;
        } else if (!inHTML && htmlEntity && el === ';') {
          htmlEntity = false;
          htmlEntityContainer += el;
          return '' + htmlEntityContainer + '';
        } else if (!inHTML && htmlEntity) {
          htmlEntityContainer += el;

        // collecting regular letters & numbers & wrapping them in spans with fade-in class
        } else if (!inHTML && /[a-zA-Z\d]/.test(el)) {
          return '' + el + '';
        } else if (!inHTML && /[\s|\n]/.test(el)) {
          return el;
        }
      });
      joinedMappedSplit = mappedSplit.join('');
      $(this).html(joinedMappedSplit);
    });

    var timingDelay = start ? start : getTimingDelay(selector),
        timingIncrement = increment ? increment : getTimingIncrement(selector);

    setTimingIncrement(selector + ' span.' + fadeInClass, timingDelay, timingIncrement);
  }

  return {
    gradualFadeIn: gradualFadeIn,
    letterFadeIn: letterFadeIn
  }
})();
<commit_msg>Added object arguments and allows user to specify child classes to target<commit_after>var ANIM = (function() {

  /* SETTING INCREMENTAL TIMING ------------------------------ */

  // HOW TO USE
  // 1.) Set a parent element with with a class onto which to hook (commonly set to a class like 'set-timing')
  // There are two ways to proceed from here -- set attributes or pass explicit timing delays and increments. The process for adding attributes is
  // detailed below -- if you would prefer to pass them explicitly, simply pass them along with your selector into the 'setTiming' function.
  // 2.) Set the timing-delay attribute of the parent element. This will determine when the fade-ins START. For example, setting a
  // timing-delay like this -- timing-delay="2000" -- will have the first fade-in start at 2000ms after the animation is initiated.
  // NOTE: The default is 0ms.
  // 3.) Set the timing-increment attribute of the parent element. This will determine the amount of time between each individual fade-* animation.
  // NOTE: The default is set to 40ms.
  // 4.) Set children elements with a class to hook onto. The default is set to all of the fade-* classes (fade-in, fade-up, fade-down, fade-left, fade-right)

  var defaultTimingDelay = 0,
      defaultTimingIncrement = 40;

  // Setting timing delays & increments of children
  function setTiming(arg) {

    // defaults
    var opt = {
      parent: arg && arg.parent ? arg.parent : 'set-timing',
      child: arg && arg.child ? arg.child : '.fade-in, .fade-up, .fade-right, .fade-down, .fade-left',
      delay: 0,
      increment: 40,
      type: arg && arg.type ? arg.type : 'transition'
    }

    $(opt.parent).each(function(el) {
      if (!arg && !arg.delay && getTimingDelay($(this)) !== null) {
        opt.delay = getTimingDelay($(this));
      } else if (arg && arg.delay) {
        opt.delay = arg.delay;
      }
      if (!arg && !arg.increment && getTimingIncrement($(this)) !== null) {
        opt.increment = getTimingIncrement($(this));
      } else if (arg && arg.increment) {
        opt.increment = arg.increment;
      }
      setChildTiming($(this).find(opt.child), opt.delay, opt.increment, opt.type);
    });
  }

  // Utility function to get the timing delay from the 'timing-delay' attribute
  function getTimingDelay(el) {
    var timingDelayAttr = parseInt($(el).attr('timing-delay')),
        timingDelay = isNaN(timingDelayAttr) ? null : timingDelayAttr;
    return timingDelay;
  }

  // Utility function to get the timing increment from the 'timing-increment' attribute
  function getTimingIncrement(el) {
    var timingIncrementAttr = parseInt($(el).attr('timing-increment')),
        timingIncrement = isNaN(timingIncrementAttr) ? null : timingIncrementAttr;
    return timingIncrement;
  }

  // Utility function to increment timing delays on passed el, starting from the start argument,
  // and incrementing by the increment argument
  function setChildTiming(el, start, increment, type) {
    var timingDelay = start,
        realIncrement = increment === undefined ? 0 : increment;
    $(el).each(function() {
      if (type === 'transition') $(this).css('transition-delay', timingDelay + 'ms');
      if (type === 'animation') $(this).css('animation-delay', timingDelay + 'ms');
      timingDelay += realIncrement;
    });
  }

  // Progressively fade-in letters. This function takes letters in an element and wraps them in spans with the given fade-* class
  // as well as the given start and increment. You can also set the 'timing-delay' and 'timing-increment' on the passed element,
  // otherwise you can pass it explicitly as an argument.
  //
  // This can handle nested HTML elements (like span), but I would recommend keeping this as deep as possible in the node tree
  function letterFadeIn(selector, fadeInClass, start, increment) {
    var inHTML = false;

    // room for improvement -- scope the incremental delay to slides. Right now, it considers the entire carousel

    $(selector).each(function() {
      var split = $(this).html().match(/[a-zA-Z\d&;<\/="\->\s\n]/g),
          htmlEntity = false,
          htmlEntityContainer;
      var mappedSplit = split.map(function(el) {

        // Keeping track of any nested html tags
        if (el === '<') {
          inHTML = true;
          return el;
        } else if (el === '>') {
          inHTML = false;
          return el;
        } else if (inHTML) {
          return el;

        // collecting html entities for proper rendering
        } else if (!inHTML && !htmlEntity && el === '&') {
          htmlEntity = true;
          htmlEntityContainer = el;
        } else if (!inHTML && htmlEntity && el === ';') {
          htmlEntity = false;
          htmlEntityContainer += el;
          return '' + htmlEntityContainer + '';
        } else if (!inHTML && htmlEntity) {
          htmlEntityContainer += el;

        // collecting regular letters & numbers & wrapping them in spans with fade-in class
        } else if (!inHTML && /[a-zA-Z\d]/.test(el)) {
          return '' + el + '';
        } else if (!inHTML && /[\s|\n]/.test(el)) {
          return el;
        }
      });
      joinedMappedSplit = mappedSplit.join('');
      $(this).html(joinedMappedSplit);
    });

    var timingDelay = start ? start : getTimingDelay(selector),
        timingIncrement = increment ? increment : getTimingIncrement(selector);

    setChildTiming(selector + ' span.' + fadeInClass, timingDelay, timingIncrement);
  }

  return {
    setTiming: setTiming,
    letterFadeIn: letterFadeIn
  }
})();
<|endoftext|>


<commit_before>var express = require('express');
var app = express();

var sqlite3 = require('sqlite3');
var db = new sqlite3.Database('Tester3');

app.set('view engine', 'jade');

app.get('/', function (req, res) {

   db.serialize(function() {
    db.all('SELECT * FROM Donor', function(err, rows) {
      var arr = [];
      console.log(rows);
      console.log(rows.length);
      res.render('index2', { title: rows[0].PrimaryID, message: rows[0].FirstName, data: rows });

        // res.send(rows)

      // for (i=0;i<rows.length;i++) {

      // }

   });
  })
 })

app.listen(3000);

<commit_msg>cleaned up code<commit_after>var express = require('express');
var app = express();

var sqlite3 = require('sqlite3');
var db = new sqlite3.Database('Tester3');

app.set('view engine', 'jade');

app.get('/', function (req, res) {

   db.serialize(function() {
    db.all('SELECT * FROM Donor', function(err, rows) {
      var arr = [];
      console.log(rows);
      console.log(rows.length);
      res.render('index2', { data: rows });
   });
  });
 });

app.listen(3000);

<|endoftext|>


<commit_before>/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.SpotLight = function ( color, intensity, distance, angle, penumbra, decay ) {

	THREE.Light.call( this, color, intensity );

	this.type = 'SpotLight';

	this.position.set( 0, 1, 0 );
	this.updateMatrix();

	this.target = new THREE.Object3D();

	this.distance = ( distance !== undefined ) ? distance : 0;
	this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
	this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
	this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.

	this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 0.5, 500 ) );

};

THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
THREE.SpotLight.prototype.constructor = THREE.SpotLight;

Object.defineProperty(THREE.SpotLight.prototype, "power", {

  get: function() {

		// intensity = power per solid angle.
		// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
		return this.intensity * 4 * Math.PI;

  },
	set: function( power ) {

		// intensity = power per solid angle.
		// ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
		this.intensity = power / ( 4 * Math.PI );

	}

});

THREE.SpotLight.prototype.copy = function ( source ) {

	THREE.Light.prototype.copy.call( this, source );

	this.distance = source.distance;
	this.angle = source.angle;
	this.penumbra = source.penumbra;
	this.decay = source.decay;

	this.target = source.target.clone();

	this.shadow = source.shadow.clone();

	return this;

};
<commit_msg>adopt convert between power - intensity for SpotLight used by Frostbite 3.<commit_after>/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.SpotLight = function ( color, intensity, distance, angle, penumbra, decay ) {

	THREE.Light.call( this, color, intensity );

	this.type = 'SpotLight';

	this.position.set( 0, 1, 0 );
	this.updateMatrix();

	this.target = new THREE.Object3D();

	this.distance = ( distance !== undefined ) ? distance : 0;
	this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
	this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
	this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.

	this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 0.5, 500 ) );

};

THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
THREE.SpotLight.prototype.constructor = THREE.SpotLight;

Object.defineProperty(THREE.SpotLight.prototype, "power", {

  get: function() {

		// intensity = power per solid angle.
		// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
		return this.intensity * Math.PI;

  },
	set: function( power ) {

		// intensity = power per solid angle.
		// ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf
		this.intensity = power / Math.PI;

	}

});

THREE.SpotLight.prototype.copy = function ( source ) {

	THREE.Light.prototype.copy.call( this, source );

	this.distance = source.distance;
	this.angle = source.angle;
	this.penumbra = source.penumbra;
	this.decay = source.decay;

	this.target = source.target.clone();

	this.shadow = source.shadow.clone();

	return this;

};
<|endoftext|>


<commit_before>var id;
var callbacks = {};

window.attachEventListener = function(obj, type, func, capture) {
  if(!!obj.addEventListener) {
    obj.addEventListener(type, func, capture);
  }
  else if(!!obj.attachEvent) {
    obj.attachEvent("on" + type, func);
  }
};

var Intents = new (function() {

  this.getAllActions = function () {
    var actions = [];
    for(var key in localStorage) {
      var action = JSON.parse(localStorage[key]);

      if(action instanceof Array) {
        actions.push({ key: key, actions: action });
      }
    }

    return actions;
  };

  this.getActions = function(intent) {
    if(!!intent == false) throw "No intent";
    if(!!intent.action == false) throw "No action to resolve";

    var actionData = localStorage[intent.action] || "[]";
    var actions = JSON.parse(actionData);
    var action;
    var filteredActions = [];
    // Find the actions that are of the correct type (or not).  Does not handle *, yet
    for(var i = 0; action = actions[i]; i++) {
      if(intent.type == action.type || !!intent.type == false) {
        filteredActions.push(action);
      }
    }

    return filteredActions;
  };

  this.addAction = function(intent) {
    if(!!intent == false) throw "No intent";
    if(!!intent.action == false) throw "No action to resolve";

    var actionData = localStorage[intent.action] || "[]";
    var actions = JSON.parse(actionData);
    var action;
    var found = false;

    // Replace an existing action.
    for(var i = 0; action = actions[i]; i++) {
      if(intent.action == action.action && intent.url == action.url && intent.type == action.type) {
        actions[i] = intent;
        found = true;
        break;
      }
    }
    // Add a new action
    if(found == false) {
      actions.push(intent);
    }

    localStorage[intent.action] = JSON.stringify(actions);
  };
})();

var MessageDispatcher = function() {

  this.register = function(data, timestamp, e) {
    Intents.addAction(data.intent);
  };

  this.startActivity = function(data, timestamp, e) {
    var actions = Intents.getActions(data.intent);

    var intentData = {
      id: data.intent._id,
      intent: data.intent,
      timestamp: timestamp
    };

    localStorage[data.intent._id] = JSON.stringify(intentData);
    IntentController.renderActions(actions, data.intent);
  };

  this.registerCallback = function(data, timestamp, e) {
    callbacks[data.id] = {};

    if(!!window.onstorage == false) {
      // We are going to have to set up something that polls.
      var timer = setInterval(function() {
        var intentStr = localStorage[data.id];
        if(!!intentStr) {
          var intentObj = JSON.parse(intentStr);
          if(intentObj.request == "sendResponse") {
            window.postMessage(intentStr, "*");
            clearInterval(timer);
          }
        }
      },1000);
    }
  };

  /*
   * The service has sent a response, route it back to the correct frame.
   */
  this.intentResponse = function(data, timestamp, e) {
    var id = data.intent._id;
    var intentData = {
      "request": "sendResponse",
      intent: data.intent,
      timestamp: timestamp
    };
    localStorage[id] = JSON.stringify(intentData);
  };

  /*
   * The correct frame has recieved the reposen, route it back to the parent app.
   */
  this.sendResponse = function(data, timestamp, e) {
    var vals = localStorage[e.key];
    var data = JSON.parse(vals);
    localStorage.removeItem[data.intent._id];
    var message = JSON.stringify({ intent: data.intent, request: "response" });
    window.parent.postMessage(
      message,
      "*"
    );
  };
};

var MessageHandler = function() {
  var dispatcher = new MessageDispatcher();
  this.handler = function(e) {
    var data;
    if(!!e.data) {
      data = JSON.parse(e.data);
    }
    else {
      var vals = localStorage[e.key];
      try {
        data = JSON.parse(vals);
      } catch(ex) {
        return;
      }
    }

    if(data.origin && data.origin !== window.name ||
       data.process && data.process == false) {
      // If there is an intended origin, then enforce it, or the system says not to listen to the event.
      return;
    }

    var timestamp = (new Date()).valueOf();

    if(dispatcher[data.request])
      dispatcher[data.request](data, timestamp, e);
  };
}

var msgHandler = new MessageHandler();;

attachEventListener(window, "message", msgHandler.handler, false);
attachEventListener(window, "storage", msgHandler.handler, false);
attachEventListener(document, "storage", msgHandler.handler, false);

if(!!window.onstorage) {
  // we don't have storage events, so lets poll.

}
<commit_msg>#34 - tidying up for IE support<commit_after>var id;
var callbacks = {};

window.attachEventListener = function(obj, type, func, capture) {
  if(!!obj.addEventListener) {
    obj.addEventListener(type, func, capture);
  }
  else if(!!obj.attachEvent) {
    obj.attachEvent("on" + type, func);
  }
};

var Intents = new (function() {

  this.getAllActions = function () {
    var actions = [];
    for(var key in localStorage) {
      var action = JSON.parse(localStorage[key]);

      if(action instanceof Array) {
        actions.push({ key: key, actions: action });
      }
    }

    return actions;
  };

  this.getActions = function(intent) {
    if(!!intent == false) throw "No intent";
    if(!!intent.action == false) throw "No action to resolve";

    var actionData = localStorage[intent.action] || "[]";
    var actions = JSON.parse(actionData);
    var action;
    var filteredActions = [];
    // Find the actions that are of the correct type (or not).  Does not handle *, yet
    for(var i = 0; action = actions[i]; i++) {
      if(intent.type == action.type || !!intent.type == false) {
        filteredActions.push(action);
      }
    }

    return filteredActions;
  };

  this.addAction = function(intent) {
    if(!!intent == false) throw "No intent";
    if(!!intent.action == false) throw "No action to resolve";

    var actionData = localStorage[intent.action] || "[]";
    var actions = JSON.parse(actionData);
    var action;
    var found = false;

    // Replace an existing action.
    for(var i = 0; action = actions[i]; i++) {
      if(intent.action == action.action && intent.url == action.url && intent.type == action.type) {
        actions[i] = intent;
        found = true;
        break;
      }
    }
    // Add a new action
    if(found == false) {
      actions.push(intent);
    }

    localStorage[intent.action] = JSON.stringify(actions);
  };
})();

var MessageDispatcher = function() {

  this.register = function(data, timestamp, e) {
    Intents.addAction(data.intent);
  };

  this.startActivity = function(data, timestamp, e) {
    var actions = Intents.getActions(data.intent);

    var intentData = {
      id: data.intent._id,
      intent: data.intent,
      timestamp: timestamp
    };

    localStorage[data.intent._id] = JSON.stringify(intentData);
    IntentController.renderActions(actions, data.intent);
  };

  this.registerCallback = function(data, timestamp, e) {
    callbacks[data.id] = {};

    if(!!window.onstorage == false) {
      // We are going to have to set up something that polls.
      var timer = setInterval(function() {
        var intentStr = localStorage.getItem(data.id);
        if(!!intentStr) {
          var intentObj = JSON.parse(intentStr);
          if(intentObj.request == "sendResponse") {
            window.postMessage(intentStr, "*");
            clearInterval(timer);
          }
        }
      },1000);
    }
  };

  /*
   * The service has sent a response, route it back to the correct frame.
   */
  this.intentResponse = function(data, timestamp, e) {
    var id = data.intent._id;
    var intentData = {
      "request": "sendResponse",
      intent: data.intent,
      timestamp: timestamp
    };
    localStorage[id] = JSON.stringify(intentData);
  };

  /*
   * The correct frame has recieved the reposen, route it back to the parent app.
   */
  this.sendResponse = function(data, timestamp, e) {
    var vals = localStorage[e.key];
    var data = JSON.parse(vals);
    localStorage.removeItem[data.intent._id];
    var message = JSON.stringify({ intent: data.intent, request: "response" });
    window.parent.postMessage(
      message,
      "*"
    );
  };
};

var MessageHandler = function() {
  var dispatcher = new MessageDispatcher();
  this.handler = function(e) {
    var data;
    if(!!e.data) {
      data = JSON.parse(e.data);
    }
    else {
      var vals = localStorage[e.key];
      try {
        data = JSON.parse(vals);
      } catch(ex) {
        return;
      }
    }

    if(data.origin && data.origin !== window.name ||
       data.process && data.process == false) {
      // If there is an intended origin, then enforce it, or the system says not to listen to the event.
      return;
    }

    var timestamp = (new Date()).valueOf();

    if(dispatcher[data.request])
      dispatcher[data.request](data, timestamp, e);
  };
}

var msgHandler = new MessageHandler();;

attachEventListener(window, "message", msgHandler.handler, false);
attachEventListener(window, "storage", msgHandler.handler, false);
attachEventListener(document, "storage", msgHandler.handler, false);

if(!!window.onstorage) {
  // we don't have storage events, so lets poll.

}
<|endoftext|>


<commit_before>var aws4 = exports,
    url = require('url'),
    querystring = require('querystring'),
    crypto = require('crypto'),
    lru = require('./lru'),
    credentialsCache = lru(1000)

// http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html

function hmac(key, string, encoding) {
  return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding)
}

function hash(string, encoding) {
  return crypto.createHash('sha256').update(string, 'utf8').digest(encoding)
}

// This function assumes the string has already been percent encoded
function encodeRfc3986(urlEncodedString) {
  return urlEncodedString.replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16).toUpperCase()
  })
}

// request: { path | body, [host], [method], [headers], [service], [region] }
// credentials: { accessKeyId, secretAccessKey, [sessionToken] }
function RequestSigner(request, credentials) {

  if (typeof request === 'string') request = url.parse(request)

  var headers = request.headers = (request.headers || {}),
      hostParts = this.matchHost(request.hostname || request.host || headers.Host || headers.host)

  this.request = request
  this.credentials = credentials || this.defaultCredentials()

  this.service = request.service || hostParts[0] || ''
  this.region = request.region || hostParts[1] || 'us-east-1'

  // SES uses a different domain from the service name
  if (this.service === 'email') this.service = 'ses'

  if (!request.method && request.body)
    request.method = 'POST'

  if (!headers.Host && !headers.host) {
    headers.Host = request.hostname || request.host || this.createHost()

    // If a port is specified explicitly, use it as is
    if (request.port)
      headers.Host += ':' + request.port
  }
  if (!request.hostname && !request.host)
    request.hostname = headers.Host || headers.host

  this.isCodeCommitGit = this.service === 'codecommit' && request.method === 'GIT'
}

RequestSigner.prototype.matchHost = function(host) {
  var match = (host || '').match(/([^\.]+)\.(?:([^\.]*)\.)?amazonaws\.com$/)
  var hostParts = (match || []).slice(1, 3)

  // ES's hostParts are sometimes the other way round, if the value that is expected
  // to be region equals ‘es’ switch them back
  // e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com
  if (hostParts[1] === 'es')
    hostParts = hostParts.reverse()

  return hostParts
}

// http://docs.aws.amazon.com/general/latest/gr/rande.html
RequestSigner.prototype.isSingleRegion = function() {
  // Special case for S3 and SimpleDB in us-east-1
  if (['s3', 'sdb'].indexOf(this.service) >= 0 && this.region === 'us-east-1') return true

  return ['cloudfront', 'ls', 'route53', 'iam', 'importexport', 'sts']
    .indexOf(this.service) >= 0
}

RequestSigner.prototype.createHost = function() {
  var region = this.isSingleRegion() ? '' :
        (this.service === 's3' && this.region !== 'us-east-1' ? '-' : '.') + this.region,
      service = this.service === 'ses' ? 'email' : this.service
  return service + region + '.amazonaws.com'
}

RequestSigner.prototype.prepareRequest = function() {
  this.parsePath()

  var request = this.request, headers = request.headers, query

  if (request.signQuery) {

    this.parsedPath.query = query = this.parsedPath.query || {}

    if (this.credentials.sessionToken)
      query['X-Amz-Security-Token'] = this.credentials.sessionToken

    if (this.service === 's3' && !query['X-Amz-Expires'])
      query['X-Amz-Expires'] = 86400

    if (query['X-Amz-Date'])
      this.datetime = query['X-Amz-Date']
    else
      query['X-Amz-Date'] = this.getDateTime()

    query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256'
    query['X-Amz-Credential'] = this.credentials.accessKeyId + '/' + this.credentialString()
    query['X-Amz-SignedHeaders'] = this.signedHeaders()

  } else {

    if (!request.doNotModifyHeaders && !this.isCodeCommitGit) {
      if (request.body && !headers['Content-Type'] && !headers['content-type'])
        headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'

      if (request.body && !headers['Content-Length'] && !headers['content-length'])
        headers['Content-Length'] = Buffer.byteLength(request.body)

      if (this.credentials.sessionToken && !headers['X-Amz-Security-Token'] && !headers['x-amz-security-token'])
        headers['X-Amz-Security-Token'] = this.credentials.sessionToken

      if (this.service === 's3' && !headers['X-Amz-Content-Sha256'] && !headers['x-amz-content-sha256'])
        headers['X-Amz-Content-Sha256'] = hash(this.request.body || '', 'hex')

      if (headers['X-Amz-Date'] || headers['x-amz-date'])
        this.datetime = headers['X-Amz-Date'] || headers['x-amz-date']
      else
        headers['X-Amz-Date'] = this.getDateTime()
    }

    delete headers.Authorization
    delete headers.authorization
  }
}

RequestSigner.prototype.sign = function() {
  if (!this.parsedPath) this.prepareRequest()

  if (this.request.signQuery) {
    this.parsedPath.query['X-Amz-Signature'] = this.signature()
  } else {
    this.request.headers.Authorization = this.authHeader()
  }

  this.request.path = this.formatPath()

  return this.request
}

RequestSigner.prototype.getDateTime = function() {
  if (!this.datetime) {
    var headers = this.request.headers,
      date = new Date(headers.Date || headers.date || new Date)

    this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '')

    // Remove the trailing 'Z' on the timestamp string for CodeCommit git access
    if (this.isCodeCommitGit) this.datetime = this.datetime.slice(0, -1)
  }
  return this.datetime
}

RequestSigner.prototype.getDate = function() {
  return this.getDateTime().substr(0, 8)
}

RequestSigner.prototype.authHeader = function() {
  return [
    'AWS4-HMAC-SHA256 Credential=' + this.credentials.accessKeyId + '/' + this.credentialString(),
    'SignedHeaders=' + this.signedHeaders(),
    'Signature=' + this.signature(),
  ].join(', ')
}

RequestSigner.prototype.signature = function() {
  var date = this.getDate(),
      cacheKey = [this.credentials.secretAccessKey, date, this.region, this.service].join(),
      kDate, kRegion, kService, kCredentials = credentialsCache.get(cacheKey)
  if (!kCredentials) {
    kDate = hmac('AWS4' + this.credentials.secretAccessKey, date)
    kRegion = hmac(kDate, this.region)
    kService = hmac(kRegion, this.service)
    kCredentials = hmac(kService, 'aws4_request')
    credentialsCache.set(cacheKey, kCredentials)
  }
  return hmac(kCredentials, this.stringToSign(), 'hex')
}

RequestSigner.prototype.stringToSign = function() {
  return [
    'AWS4-HMAC-SHA256',
    this.getDateTime(),
    this.credentialString(),
    hash(this.canonicalString(), 'hex'),
  ].join('\n')
}

RequestSigner.prototype.canonicalString = function() {
  if (!this.parsedPath) this.prepareRequest()

  var pathStr = this.parsedPath.path,
      query = this.parsedPath.query,
      headers = this.request.headers,
      queryStr = '',
      normalizePath = this.service !== 's3',
      decodePath = this.service === 's3' || this.request.doNotEncodePath,
      decodeSlashesInPath = this.service === 's3',
      firstValOnly = this.service === 's3',
      bodyHash

  if (this.service === 's3' && this.request.signQuery) {
    bodyHash = 'UNSIGNED-PAYLOAD'
  } else if (this.isCodeCommitGit) {
    bodyHash = ''
  } else {
    bodyHash = headers['X-Amz-Content-Sha256'] || headers['x-amz-content-sha256'] ||
      hash(this.request.body || '', 'hex')
  }

  if (query) {
    queryStr = encodeRfc3986(querystring.stringify(Object.keys(query).sort().reduce(function(obj, key) {
      if (!key) return obj
      obj[key] = !Array.isArray(query[key]) ? query[key] :
        (firstValOnly ? query[key][0] : query[key].slice().sort())
      return obj
    }, {})))
  }
  if (pathStr !== '/') {
    if (normalizePath) pathStr = pathStr.replace(/\/{2,}/g, '/')
    pathStr = pathStr.split('/').reduce(function(path, piece) {
      if (normalizePath && piece === '..') {
        path.pop()
      } else if (!normalizePath || piece !== '.') {
        if (decodePath) piece = decodeURIComponent(piece)
        path.push(encodeRfc3986(encodeURIComponent(piece)))
      }
      return path
    }, []).join('/')
    if (pathStr[0] !== '/') pathStr = '/' + pathStr
    if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, '/')
  }

  return [
    this.request.method || 'GET',
    pathStr,
    queryStr,
    this.canonicalHeaders() + '\n',
    this.signedHeaders(),
    bodyHash,
  ].join('\n')
}

RequestSigner.prototype.canonicalHeaders = function() {
  var headers = this.request.headers
  function trimAll(header) {
    return header.toString().trim().replace(/\s+/g, ' ')
  }
  return Object.keys(headers)
    .sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 })
    .map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) })
    .join('\n')
}

RequestSigner.prototype.signedHeaders = function() {
  return Object.keys(this.request.headers)
    .map(function(key) { return key.toLowerCase() })
    .sort()
    .join(';')
}

RequestSigner.prototype.credentialString = function() {
  return [
    this.getDate(),
    this.region,
    this.service,
    'aws4_request',
  ].join('/')
}

RequestSigner.prototype.defaultCredentials = function() {
  var env = process.env
  return {
    accessKeyId: env.AWS_ACCESS_KEY_ID || env.AWS_ACCESS_KEY,
    secretAccessKey: env.AWS_SECRET_ACCESS_KEY || env.AWS_SECRET_KEY,
    sessionToken: env.AWS_SESSION_TOKEN,
  }
}

RequestSigner.prototype.parsePath = function() {
  var path = this.request.path || '/',
      queryIx = path.indexOf('?'),
      query = null

  if (queryIx >= 0) {
    query = querystring.parse(path.slice(queryIx + 1))
    path = path.slice(0, queryIx)
  }

  // S3 doesn't always encode characters > 127 correctly and
  // all services don't encode characters > 255 correctly
  // So if there are non-reserved chars (and it's not already all % encoded), just encode them all
  if (/[^0-9A-Za-z!'()*\-._~%/]/.test(path)) {
    path = path.split('/').map(function(piece) {
      return encodeURIComponent(decodeURIComponent(piece))
    }).join('/')
  }

  this.parsedPath = {
    path: path,
    query: query,
  }
}

RequestSigner.prototype.formatPath = function() {
  var path = this.parsedPath.path,
      query = this.parsedPath.query

  if (!query) return path

  // Services don't support empty query string keys
  if (query[''] != null) delete query['']

  return path + '?' + encodeRfc3986(querystring.stringify(query))
}

aws4.RequestSigner = RequestSigner

aws4.sign = function(request, credentials) {
  return new RequestSigner(request, credentials).sign()
}
<commit_msg>update host regex to include optional cn group <commit_after>var aws4 = exports,
    url = require('url'),
    querystring = require('querystring'),
    crypto = require('crypto'),
    lru = require('./lru'),
    credentialsCache = lru(1000)

// http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html

function hmac(key, string, encoding) {
  return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding)
}

function hash(string, encoding) {
  return crypto.createHash('sha256').update(string, 'utf8').digest(encoding)
}

// This function assumes the string has already been percent encoded
function encodeRfc3986(urlEncodedString) {
  return urlEncodedString.replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16).toUpperCase()
  })
}

// request: { path | body, [host], [method], [headers], [service], [region] }
// credentials: { accessKeyId, secretAccessKey, [sessionToken] }
function RequestSigner(request, credentials) {

  if (typeof request === 'string') request = url.parse(request)

  var headers = request.headers = (request.headers || {}),
      hostParts = this.matchHost(request.hostname || request.host || headers.Host || headers.host)

  this.request = request
  this.credentials = credentials || this.defaultCredentials()

  this.service = request.service || hostParts[0] || ''
  this.region = request.region || hostParts[1] || 'us-east-1'

  // SES uses a different domain from the service name
  if (this.service === 'email') this.service = 'ses'

  if (!request.method && request.body)
    request.method = 'POST'

  if (!headers.Host && !headers.host) {
    headers.Host = request.hostname || request.host || this.createHost()

    // If a port is specified explicitly, use it as is
    if (request.port)
      headers.Host += ':' + request.port
  }
  if (!request.hostname && !request.host)
    request.hostname = headers.Host || headers.host

  this.isCodeCommitGit = this.service === 'codecommit' && request.method === 'GIT'
}

RequestSigner.prototype.matchHost = function(host) {
  var match = (host || '').match(/([^\.]+)\.(?:([^\.]*)\.)?amazonaws\.com(\.cn)*$/)
  var hostParts = (match || []).slice(1, 3)

  // ES's hostParts are sometimes the other way round, if the value that is expected
  // to be region equals ‘es’ switch them back
  // e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com
  if (hostParts[1] === 'es')
    hostParts = hostParts.reverse()

  return hostParts
}

// http://docs.aws.amazon.com/general/latest/gr/rande.html
RequestSigner.prototype.isSingleRegion = function() {
  // Special case for S3 and SimpleDB in us-east-1
  if (['s3', 'sdb'].indexOf(this.service) >= 0 && this.region === 'us-east-1') return true

  return ['cloudfront', 'ls', 'route53', 'iam', 'importexport', 'sts']
    .indexOf(this.service) >= 0
}

RequestSigner.prototype.createHost = function() {
  var region = this.isSingleRegion() ? '' :
        (this.service === 's3' && this.region !== 'us-east-1' ? '-' : '.') + this.region,
      service = this.service === 'ses' ? 'email' : this.service
  return service + region + '.amazonaws.com'
}

RequestSigner.prototype.prepareRequest = function() {
  this.parsePath()

  var request = this.request, headers = request.headers, query

  if (request.signQuery) {

    this.parsedPath.query = query = this.parsedPath.query || {}

    if (this.credentials.sessionToken)
      query['X-Amz-Security-Token'] = this.credentials.sessionToken

    if (this.service === 's3' && !query['X-Amz-Expires'])
      query['X-Amz-Expires'] = 86400

    if (query['X-Amz-Date'])
      this.datetime = query['X-Amz-Date']
    else
      query['X-Amz-Date'] = this.getDateTime()

    query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256'
    query['X-Amz-Credential'] = this.credentials.accessKeyId + '/' + this.credentialString()
    query['X-Amz-SignedHeaders'] = this.signedHeaders()

  } else {

    if (!request.doNotModifyHeaders && !this.isCodeCommitGit) {
      if (request.body && !headers['Content-Type'] && !headers['content-type'])
        headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'

      if (request.body && !headers['Content-Length'] && !headers['content-length'])
        headers['Content-Length'] = Buffer.byteLength(request.body)

      if (this.credentials.sessionToken && !headers['X-Amz-Security-Token'] && !headers['x-amz-security-token'])
        headers['X-Amz-Security-Token'] = this.credentials.sessionToken

      if (this.service === 's3' && !headers['X-Amz-Content-Sha256'] && !headers['x-amz-content-sha256'])
        headers['X-Amz-Content-Sha256'] = hash(this.request.body || '', 'hex')

      if (headers['X-Amz-Date'] || headers['x-amz-date'])
        this.datetime = headers['X-Amz-Date'] || headers['x-amz-date']
      else
        headers['X-Amz-Date'] = this.getDateTime()
    }

    delete headers.Authorization
    delete headers.authorization
  }
}

RequestSigner.prototype.sign = function() {
  if (!this.parsedPath) this.prepareRequest()

  if (this.request.signQuery) {
    this.parsedPath.query['X-Amz-Signature'] = this.signature()
  } else {
    this.request.headers.Authorization = this.authHeader()
  }

  this.request.path = this.formatPath()

  return this.request
}

RequestSigner.prototype.getDateTime = function() {
  if (!this.datetime) {
    var headers = this.request.headers,
      date = new Date(headers.Date || headers.date || new Date)

    this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '')

    // Remove the trailing 'Z' on the timestamp string for CodeCommit git access
    if (this.isCodeCommitGit) this.datetime = this.datetime.slice(0, -1)
  }
  return this.datetime
}

RequestSigner.prototype.getDate = function() {
  return this.getDateTime().substr(0, 8)
}

RequestSigner.prototype.authHeader = function() {
  return [
    'AWS4-HMAC-SHA256 Credential=' + this.credentials.accessKeyId + '/' + this.credentialString(),
    'SignedHeaders=' + this.signedHeaders(),
    'Signature=' + this.signature(),
  ].join(', ')
}

RequestSigner.prototype.signature = function() {
  var date = this.getDate(),
      cacheKey = [this.credentials.secretAccessKey, date, this.region, this.service].join(),
      kDate, kRegion, kService, kCredentials = credentialsCache.get(cacheKey)
  if (!kCredentials) {
    kDate = hmac('AWS4' + this.credentials.secretAccessKey, date)
    kRegion = hmac(kDate, this.region)
    kService = hmac(kRegion, this.service)
    kCredentials = hmac(kService, 'aws4_request')
    credentialsCache.set(cacheKey, kCredentials)
  }
  return hmac(kCredentials, this.stringToSign(), 'hex')
}

RequestSigner.prototype.stringToSign = function() {
  return [
    'AWS4-HMAC-SHA256',
    this.getDateTime(),
    this.credentialString(),
    hash(this.canonicalString(), 'hex'),
  ].join('\n')
}

RequestSigner.prototype.canonicalString = function() {
  if (!this.parsedPath) this.prepareRequest()

  var pathStr = this.parsedPath.path,
      query = this.parsedPath.query,
      headers = this.request.headers,
      queryStr = '',
      normalizePath = this.service !== 's3',
      decodePath = this.service === 's3' || this.request.doNotEncodePath,
      decodeSlashesInPath = this.service === 's3',
      firstValOnly = this.service === 's3',
      bodyHash

  if (this.service === 's3' && this.request.signQuery) {
    bodyHash = 'UNSIGNED-PAYLOAD'
  } else if (this.isCodeCommitGit) {
    bodyHash = ''
  } else {
    bodyHash = headers['X-Amz-Content-Sha256'] || headers['x-amz-content-sha256'] ||
      hash(this.request.body || '', 'hex')
  }

  if (query) {
    queryStr = encodeRfc3986(querystring.stringify(Object.keys(query).sort().reduce(function(obj, key) {
      if (!key) return obj
      obj[key] = !Array.isArray(query[key]) ? query[key] :
        (firstValOnly ? query[key][0] : query[key].slice().sort())
      return obj
    }, {})))
  }
  if (pathStr !== '/') {
    if (normalizePath) pathStr = pathStr.replace(/\/{2,}/g, '/')
    pathStr = pathStr.split('/').reduce(function(path, piece) {
      if (normalizePath && piece === '..') {
        path.pop()
      } else if (!normalizePath || piece !== '.') {
        if (decodePath) piece = decodeURIComponent(piece)
        path.push(encodeRfc3986(encodeURIComponent(piece)))
      }
      return path
    }, []).join('/')
    if (pathStr[0] !== '/') pathStr = '/' + pathStr
    if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, '/')
  }

  return [
    this.request.method || 'GET',
    pathStr,
    queryStr,
    this.canonicalHeaders() + '\n',
    this.signedHeaders(),
    bodyHash,
  ].join('\n')
}

RequestSigner.prototype.canonicalHeaders = function() {
  var headers = this.request.headers
  function trimAll(header) {
    return header.toString().trim().replace(/\s+/g, ' ')
  }
  return Object.keys(headers)
    .sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 })
    .map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) })
    .join('\n')
}

RequestSigner.prototype.signedHeaders = function() {
  return Object.keys(this.request.headers)
    .map(function(key) { return key.toLowerCase() })
    .sort()
    .join(';')
}

RequestSigner.prototype.credentialString = function() {
  return [
    this.getDate(),
    this.region,
    this.service,
    'aws4_request',
  ].join('/')
}

RequestSigner.prototype.defaultCredentials = function() {
  var env = process.env
  return {
    accessKeyId: env.AWS_ACCESS_KEY_ID || env.AWS_ACCESS_KEY,
    secretAccessKey: env.AWS_SECRET_ACCESS_KEY || env.AWS_SECRET_KEY,
    sessionToken: env.AWS_SESSION_TOKEN,
  }
}

RequestSigner.prototype.parsePath = function() {
  var path = this.request.path || '/',
      queryIx = path.indexOf('?'),
      query = null

  if (queryIx >= 0) {
    query = querystring.parse(path.slice(queryIx + 1))
    path = path.slice(0, queryIx)
  }

  // S3 doesn't always encode characters > 127 correctly and
  // all services don't encode characters > 255 correctly
  // So if there are non-reserved chars (and it's not already all % encoded), just encode them all
  if (/[^0-9A-Za-z!'()*\-._~%/]/.test(path)) {
    path = path.split('/').map(function(piece) {
      return encodeURIComponent(decodeURIComponent(piece))
    }).join('/')
  }

  this.parsedPath = {
    path: path,
    query: query,
  }
}

RequestSigner.prototype.formatPath = function() {
  var path = this.parsedPath.path,
      query = this.parsedPath.query

  if (!query) return path

  // Services don't support empty query string keys
  if (query[''] != null) delete query['']

  return path + '?' + encodeRfc3986(querystring.stringify(query))
}

aws4.RequestSigner = RequestSigner

aws4.sign = function(request, credentials) {
  return new RequestSigner(request, credentials).sign()
}
<|endoftext|>


<commit_before>import {
    createStore as createReduxStore,
    combineReducers,
    applyMiddleware
} from 'redux';

/**
 * Middlewares
 */
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';

/**
 * Libs
 */
import groupBy from 'lodash/groupBy';
import map from 'lodash/map';

import * as reducers from './store-reducers';
import * as actions from './store-actions';

const middlewares = [];
middlewares.push(thunkMiddleware);
if (process.env.NODE_ENV === 'development')
    middlewares.push(createLogger());

const createStoreWithMiddleware = applyMiddleware.apply(
    undefined,
    middlewares
)(createReduxStore);

const finalReducer = combineReducers(reducers);

export function createStore(urls, state) {
    const store = createStoreWithMiddleware(finalReducer, {...state, urls})
    window.addEventListener('popstate', () => handlePopState(store.dispatch, store.getState));
    return store;
};

function containsText(string, search) {
    return string.toLowerCase().indexOf(search.toLowerCase()) !== -1;
}

function settingMatches(setting, search) {
    return [setting.name, setting.description].some(s => containsText(s, search));
}

function getGroupName(setting) {
    return setting.name.replace(/^([^\.]+)\..+$/, '$1');
}

export function getVisibleSettings(settings, search) {
    return settings
    .filter(setting => settingMatches(setting, search))
    .map((setting, index) => ({setting, index}))
    ;
};

export function getGroups (settings) {
    const groups = groupBy(settings, s => getGroupName(s.setting));
    return map(groups, (settings, name) => ({ name, settings}));
};

<commit_msg>fix incorrect import in store.js<commit_after>import {
    createStore as createReduxStore,
    combineReducers,
    applyMiddleware
} from 'redux';

/**
 * Middlewares
 */
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';

/**
 * Libs
 */
import groupBy from 'lodash/groupBy';
import map from 'lodash/map';

import * as reducers from './store-reducers';
import { handlePopState } from './store-actions';

const middlewares = [];
middlewares.push(thunkMiddleware);
if (process.env.NODE_ENV === 'development')
    middlewares.push(createLogger());

const createStoreWithMiddleware = applyMiddleware.apply(
    undefined,
    middlewares
)(createReduxStore);

const finalReducer = combineReducers(reducers);

export function createStore(urls, state) {
    const store = createStoreWithMiddleware(finalReducer, {...state, urls})
    window.addEventListener('popstate', () => handlePopState(store.dispatch, store.getState));
    return store;
};

function containsText(string, search) {
    return string.toLowerCase().indexOf(search.toLowerCase()) !== -1;
}

function settingMatches(setting, search) {
    return [setting.name, setting.description].some(s => containsText(s, search));
}

function getGroupName(setting) {
    return setting.name.replace(/^([^\.]+)\..+$/, '$1');
}

export function getVisibleSettings(settings, search) {
    return settings
    .filter(setting => settingMatches(setting, search))
    .map((setting, index) => ({setting, index}))
    ;
};

export function getGroups (settings) {
    const groups = groupBy(settings, s => getGroupName(s.setting));
    return map(groups, (settings, name) => ({ name, settings}));
};

<|endoftext|>