<commit_before>/**
 * BMotionWeb Session Module
 *
 */
define([
  'angular',
  'bms.func',
  'bms.ws',
  'bms.manifest',
  'bms.visualization'
], function(angular, bms) {

  return angular.module('bms.session', ['bms.ws', 'bms.manifest', 'bms.visualization'])
    .factory('bmsSession', ['$q', 'bmsWsService', 'bmsManifestService', 'bmsVisualization',
      function($q, bmsWsService, bmsManifestService, bmsVisualization) {

        var bmsSession = function(sessionId) {
          this.id = sessionId;
          this.manifestFilePath = undefined;
          this.manifestData = {};
          this.initialized = $q.defer();
          this.templateFolder = undefined;
          this.modelPath = undefined;
          this.toolData = {};
          this.views = {};
        };

        bmsSession.prototype.getId = function() {
          return this.id;
        };

        bmsSession.prototype.getModelPath = function() {
          return this.modelPath;
        };

        bmsSession.prototype.getTemplateFolder = function(manifestFilePath) {
          //TODO check if manifestFilePath is undefined
          var filename = manifestFilePath.replace(/^.*[\\\/]/, '');
          var folder = manifestFilePath.replace('/' + filename, '');
          return folder;
        };

        bmsSession.prototype.getSvgData = function() {
          var self = this;
          var svgData = [];
          angular.forEach(this.views, function(view) {
            for (svg in view.svg) {
              svgData.push({
                file: svg,
                viewId: view.viewData.id,
                id: view.id
              });
            }
          });
          return svgData;
        };

        bmsSession.prototype.init = function(manifestFilePath) {

          var defer = $q.defer();

          var self = this;

          if (!manifestFilePath) {
            defer.reject("Manifest file path must not be undefined.");
          } else {
            bmsManifestService.getManifest(manifestFilePath)
              .then(function(manifestData) {

                var templateFolder = self.getTemplateFolder(manifestFilePath);
                var modelPath = templateFolder + '/' + manifestData.model;

                bmsWsService.initSession(self.id, manifestFilePath, modelPath, manifestData.modelOptions)
                  .then(function(sessionData) {

                    self.tool = sessionData[0].tool;
                    self.toolData = sessionData[1];
                    self.manifestFilePath = manifestFilePath;
                    self.manifestData = manifestData;
                    self.templateFolder = templateFolder;
                    self.modelPath = modelPath;
                    defer.resolve(self);
                    self.initialized.resolve(self);

                  }, function(err) {
                    defer.reject(err);
                  });
              }, function(err) {
                defer.reject(err);
              });
          }

          return defer.promise;

        };

        bmsSession.prototype.load = function() {

          var defer = $q.defer();
          var self = this;
          self.initialized = $q.defer();

          bmsWsService.loadSession(self.id)
            .then(function(sessionData) {

              self.tool = sessionData[0].tool;
              self.toolData = sessionData[1];
              self.manifestFilePath = sessionData[0].manifestFilePath;
              self.templateFolder = self.getTemplateFolder(self.manifestFilePath);

              bmsManifestService.getManifest(self.manifestFilePath)
                .then(function(manifestData) {
                  self.manifestData = manifestData;
                  self.modelPath = self.templateFolder + '/' + self.manifestData.model;
                  defer.resolve(self);
                  self.initialized.resolve(self);
                });

            }, function(err) {
              defer.reject(err);
            });

          return defer.promise;

        };

        bmsSession.prototype.destroy = function() {
          return bmsWsService.destroySession(self.id);
        };

        bmsSession.prototype.isInitialized = function() {
          return this.initialized.promise;
        };

        bmsSession.prototype.isClassicalBVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'ClassicalBVisualization';
          }
        };

        bmsSession.prototype.isEventBVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'EventBVisualization';
          }
        };

        bmsSession.prototype.isBVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'EventBVisualization' || this.tool === 'ClassicalBVisualization';
          }
        };

        bmsSession.prototype.isCSPVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'CSPVisualisation';
          }
        };

        bmsSession.prototype.getView = function(viewId) {
          // If id is undefined create a new one
          viewId = viewId === undefined ? bms.uuid() : viewId;
          if (this.views[viewId] === undefined) {
            this.views[viewId] = new bmsVisualization(viewId, this);
          }
          return this.views[viewId];
        };

        return bmsSession;

      }
    ])
    .factory('bmsSessionService', ['$q', 'bmsSession', 'bmsManifestService', 'bmsWsService',
      function($q, bmsSession, bmsManifestService, bmsWsService) {

        var sessions = {};

        return {
          getSession: function(_sessionId_) {
            sessionId = _sessionId_ ? _sessionId_ : bms.uuid();
            if (sessions[sessionId] === undefined) {
              sessions[sessionId] = new bmsSession(sessionId);
            }
            return sessions[sessionId];
          }
        };

      }
    ]);

});
<commit_msg>fixed windows path bug<commit_after>/**
 * BMotionWeb Session Module
 *
 */
define([
  'angular',
  'bms.func',
  'bms.ws',
  'bms.manifest',
  'bms.visualization'
], function(angular, bms) {

  return angular.module('bms.session', ['bms.ws', 'bms.manifest', 'bms.visualization'])
    .factory('bmsSession', ['$q', 'bmsWsService', 'bmsManifestService', 'bmsVisualization',
      function($q, bmsWsService, bmsManifestService, bmsVisualization) {

        var bmsSession = function(sessionId) {
          this.id = sessionId;
          this.manifestFilePath = undefined;
          this.manifestData = {};
          this.initialized = $q.defer();
          this.templateFolder = undefined;
          this.modelPath = undefined;
          this.toolData = {};
          this.views = {};
        };

        bmsSession.prototype.getId = function() {
          return this.id;
        };

        bmsSession.prototype.getModelPath = function() {
          return this.modelPath;
        };

        bmsSession.prototype.getTemplateFolder = function(manifestFilePath) {
          //TODO check if manifestFilePath is undefined
          //var filename = manifestFilePath.replace(/^.*[\\\/]/, '');
          return manifestFilePath.replace('bmotion.json', '');
          return folder;
        };

        bmsSession.prototype.getSvgData = function() {
          var self = this;
          var svgData = [];
          angular.forEach(this.views, function(view) {
            for (svg in view.svg) {
              svgData.push({
                file: svg,
                viewId: view.viewData.id,
                id: view.id
              });
            }
          });
          return svgData;
        };

        bmsSession.prototype.init = function(manifestFilePath) {

          var defer = $q.defer();

          var self = this;

          if (!manifestFilePath) {
            defer.reject("Manifest file path must not be undefined.");
          } else {
            bmsManifestService.getManifest(manifestFilePath)
              .then(function(manifestData) {

                var templateFolder = self.getTemplateFolder(manifestFilePath);
                var modelPath = templateFolder + '/' + manifestData.model;

                bmsWsService.initSession(self.id, manifestFilePath, modelPath, manifestData.modelOptions)
                  .then(function(sessionData) {

                    self.tool = sessionData[0].tool;
                    self.toolData = sessionData[1];
                    self.manifestFilePath = manifestFilePath;
                    self.manifestData = manifestData;
                    self.templateFolder = templateFolder;
                    self.modelPath = modelPath;
                    defer.resolve(self);
                    self.initialized.resolve(self);

                  }, function(err) {
                    defer.reject(err);
                  });
              }, function(err) {
                defer.reject(err);
              });
          }

          return defer.promise;

        };

        bmsSession.prototype.load = function() {

          var defer = $q.defer();
          var self = this;
          self.initialized = $q.defer();

          bmsWsService.loadSession(self.id)
            .then(function(sessionData) {

              self.tool = sessionData[0].tool;
              self.toolData = sessionData[1];
              self.manifestFilePath = sessionData[0].manifestFilePath;
              self.templateFolder = self.getTemplateFolder(self.manifestFilePath);

              bmsManifestService.getManifest(self.manifestFilePath)
                .then(function(manifestData) {
                  self.manifestData = manifestData;
                  self.modelPath = self.templateFolder + '/' + self.manifestData.model;
                  defer.resolve(self);
                  self.initialized.resolve(self);
                });

            }, function(err) {
              defer.reject(err);
            });

          return defer.promise;

        };

        bmsSession.prototype.destroy = function() {
          return bmsWsService.destroySession(self.id);
        };

        bmsSession.prototype.isInitialized = function() {
          return this.initialized.promise;
        };

        bmsSession.prototype.isClassicalBVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'ClassicalBVisualization';
          }
        };

        bmsSession.prototype.isEventBVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'EventBVisualization';
          }
        };

        bmsSession.prototype.isBVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'EventBVisualization' || this.tool === 'ClassicalBVisualization';
          }
        };

        bmsSession.prototype.isCSPVisualization = function() {
          if (!this.tool) {
            return false;
          } else {
            return this.tool === 'CSPVisualisation';
          }
        };

        bmsSession.prototype.getView = function(viewId) {
          // If id is undefined create a new one
          viewId = viewId === undefined ? bms.uuid() : viewId;
          if (this.views[viewId] === undefined) {
            this.views[viewId] = new bmsVisualization(viewId, this);
          }
          return this.views[viewId];
        };

        return bmsSession;

      }
    ])
    .factory('bmsSessionService', ['$q', 'bmsSession', 'bmsManifestService', 'bmsWsService',
      function($q, bmsSession, bmsManifestService, bmsWsService) {

        var sessions = {};

        return {
          getSession: function(_sessionId_) {
            sessionId = _sessionId_ ? _sessionId_ : bms.uuid();
            if (sessions[sessionId] === undefined) {
              sessions[sessionId] = new bmsSession(sessionId);
            }
            return sessions[sessionId];
          }
        };

      }
    ]);

});
<|endoftext|>


<commit_before>var config = {
	isCustomConfiguration:false
};

(function(){

// TOD how can we embed this into the synchronous loading process to fill the config??
	//function _findValidAddressBookItemId(callback){
	//	try{
	//		var pim = Widget.PIM;
	//		var addr = new pim.AddressBookItem();
	//		addr.setAttributeValue("fullName", "*");
	//		Widget.PIM.onAddressBookItemsFound = function(items){
	//			if (items.length>0){
	//				callback(items[0].addressBookItemId);
	//			}
	//		}
	//		pim.findAddressBookItems(addr, 0, 1);
	//		delete pim.onAddressBookItemsFound;
	//	}catch(e){
	//		callback(null);
	//	}
	//}

	var defaults = {
		// summary: This configuration defines the features of the phone.
		// description: It maybe used to determine if a test is viable
		// 		and shall be added or not. E.g. if a phone has a certain hardware
		// 		feature or not, like a clamshell.
		hasAccelerometer:true,
		hasClipboard:false,
		hasClamshell:false,
		hasKeypadLight:false,

		supportsOrientationLandscape:true,
		supportsMultipleEmailAccounts:true,
		supportsDeleteEmailAccounts:true,

		unsupportedApis:[],

		// Some devices/platforms don't support certain features and they normally need to return UNSUPPORTED
		// exception, but to run the correct tests (those testing for the exception) we need to configure
		// the platforms. That is done here.
		// The list below ONLY lists those features that need to be turned off for a certain platform
		// if there is one missing add it, by default the features are all expected to be supported (default value is true).
		supports:{
			// On the first the module (=test file) is given.
			Messaging:{
				moveMessage:true, // moveToFolder()
				editFolder:true, // If createFolder(), moveFolder(), deleteFolder() are NOT supported set this to false.
				multipleEmailAccounts:true
			}
		},

		// Set this to true if the device can open multiple applications.
		// E.g. we can only test Widget.onRestore when the device allows to put the
		// application in the background.
		canDoMultitasking:true,

		validAddressBookItemId:"1",
		validCalendarItemId:"1", // The first contact filled in an H2 really has the ID "1".

		// Various file system settings that will be used for testing, etc.
		// NOTE: Paths must always end with the directorySeparator
		// (just to have less hazzle when just adding a filename in the test).
		fileSystem:{
			directorySeparator:"/",

			// A path where we can read a file from, do directory listing or something alike.
			readablePath:"/virtual/photos/",
			// Specify a file name here for a file that is readable.
			// E.g. for testing methods like getFile().
			readableFile:"/virtual/photos/test-photo/test.txt",
			emptyReadableDirectory:"/virtual/photos/test-photo/testdir",

			// Writeable file or path.
			writeablePath:"/virtual/photos/",
			writeableFile:"/virtual/photos/test-photo/test-write.txt",

			// The root path of the widget, where we can e.g. read out all the
			// files provided with the widget (like audio or video files).
			widgetPath:"",
			playableAudioFiles:{
				inWidget:{
					songWav:"test-audio/wav/music.wav",
					songMp3:"test-audio/mp3/music.mp3",
					loopWav:"test-audio/wav/loop.wav",
					loopMp3:"test-audio/mp3/loop.mp3"
				},
				onDevice:{
					songWav:"/virtual/music/test-audio/wav/music.wav",
					songMp3:"/virtual/music/test-audio/mp3/music.mp3",
					loopWav:"/virtual/music/test-audio/wav/loop.wav",
					loopMp3:"/virtual/music/test-audio/mp3/loop.mp3"
				}
			},
			playableVideoFiles:{
				//viaHttp:"http://...",
				//viaHttps:"https://...",
				//viaRtsp:"rtsp://...",
				//viaFile:"file:///", // ??? shall this be the virtual FS or the real FS (=device specific)???
				avc:{
					inWidget:"test-video/avc/AVC_AAC_48K_30F_QVGA.mp4",
					onDevice:"/virtual/videos/test-video/avc/AVC_AAC_48K_30F_QVGA.mp4"
				},
				h263:{
					inWidget:"test-video/h263/H263_148K_QCIF_15_plus_MP4AAC_22_1.3gp",
					onDevice:"/virtual/videos/test-video/h263/H263_148K_QCIF_15_plus_MP4AAC_22_1.3gp"
				},
				h264:{
					inWidget:"test-video/h264/H264_256K_QVGA_15_plus_AAC_22_2.mp4",
					onDevice:"/virtual/videos/test-video/h264/H264_256K_QVGA_15_plus_AAC_22_2.mp4",
					inWidget1:"test-video/h264/HMC_boa_320_240.MP4",
					onDevice1:"/virtual/videos/test-video/h264/HMC_boa_320_240.MP4"
				},
				mp4:{
					inWidget:"test-video/mp4/MP4V_508K_QVGA_15_plus_MP4AAC_32_2.mp4",
					onDevice:"/virtual/videos/test-video/mp4/MP4V_508K_QVGA_15_plus_MP4AAC_32_2.mp4"
				}
			},
			imageFile:""
		},

		events:{
			invalidRecurrenceTypes:[] // By default all are valid, just list those here that are in the spec but not valid.
		},

		geolocation:{
			supportsAgps:true,
			supportsCellId:true,
			supportsGps:true,
			timeouts:{
				gps:180 * 1000,
				agps:5 * 1000,
				cellId:15 * 1000
			}
		}
	};

	//
	//	Configure your stuff here!!!!!!!!!!!!!!
	//
	var configs = {
		//
		//	Vodafone 360 Devices, H1/M1
		//
		"regexp:^WidgetManager;\\sSAMSUNG-GT-I8320-Vodafone;AppleWebKit.*":function(){
			// Figure out the widget's root directory by making a filesystem
			// function throw an error and reading the "sourceURL" property of this error.
			// It returns the filename for this config.js file.
			var readableFile = "";
			try{
				Widget.Device.getDirectoryFileNames("doesn't exist anyway!");
			}catch(e){
				if (e.sourceURL){
					readableFile = e.sourceURL;
				}
			}
			// Replace multiple trailing slashes, explicitly (just to be sure).
			var widgetPath = readableFile.replace(/\/js\/config\.js$/, "").replace(/\/+$/, "")+"/";

			var ret = {
				canDoMultitasking:false
				// Add the device's configuration, different from the default here!
			};
			return ret;
		},
		//
		//	Vodafone 360 Devices, H2 (I8330), M2 (I6420)
		//
		"regexp:^WidgetManager;\\sSAMSUNG-GT-I\\d{4}-Vodafone;AppleWebKit.*":function(){
			var ret = {
				// AGPS==GPS so set the timeout to the same on the H2
				geolocation:{
					timeouts: {
						agps: defaults.geolocation.timeouts.gps
					}
				},
				events: {
					invalidRecurrenceTypes: ['EVERY_WEEKDAY', 'MONTHLY_ON_DAY']
				},
				supports: {
					Messaging:{
						moveMessage: false,
						editFolder: false,
						multipleEmailAccounts: false
					}
				}
			};
			return ret;
		},
		//
		//	Opera Widget Runtime for Vodafone for Android
		//
		"regexp:^WidgetManager;.*\\(Android.*Opera.*Widgets.*":function(){
			var ret = {
				unsupportedApis:[
					"Widget.RadioInfo.radioSignalSource",
					"Widget.RadioInfo.radioSignalStrengthPercent",
					"Widget.RadioInfo.onSignalSourceChange",
					"Widget.DataNetworkInfo.onNetworkConnectionChanged",
					"Widget.DataNetworkInfo.getNetworkConnectionName",
					"Widget.DataNetworkInfo.networkConnectionType",
					"Widget.Device.clipboardString",
					"Widget.Device.copyFile",
					"Widget.Device.deleteFile",
					"Widget.Device.findFiles",
					"Widget.Device.getFileSystemRoots",
					"Widget.Device.getFileSystemSize",
					"Widget.Device.moveFile",
					"Widget.Device.onFilesFound",
					"Widget.Device.setRingtone",
					"Widget.Device.vibrate",
					"Widget.Device.PowerInfo",
					"Widget.DeviceInfo.totalMemory",
					"Widget.DeviceStateInfo.backLightOn",
					"Widget.DeviceStateInfo.keypadLightOn",
					"Widget.DeviceStateInfo.onScreenChangeDimensions",
					"Widget.DeviceStateInfo.Config",
					"Widget.PositionInfo.altitudeAccuracy",
					"Widget.PositionInfo.cellID",
					"Widget.PIM.deleteAddressBookItem",
					"Widget.Multimedia.isVideoPlaying",
					"Widget.VideoPlayer.*",
					"Widget.PIM.addCalendarItem",
					"Widget.PIM.deleteCalendarItem",
					"Widget.PIM.exportAsVCard",
					"Widget.PIM.findCalendarItems",
					"Widget.PIM.getCalendarItem",
					"Widget.PIM.getCalendarItems",
					"Widget.PIM.onCalendarItemAlert",
					"Widget.PIM.onCalendarItemsFound",
					"Widget.Calendar*",
					"Widget.EventRecurrenceTypes",
					"Widget.Device.AccountInfo.phoneMSISDN",
					"Widget.Device.AccountInfo.userSubscriptionType",
					"Widget.Device.AccountInfo.userAccountBalance",
					"Widget.Telephony*",
					"Widget.CallRecord*",
					"Widget.Messag*", // includes Message, Messaging, etc.
					"Widget.Attachment",
					"Widget.Account",
					"Widget.Config",
					"Widget.PowerInfo",
				]
			};
			return ret;
		},
		//
		//	PC, Opera Widget Runtime
		//
		"regexp:Opera\\/9\\.64(.*)Presto\\/2\\.1\\.1":function(){
			var ret = {
				hasClipboard:true,
				hasClamshell:false
			};
			return ret;
		},
		//
		//	Opera Widgets 10.00 (Emulator, maybe also when running on a device)
		//
		"regexp:Opera\\/9\\.80(.*)Presto\\/2\\.4\\.18":function(){
		},
		//
		//	Firefox on PC
		//
		// e.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6"
		"regexp:Mozilla.*Gecko\/\\d+\\sFirefox.*":function(){
// using only "AppleWebkit" here would also be found on the H2
		//"regexp:(.*AppleWebKit.*)|(Mozilla.*Gecko\/\\d+\\sFirefox.*)":function(){
			var ret = {
				hasClipboard:true,
				hasClamshell:false,
				geolocation:{
					timeouts: {
						agps: defaults.geolocation.timeouts.gps
					}
				},
				events: {
					invalidRecurrenceTypes: ['EVERY_WEEKDAY', 'MONTHLY_ON_DAY']
				},
				supports: {
					Messaging:{
						moveMessage: false,
						editFolder: false,
						multipleEmailAccounts: false
					}
				}
			};
			return ret;
		},
		//
		// Chrome, Ripple
		//
		//"regexp:Mozilla.*Chrome":function(){
		//	var ret = {
		//	};
		//	return ret;
		//},

		// Made for UAs
		// 		WidgetManager; Nokia N96....
		// 		WidgetManager; Nokia 5800...
		"regexp:^WidgetManager;\\sNokia\\s(N)?\\d+;\\sOpera.*":function(){
			var widgetPath = (""+window.location).replace("widget://localhost/", "").replace(/index.html$/, "");
			var ret = {
				hasClipboard:true,
				hasClamshell:false
			};
			return ret;
		},
		"WidgetManager; NOKIA E52-1; Opera/9.5 (S60; Symbian OS; U; de; Opera Mobile/1109)":function(){
			var widgetPath = (""+window.location).replace("widget://localhost/", "").replace(/index.html$/, "");
			var ret = {
				hasClipboard:true,
				hasClamshell:false
			};
			return ret;
		}
	};
	//
	//	END of the configuring stuff.
	//

	//
	// Find the config we have to mixin.
	//
	var ua = window.navigator.userAgent;
	var configToMixin = null;
//var ua = "WidgetManager; SAMSUNG-GT-I8320-Vodafone;AppleWebKit/528.5+(X11;U;Linux;en;i8329BUIH8)";
	for (var key in configs){
		var c = configs[key];
		if (key.indexOf("regexp:")===0){
			if (ua.match(new RegExp(key.substr(7)))){
				configToMixin = c();
				break;
			}
		} else if(key===ua){
			configToMixin = c();
			break;
		}
	}
	if (configToMixin===null){
		configToMixin = doh.util.mixin({}, defaults);
	} else {
		configToMixin.isCustomConfiguration = true;
	}

	// config is still empty at this point, just contains key "isCustomConfiguration".
	doh.util.mixin(config, defaults);
	// Mixin the additional config params.
	// Mixin recursively so objects don't have to declare each key again!
	function _mixin(base, overrider){
		// summary:
		// 		Recursive object mixin.
		// description:
		// 		base is the initial object, overrider contains values that
		// 		override the according values in base.
		var ret = doh.util.mixin({}, base); // clone base
		for (var key in overrider){
			var v = overrider[key];
			if (!doh.util.isArray(v) && typeof v=="object"){
				ret[key] = _mixin(ret[key], v);
			} else {
				ret[key] = v;
			}
		}
		return ret;
	}
	for (var key in configToMixin){
		var v = configToMixin[key];
		if (typeof v=="object" && !doh.util.isArray(v)){
			config[key] = _mixin(config[key], v);
		} else {
			config[key] = v;
		}
	}
})();
<commit_msg>fixed opera config, now signed widgets can be tested<commit_after>var config = {
	isCustomConfiguration:false
};

(function(){

// TOD how can we embed this into the synchronous loading process to fill the config??
	//function _findValidAddressBookItemId(callback){
	//	try{
	//		var pim = Widget.PIM;
	//		var addr = new pim.AddressBookItem();
	//		addr.setAttributeValue("fullName", "*");
	//		Widget.PIM.onAddressBookItemsFound = function(items){
	//			if (items.length>0){
	//				callback(items[0].addressBookItemId);
	//			}
	//		}
	//		pim.findAddressBookItems(addr, 0, 1);
	//		delete pim.onAddressBookItemsFound;
	//	}catch(e){
	//		callback(null);
	//	}
	//}

	var defaults = {
		// summary: This configuration defines the features of the phone.
		// description: It maybe used to determine if a test is viable
		// 		and shall be added or not. E.g. if a phone has a certain hardware
		// 		feature or not, like a clamshell.
		hasAccelerometer:true,
		hasClipboard:false,
		hasClamshell:false,
		hasKeypadLight:false,

		supportsOrientationLandscape:true,
		supportsMultipleEmailAccounts:true,
		supportsDeleteEmailAccounts:true,

		unsupportedApis:[],

		// Some devices/platforms don't support certain features and they normally need to return UNSUPPORTED
		// exception, but to run the correct tests (those testing for the exception) we need to configure
		// the platforms. That is done here.
		// The list below ONLY lists those features that need to be turned off for a certain platform
		// if there is one missing add it, by default the features are all expected to be supported (default value is true).
		supports:{
			// On the first the module (=test file) is given.
			Messaging:{
				moveMessage:true, // moveToFolder()
				editFolder:true, // If createFolder(), moveFolder(), deleteFolder() are NOT supported set this to false.
				multipleEmailAccounts:true
			}
		},

		// Set this to true if the device can open multiple applications.
		// E.g. we can only test Widget.onRestore when the device allows to put the
		// application in the background.
		canDoMultitasking:true,

		validAddressBookItemId:"1",
		validCalendarItemId:"1", // The first contact filled in an H2 really has the ID "1".

		// Various file system settings that will be used for testing, etc.
		// NOTE: Paths must always end with the directorySeparator
		// (just to have less hazzle when just adding a filename in the test).
		fileSystem:{
			directorySeparator:"/",

			// A path where we can read a file from, do directory listing or something alike.
			readablePath:"/virtual/photos/",
			// Specify a file name here for a file that is readable.
			// E.g. for testing methods like getFile().
			readableFile:"/virtual/photos/test-photo/test.txt",
			emptyReadableDirectory:"/virtual/photos/test-photo/testdir",

			// Writeable file or path.
			writeablePath:"/virtual/photos/",
			writeableFile:"/virtual/photos/test-photo/test-write.txt",

			// The root path of the widget, where we can e.g. read out all the
			// files provided with the widget (like audio or video files).
			widgetPath:"",
			playableAudioFiles:{
				inWidget:{
					songWav:"test-audio/wav/music.wav",
					songMp3:"test-audio/mp3/music.mp3",
					loopWav:"test-audio/wav/loop.wav",
					loopMp3:"test-audio/mp3/loop.mp3"
				},
				onDevice:{
					songWav:"/virtual/music/test-audio/wav/music.wav",
					songMp3:"/virtual/music/test-audio/mp3/music.mp3",
					loopWav:"/virtual/music/test-audio/wav/loop.wav",
					loopMp3:"/virtual/music/test-audio/mp3/loop.mp3"
				}
			},
			playableVideoFiles:{
				//viaHttp:"http://...",
				//viaHttps:"https://...",
				//viaRtsp:"rtsp://...",
				//viaFile:"file:///", // ??? shall this be the virtual FS or the real FS (=device specific)???
				avc:{
					inWidget:"test-video/avc/AVC_AAC_48K_30F_QVGA.mp4",
					onDevice:"/virtual/videos/test-video/avc/AVC_AAC_48K_30F_QVGA.mp4"
				},
				h263:{
					inWidget:"test-video/h263/H263_148K_QCIF_15_plus_MP4AAC_22_1.3gp",
					onDevice:"/virtual/videos/test-video/h263/H263_148K_QCIF_15_plus_MP4AAC_22_1.3gp"
				},
				h264:{
					inWidget:"test-video/h264/H264_256K_QVGA_15_plus_AAC_22_2.mp4",
					onDevice:"/virtual/videos/test-video/h264/H264_256K_QVGA_15_plus_AAC_22_2.mp4",
					inWidget1:"test-video/h264/HMC_boa_320_240.MP4",
					onDevice1:"/virtual/videos/test-video/h264/HMC_boa_320_240.MP4"
				},
				mp4:{
					inWidget:"test-video/mp4/MP4V_508K_QVGA_15_plus_MP4AAC_32_2.mp4",
					onDevice:"/virtual/videos/test-video/mp4/MP4V_508K_QVGA_15_plus_MP4AAC_32_2.mp4"
				}
			},
			imageFile:""
		},

		events:{
			invalidRecurrenceTypes:[] // By default all are valid, just list those here that are in the spec but not valid.
		},

		geolocation:{
			supportsAgps:true,
			supportsCellId:true,
			supportsGps:true,
			timeouts:{
				gps:180 * 1000,
				agps:5 * 1000,
				cellId:15 * 1000
			}
		}
	};

	//
	//	Configure your stuff here!!!!!!!!!!!!!!
	//
	var configs = {
		//
		//	Vodafone 360 Devices, H1/M1
		//
		"regexp:^WidgetManager;\\sSAMSUNG-GT-I8320-Vodafone;AppleWebKit.*":function(){
			// Figure out the widget's root directory by making a filesystem
			// function throw an error and reading the "sourceURL" property of this error.
			// It returns the filename for this config.js file.
			var readableFile = "";
			try{
				Widget.Device.getDirectoryFileNames("doesn't exist anyway!");
			}catch(e){
				if (e.sourceURL){
					readableFile = e.sourceURL;
				}
			}
			// Replace multiple trailing slashes, explicitly (just to be sure).
			var widgetPath = readableFile.replace(/\/js\/config\.js$/, "").replace(/\/+$/, "")+"/";

			var ret = {
				canDoMultitasking:false
				// Add the device's configuration, different from the default here!
			};
			return ret;
		},
		//
		//	Vodafone 360 Devices, H2 (I8330), M2 (I6420)
		//
		"regexp:^WidgetManager;\\sSAMSUNG-GT-I\\d{4}-Vodafone;AppleWebKit.*":function(){
			var ret = {
				// AGPS==GPS so set the timeout to the same on the H2
				geolocation:{
					timeouts: {
						agps: defaults.geolocation.timeouts.gps
					}
				},
				events: {
					invalidRecurrenceTypes: ['EVERY_WEEKDAY', 'MONTHLY_ON_DAY']
				},
				supports: {
					Messaging:{
						moveMessage: false,
						editFolder: false,
						multipleEmailAccounts: false
					}
				}
			};
			return ret;
		},
		//
		//	Opera Widget Runtime for Vodafone for Android
		//
		"regexp:^WidgetManager;.*\\(Android.*Opera.*Widgets.*":function(){
			var ret = {
				fileSystem:{
					readablePath:"/sdcard",
					readableFile:"/sdcard/test-audio/mp3/loop.mp3",
					playableAudioFiles:{
						onDevice:{
							// Hope we soon wont need it and opera builds the virtual fs
							songWav:"file:///sdcard/test-audio/wav/music.wav",
							songMp3:"file:///sdcard/test-audio/mp3/music.mp3",
							loopWav:"file:///sdcard/test-audio/wav/loop.wav",
							loopMp3:"file:///sdcard/test-audio/mp3/loop.mp3"
						}
					}
				},
				unsupportedApis:[
					"Widget.Device.RadioInfo.radioSignalSource",
					"Widget.Device.RadioInfo.radioSignalStrengthPercent",
					"Widget.Device.RadioInfo.onSignalSourceChange",
					"Widget.Device.DataNetworkInfo.onNetworkConnectionChanged",
					"Widget.Device.DataNetworkInfo.getNetworkConnectionName",
					"Widget.Device.DataNetworkInfo.networkConnectionType",
					"Widget.Device.clipboardString",
					"Widget.Device.copyFile",
					"Widget.Device.deleteFile",
					"Widget.Device.findFiles",
					"Widget.Device.getFileSystemRoots",
					"Widget.Device.getFileSystemSize",
					"Widget.Device.moveFile",
					"Widget.Device.onFilesFound",
					"Widget.Device.setRingtone",
					"Widget.Device.vibrate",
					"Widget.Device.PowerInfo",
					"Widget.Device.DeviceInfo.totalMemory",
					"Widget.Device.DeviceStateInfo.backLightOn",
					"Widget.Device.DeviceStateInfo.keypadLightOn",
					"Widget.Device.DeviceStateInfo.onScreenChangeDimensions",
					"Widget.Device.DeviceStateInfo.Config",
					"Widget.Device.PositionInfo.altitudeAccuracy",
					"Widget.Device.PositionInfo.cellID",
					"Widget.PIM.deleteAddressBookItem",
					"Widget.Multimedia.isVideoPlaying",
					"Widget.Multimedia.VideoPlayer.*",
					"Widget.PIM.addCalendarItem",
					"Widget.PIM.deleteCalendarItem",
					"Widget.PIM.exportAsVCard",
					"Widget.PIM.findCalendarItems",
					"Widget.PIM.getCalendarItem",
					"Widget.PIM.getCalendarItems",
					"Widget.PIM.onCalendarItemAlert",
					"Widget.PIM.onCalendarItemsFound",
					"Widget.PIM.Calendar*",
					"Widget.PIM.EventRecurrenceTypes",
					"Widget.Device.AccountInfo.phoneMSISDN",
					"Widget.Device.AccountInfo.userSubscriptionType",
					"Widget.Device.AccountInfo.userAccountBalance",
					"Widget.Telephony*",
					"Widget.CallRecord*",
					"Widget.Messag*", // includes Message, Messaging, etc.
					"Widget.Attachment",
					"Widget.Account",
					"Widget.Config"
				]
			};
			return ret;
		},
		//
		//	PC, Opera Widget Runtime
		//
		"regexp:Opera\\/9\\.64(.*)Presto\\/2\\.1\\.1":function(){
			var ret = {
				hasClipboard:true,
				hasClamshell:false
			};
			return ret;
		},
		//
		//	Opera Widgets 10.00 (Emulator, maybe also when running on a device)
		//
		"regexp:Opera\\/9\\.80(.*)Presto\\/2\\.4\\.18":function(){
		},
		//
		//	Firefox on PC
		//
		// e.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-GB; rv:1.9.2) Gecko/20100115 Firefox/3.6"
		"regexp:Mozilla.*Gecko\/\\d+\\sFirefox.*":function(){
// using only "AppleWebkit" here would also be found on the H2
		//"regexp:(.*AppleWebKit.*)|(Mozilla.*Gecko\/\\d+\\sFirefox.*)":function(){
			var ret = {
				hasClipboard:true,
				hasClamshell:false,
				geolocation:{
					timeouts: {
						agps: defaults.geolocation.timeouts.gps
					}
				},
				events: {
					invalidRecurrenceTypes: ['EVERY_WEEKDAY', 'MONTHLY_ON_DAY']
				},
				supports: {
					Messaging:{
						moveMessage: false,
						editFolder: false,
						multipleEmailAccounts: false
					}
				}
			};
			return ret;
		},
		//
		// Chrome, Ripple
		//
		//"regexp:Mozilla.*Chrome":function(){
		//	var ret = {
		//	};
		//	return ret;
		//},

		// Made for UAs
		// 		WidgetManager; Nokia N96....
		// 		WidgetManager; Nokia 5800...
		"regexp:^WidgetManager;\\sNokia\\s(N)?\\d+;\\sOpera.*":function(){
			var widgetPath = (""+window.location).replace("widget://localhost/", "").replace(/index.html$/, "");
			var ret = {
				hasClipboard:true,
				hasClamshell:false
			};
			return ret;
		},
		"WidgetManager; NOKIA E52-1; Opera/9.5 (S60; Symbian OS; U; de; Opera Mobile/1109)":function(){
			var widgetPath = (""+window.location).replace("widget://localhost/", "").replace(/index.html$/, "");
			var ret = {
				hasClipboard:true,
				hasClamshell:false
			};
			return ret;
		}
	};
	//
	//	END of the configuring stuff.
	//

	//
	// Find the config we have to mixin.
	//
	var ua = window.navigator.userAgent;
	var configToMixin = null;
//var ua = "WidgetManager; SAMSUNG-GT-I8320-Vodafone;AppleWebKit/528.5+(X11;U;Linux;en;i8329BUIH8)";
	for (var key in configs){
		var c = configs[key];
		if (key.indexOf("regexp:")===0){
			if (ua.match(new RegExp(key.substr(7)))){
				configToMixin = c();
				break;
			}
		} else if(key===ua){
			configToMixin = c();
			break;
		}
	}
	if (configToMixin===null){
		configToMixin = doh.util.mixin({}, defaults);
	} else {
		configToMixin.isCustomConfiguration = true;
	}

	// config is still empty at this point, just contains key "isCustomConfiguration".
	doh.util.mixin(config, defaults);
	// Mixin the additional config params.
	// Mixin recursively so objects don't have to declare each key again!
	function _mixin(base, overrider){
		// summary:
		// 		Recursive object mixin.
		// description:
		// 		base is the initial object, overrider contains values that
		// 		override the according values in base.
		var ret = doh.util.mixin({}, base); // clone base
		for (var key in overrider){
			var v = overrider[key];
			if (!doh.util.isArray(v) && typeof v=="object"){
				ret[key] = _mixin(ret[key], v);
			} else {
				ret[key] = v;
			}
		}
		return ret;
	}
	for (var key in configToMixin){
		var v = configToMixin[key];
		if (typeof v=="object" && !doh.util.isArray(v)){
			config[key] = _mixin(config[key], v);
		} else {
			config[key] = v;
		}
	}
})();
<|endoftext|>


<commit_before>requirejs.config({
    baseUrl : '.',
    paths   : {
        'lib'              : 'vendor',
        'modules'          : 'js',
        'template_dir'     : 'html',
        'angular'          : 'vendor/angular/angular',
        'ng-resource'      : 'vendor/ng-resource/dist/ng-resource',
        'ui-sortable'      : 'vendor/angular-ui-sortable/sortable.min',
        'jquery-ui'        : 'vendor/jquery-ui/jquery-ui.min',
        'jquery'           : 'vendor/jquery/dist/jquery.min',
        'jqui-touch-punch' : 'vendor/jquery-ui-touch-punch/jquery.ui.touch-punch.min',
        'text'             : 'vendor/requirejs-text/text'
    },
    shim    : {
        'angular': {
            deps: ['jquery']
        },
        'ng-resource': {
            deps: ['angular']
        },
        'ui-sortable': {
            deps: ['angular', 'jquery-ui']
        },
        'jquery-ui-core': {
            deps: ['jquery']
        },
        'jqui-touch-punch': {
            deps: ['jquery-ui']
        }
    }
});

requirejs([
    'modules/Application',
    'vendor/mobile-detect/mobile-detect',
    'jqui-touch-punch',
    'angular'
], function (Appliction) {
    function bootstrapAngular () {
        var htmlElem = document.getElementsByTagName('html')[0],
            contentElem = document.getElementById('content');

        angular.bootstrap(htmlElem, ['Application']);
    }

    // Hack preventing virtual keyboard from screwing styling
    var md = new MobileDetect(window.navigator.userAgent);
    if (md.mobile() !== null) {
        document.body.style.minHeight = document.body.clientHeight + 'px';
    }

    // Auto-reload when appcache updates
    if (window.hasOwnProperty('applicationCache')) {
        window.applicationCache.addEventListener('updateready', function () {
            window.location.reload();
        });
    }

    if (document.readyState === 'complete') {
        bootstrapAngular();
    }
    else {
        window.addEventListener('load', bootstrapAngular, false);
    }
});
<commit_msg>Revert "return to using all of jquery-ui due to dep issues"<commit_after>requirejs.config({
    baseUrl : '.',
    paths   : {
        'lib'               : 'vendor',
        'modules'           : 'js',
        'template_dir'      : 'html',
        'angular'           : 'vendor/angular/angular',
        'ng-resource'       : 'vendor/ng-resource/dist/ng-resource',
        'ui-sortable'       : 'vendor/angular-ui-sortable/sortable.min',
        'jquery-ui-core'    : 'vendor/jquery-ui/ui/minified/jquery.ui.core.min',
        'jquery-ui-widget'  : 'vendor/jquery-ui/ui/minified/jquery.ui.widget.min',
        'jquery-ui-mouse'   : 'vendor/jquery-ui/ui/minified/jquery.ui.mouse.min',
        'jquery-ui-sortable': 'vendor/jquery-ui/ui/minified/jquery.ui.sortable.min',
        'jquery'            : 'vendor/jquery/dist/jquery.min',
        'jqui-touch-punch'  : 'vendor/jquery-ui-touch-punch/jquery.ui.touch-punch.min',
        'text'              : 'vendor/requirejs-text/text'
    },
    shim    : {
        'angular': {
            deps: ['jquery']
        },
        'ng-resource': {
            deps: ['angular']
        },
        'ui-sortable': {
            deps: ['angular', 'jqui-touch-punch', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse', 'jquery-ui-sortable']
        },
        'jquery-ui-core': {
            deps: ['jquery']
        },
        'jqui-touch-punch': {
            deps: ['jquery-ui-widget', 'jquery-ui-mouse']
        }
    }
});

requirejs([
    'modules/Application',
    'vendor/mobile-detect/mobile-detect',
    'angular'
], function (Appliction) {
    function bootstrapAngular () {
        var htmlElem = document.getElementsByTagName('html')[0],
            contentElem = document.getElementById('content');

        angular.bootstrap(htmlElem, ['Application']);
    }

    // Hack preventing virtual keyboard from screwing styling
    var md = new MobileDetect(window.navigator.userAgent);
    if (md.mobile() !== null) {
        document.body.style.minHeight = document.body.clientHeight + 'px';
    }

    // Auto-reload when appcache updates
    if (window.hasOwnProperty('applicationCache')) {
        window.applicationCache.addEventListener('updateready', function () {
            window.location.reload();
        });
    }

    if (document.readyState === 'complete') {
        bootstrapAngular();
    }
    else {
        window.addEventListener('load', bootstrapAngular, false);
    }
});
<|endoftext|>


<commit_before>var Ginger = function() {
  var scene, camera, renderer;

  var aspect;

  // Object3D with all meshes as children.
  var ginger;

  // All textures that need to be loaded before the meshes.
  var textures = {
    gingercolor: {
      path: 'model/ginger_color.jpg',
      texture: null,
    }
  };

  // Models that must be loaded before adding anything to the scene.
  // This helps keep horrifying body parts from showing before other parts.
  var meshes = {
    gingerhead: {
      path: 'model/gingerhead.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    },
    gingerheadband: {
      path: 'model/gingerheadband.json',
      texture: textures.gingercolor,
      morphTargets: false,
      mesh: null
    },
    gingerheadphones: {
      path: 'model/gingerheadphones.json',
      texture: null,
      morphTargets: false,
      mesh: null
    },
    gingerlefteye: {
      path: 'model/gingerlefteye.json',
      texture: textures.gingercolor,
      morphTargets: false,
      mesh: null
    },
    gingerrighteye: {
      path: 'model/gingerrighteye.json',
      texture: textures.gingercolor,
      morphTargets: false,
      mesh: null
    },
    gingerteethbot: {
      path: 'model/gingerteethbot.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    },
    gingerteethtop: {
      path: 'model/gingerteethtop.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    },
    gingertongue: {
      path: 'model/gingertongue.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    }
  };

  var morphs = {
    eyes: {
      value: -1,
      mesh: meshes.gingerhead,
      targets: [0, 1, 2, 3, 4, 5, 6, 7, 8],
      thresholds: [-1, -0.6, -0.3, -0.1, 0, 0.3, 0.4, 0.5, 0.7],

      behavior: function(value) {
        var sex = morphs.sex.value;
        var recede = EASING.linear(sex, 0, -0.125, 1);

        meshes.gingerlefteye.mesh.position.x = recede;
        meshes.gingerlefteye.mesh.position.z = recede;
        meshes.gingerrighteye.mesh.position.x = -recede;
        meshes.gingerrighteye.mesh.position.z = recede;
      }
    },
    expression: {
      value: 0.2,
      mesh: meshes.gingerhead,
      targets: [20, 9],
      thresholds: [0, 0.5]
    },
    jawrange: {
      value: 0.5,
      mesh: meshes.gingerhead,
      targets: [10, 11],
      thresholds: [0, 0.5]
    },
    jawtwist: {
      value: 0,
      mesh: meshes.gingerhead,
      targets: [12, 13],
      thresholds: [-1, 0]
    },
    lipcurl: {
      value: 0,
      mesh: meshes.gingerhead,
      targets: [15, 16],
      thresholds: [-1, 0]
    },
    lipsync: {
      value: -1,
      mesh: meshes.gingerhead,
      targets: [17, 18, 19],
      thresholds: [-1, 0, 0.5]
    },
    sex: {
      value: 0.5,
      mesh: meshes.gingerhead,
      targets: [21, 22],
      thresholds: [0, 0.75]
    },
    width: {
      value: 0,
      mesh: meshes.gingerhead,
      targets: [23, 24],
      thresholds: [-1, 0]
    },
    tongue: {
      value: 0,
      mesh: meshes.gingertongue,
      targets: [0, 1, 2, 3, 4, 5, 6],
      thresholds: [0.1, 0.2, 0.3, 0.5, 0.6, 0.7, 0.8]
    }
  };

  function morph() {
    // Apply morph values to the correct targets.
    for (var morph in morphs) {
      var morphTarget = morphs[morph];
      var target = 0;

      // Find which morph needs to have the value applied to.
      // This is determined using thresholds.
      for (var i = 0; i < morphTarget.thresholds.length; i++) {
        var threshold = morphTarget.thresholds[i];

        if (morphTarget.value >= threshold) {
          target = i;
        }
      }

      // The morph that should be updated based on the threshholds.
      var morphid = morphTarget.targets[target];

      // Apply the morph to the currently determined morph in the range.
      for (var i = 0; i < morphTarget.targets.length; i++) {
        var index = morphTarget.targets[i];

        if (morphTarget.targets[i] != morphid) {
          morphTarget.mesh.mesh.morphTargetInfluences[index] = 0;
        } else {
          morphTarget.mesh.mesh.morphTargetInfluences[index] = Math.abs(morphTarget.value);
        }
      }
    }

    // Another separate loop for morph behaviors. This is so the scale or morph
    // of certain meshes can be adjusted to account for others.
    for (var morph in morphs) {
      var morphTarget = morphs[morph];

      // Not all morphs need behaviors so do not assume.
      if (morphTarget['behavior'] != undefined) {
        morphTarget.behavior(morphTarget.value);
      }
    }
  }

  function load() {
    loadTextures(function() {
      loadMeshes(function() {
        morph();
      });
    });
  }

  function loadTextures(callback) {
    var goal = Object.keys(textures).length;
    var progress = 0;

    // Loads textures asynchronously.
    var load = function(path, texture) {
      textureLoader.load(path, function(loadedTexture) {
        textures[texture].texture = loadedTexture;
        progress++;

        // Once all textures are loaded the callback is called.
        // This allows chaining mesh loading which requires textures.
        if (progress >= goal) {
          if (callback != null) {
            callback();
          }

          return;
        }
      });
    };

    var textureLoader = new THREE.TextureLoader();

    // Begin the async load.
    for (var texture in textures) {
      var path = textures[texture].path;
      load(path, texture);
    }
  }

  function loadMeshes(callback) {
    var goal = Object.keys(meshes).length;
    var progress = 0;

    var jsonLoader = new THREE.JSONLoader();

    // Adds all meshes loaded into the scene.
    var addMeshes = function() {
      for (var mesh in meshes) {
        ginger.add(meshes[mesh].mesh);
      }
    };

    // Loads the meshes asynchronously.
    var load = function(path, mesh) {
      jsonLoader.load(path, function(geometry) {
        var texture;

        if (meshes[mesh].texture != null) {
          texture = meshes[mesh].texture.texture;
        }

        var material = new THREE.MeshLambertMaterial({
          map: texture,
          morphTargets: meshes[mesh].morphTargets
        });

        meshes[mesh].mesh = new THREE.Mesh(geometry, material);
        progress++;

        // Once all meshes are loaded, all meshes are added to the scene.
        // Optionally a callback is available.
        if (progress >= goal) {
          addMeshes();

          if (callback != null) {
            callback();
          }

          return;
        }
      });
    };

    // Begin the async load.
    for (var mesh in meshes) {
      var path = meshes[mesh].path;
      load(path, mesh);
    }
  }

  function onresize(event) {
    recalculateAspect();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }

  function recalculateAspect() {
    aspect = window.innerWidth / window.innerHeight;
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
  }

  function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
  }

  return {
    init: function() {
      scene = new THREE.Scene();

      // Find the initial aspect.
      aspect = window.innerWidth / window.innerHeight;

      camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 10000);
      camera.position.y = 5;
      camera.position.z = 10;

      // Create a renderer the size of the entire window.
      renderer = new THREE.WebGLRenderer({
        antialias: true
      });
      renderer.setSize(window.innerWidth, window.innerHeight);

      // Add the canvas to the renderer wrapper so the panel
      // stays above the canvas.
      document.getElementById('renderer').appendChild(renderer.domElement);

      // Allow viewport resizing whenever the window resizes.
      window.onresize = onresize;

      // Let there be light! The light is simply a directional light that
      // shines directly inter Ginger's face.
      var directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1);
      directionalLight.position.set(0, 0, 1);
      scene.add(directionalLight);

      // Ginger is the container for all the meshes.
      ginger = new THREE.Object3D();
      scene.add(ginger);

      // Load ginger in the background.
      load();

      // Start the render loop.
      animate();
    }
  };
};

(function() {
  var ginger = new Ginger();
  ginger.init();
})();
<commit_msg>Added mouse tracking<commit_after>var Ginger = function() {
  var scene, camera, renderer;

  var aspect;

  var queue = [];

  // Object3Ds with all meshes as children.
  var ginger = new THREE.Object3D();
  var leftEye = new THREE.Object3D();
  var rightEye = new THREE.Object3D();

  var leftEyeOrigin;
  var rightEyeOrigin;

  // All textures that need to be loaded before the meshes.
  var textures = {
    gingercolor: {
      path: 'model/ginger_color.jpg',
      texture: null,
    }
  };

  // Models that must be loaded before adding anything to the scene.
  // This helps keep horrifying body parts from showing before other parts.
  var meshes = {
    gingerhead: {
      path: 'model/gingerhead.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    },
    gingerheadband: {
      path: 'model/gingerheadband.json',
      texture: textures.gingercolor,
      morphTargets: false,
      mesh: null
    },
    gingerheadphones: {
      path: 'model/gingerheadphones.json',
      texture: null,
      morphTargets: false,
      mesh: null
    },
    gingerlefteye: {
      path: 'model/gingerlefteye.json',
      texture: textures.gingercolor,
      morphTargets: false,
      parent: leftEye,
      position: new THREE.Vector3(-0.96, -6.169, -1.305),
      mesh: null
    },
    gingerrighteye: {
      path: 'model/gingerrighteye.json',
      texture: textures.gingercolor,
      morphTargets: false,
      parent: rightEye,
      position: new THREE.Vector3(0.96, -6.169, -1.305),
      mesh: null
    },
    gingerteethbot: {
      path: 'model/gingerteethbot.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    },
    gingerteethtop: {
      path: 'model/gingerteethtop.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    },
    gingertongue: {
      path: 'model/gingertongue.json',
      texture: textures.gingercolor,
      morphTargets: true,
      mesh: null
    }
  };

  var morphs = {
    eyes: {
      value: -1,
      mesh: meshes.gingerhead,
      targets: [0, 1, 2, 3, 4, 5, 6, 7, 8],
      thresholds: [-1, -0.6, -0.3, -0.1, 0, 0.3, 0.4, 0.5, 0.7],

      behavior: function(value) {
        var sex = morphs.sex.value;
        var recede = EASING.linear(sex, 0, -0.125, 1);

        if (leftEyeOrigin == undefined) {
          leftEyeOrigin = leftEye.position;
        }
        if (rightEyeOrigin == undefined) {
          rightEyeOrigin = rightEye.position;
        }

        leftEye.position.x = leftEyeOrigin.x + recede;
        leftEye.position.z = leftEyeOrigin.z + recede;
        rightEye.position.x = rightEyeOrigin.x - recede;
        rightEye.position.z = rightEyeOrigin.z + recede;
      }
    },
    expression: {
      value: 0.2,
      mesh: meshes.gingerhead,
      targets: [20, 9],
      thresholds: [0, 0.5]
    },
    jawrange: {
      value: 0.5,
      mesh: meshes.gingerhead,
      targets: [10, 11],
      thresholds: [0, 0.5]
    },
    jawtwist: {
      value: 0,
      mesh: meshes.gingerhead,
      targets: [12, 13],
      thresholds: [-1, 0]
    },
    lipcurl: {
      value: 0,
      mesh: meshes.gingerhead,
      targets: [15, 16],
      thresholds: [-1, 0]
    },
    lipsync: {
      value: -1,
      mesh: meshes.gingerhead,
      targets: [17, 18, 19],
      thresholds: [-1, 0, 0.5]
    },
    sex: {
      value: 0.5,
      mesh: meshes.gingerhead,
      targets: [21, 22],
      thresholds: [0, 0.75]
    },
    width: {
      value: 0,
      mesh: meshes.gingerhead,
      targets: [23, 24],
      thresholds: [-1, 0]
    },
    tongue: {
      value: 0,
      mesh: meshes.gingertongue,
      targets: [0, 1, 2, 3, 4, 5, 6],
      thresholds: [0.1, 0.2, 0.3, 0.5, 0.6, 0.7, 0.8]
    }
  };

  function morph() {
    // Apply morph values to the correct targets.
    for (var morph in morphs) {
      var morphTarget = morphs[morph];
      var target = 0;

      // Find which morph needs to have the value applied to.
      // This is determined using thresholds.
      for (var i = 0; i < morphTarget.thresholds.length; i++) {
        var threshold = morphTarget.thresholds[i];

        if (morphTarget.value >= threshold) {
          target = i;
        }
      }

      // The morph that should be updated based on the threshholds.
      var morphid = morphTarget.targets[target];

      // Apply the morph to the currently determined morph in the range.
      for (var i = 0; i < morphTarget.targets.length; i++) {
        var index = morphTarget.targets[i];

        if (morphTarget.targets[i] != morphid) {
          morphTarget.mesh.mesh.morphTargetInfluences[index] = 0;
        } else {
          morphTarget.mesh.mesh.morphTargetInfluences[index] = Math.abs(morphTarget.value);
        }
      }
    }

    // Another separate loop for morph behaviors. This is so the scale or morph
    // of certain meshes can be adjusted to account for others.
    for (var morph in morphs) {
      var morphTarget = morphs[morph];

      // Not all morphs need behaviors so do not assume.
      if (morphTarget['behavior'] != undefined) {
        morphTarget.behavior(morphTarget.value);
      }
    }
  }

  function load() {
    loadTextures(function() {
      loadMeshes(function() {
        morph();
      });
    });
  }

  function loadTextures(callback) {
    var goal = Object.keys(textures).length;
    var progress = 0;

    // Loads textures asynchronously.
    var load = function(path, texture) {
      textureLoader.load(path, function(loadedTexture) {
        textures[texture].texture = loadedTexture;
        progress++;

        // Once all textures are loaded the callback is called.
        // This allows chaining mesh loading which requires textures.
        if (progress >= goal) {
          if (callback != null) {
            callback();
          }

          return;
        }
      });
    };

    var textureLoader = new THREE.TextureLoader();

    // Begin the async load.
    for (var texture in textures) {
      var path = textures[texture].path;
      load(path, texture);
    }
  }

  function loadMeshes(callback) {
    var goal = Object.keys(meshes).length;
    var progress = 0;

    var jsonLoader = new THREE.JSONLoader();

    // Adds all meshes loaded into the scene.
    var addMeshes = function() {
      for (var mesh in meshes) {
        if (meshes[mesh].position != null) {
          // Apply the transformations next frame so the initial addition does
          // not overwrite anything we write to the matrix.
          queueNextFrame(function(args) {
            args.mesh.mesh.position.copy(args.mesh.position);
          }, {
            mesh: meshes[mesh]
          });
        }

        if (meshes[mesh].parent != null) {
          meshes[mesh].parent.add(meshes[mesh].mesh);
        } else {
          ginger.add(meshes[mesh].mesh);
        }
      }
    };

    // Loads the meshes asynchronously.
    var load = function(path, mesh) {
      jsonLoader.load(path, function(geometry) {
        var texture;

        if (meshes[mesh].texture != null) {
          texture = meshes[mesh].texture.texture;
        }

        var material = new THREE.MeshLambertMaterial({
          map: texture,
          morphTargets: meshes[mesh].morphTargets
        });

        meshes[mesh].mesh = new THREE.Mesh(geometry, material);
        progress++;

        // Once all meshes are loaded, all meshes are added to the scene.
        // Optionally a callback is available.
        if (progress >= goal) {
          addMeshes();

          if (callback != null) {
            callback();
          }

          return;
        }
      });
    };

    // Begin the async load.
    for (var mesh in meshes) {
      var path = meshes[mesh].path;
      load(path, mesh);
    }
  }

  function queueNextFrame(callback, args) {
    queue.push({
      callback: callback,
      args: args
    });
  }

  function onresize(event) {
    recalculateAspect();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }

  function onmousemove(event) {
    var mouse = new THREE.Vector3(
        (event.clientX / window.innerWidth) * 2 - 1,
        - (event.clientY / window.innerHeight) * 2 + 1,
        0.5
    );

    mouse.unproject(camera);

    // When getting the direction, flip the x and y axis or the eyes will
    // look the wrong direction.
    var direction = mouse.sub(camera.position).normalize();
    direction.x *= -1;
    direction.y *= -1;

    var distance = camera.position.z / direction.z;
    var position = camera.position.clone().add(direction.multiplyScalar(distance));

    leftEye.lookAt(position);
    rightEye.lookAt(position);

    // Move the head less than the eyes.
    ginger.lookAt(position);
    ginger.rotation.x /= 5;
    ginger.rotation.y /= 5;
    ginger.rotation.z = 0;
  }

  function recalculateAspect() {
    aspect = window.innerWidth / window.innerHeight;
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
  }

  function animate() {
    requestAnimationFrame(animate);

    var i = queue.length;
    while(i--) {
      queue[i].callback(queue[i].args);
      queue.splice(i, 1);
    }

    renderer.render(scene, camera);
  }

  return {
    init: function() {
      scene = new THREE.Scene();

      // Find the initial aspect.
      aspect = window.innerWidth / window.innerHeight;

      camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 10000);
      camera.position.y = 5;
      camera.position.z = 10;

      // Create a renderer the size of the entire window.
      renderer = new THREE.WebGLRenderer({
        antialias: true
      });
      renderer.setSize(window.innerWidth, window.innerHeight);

      // Add the canvas to the renderer wrapper so the panel
      // stays above the canvas.
      document.getElementById('renderer').appendChild(renderer.domElement);

      // Allow viewport resizing whenever the window resizes.
      window.onresize = onresize;

      // Setup event so ginger's eyes track the mouse.
      document.onmousemove = onmousemove;

      // Let there be light! The light is simply a directional light that
      // shines directly inter Ginger's face.
      var directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1);
      directionalLight.position.set(0, 0, 1);
      scene.add(directionalLight);

      // Ginger is the container for all the meshes.
      scene.add(ginger);

      leftEye.position.set(0.96, 6.169, 1.305);
      ginger.add(leftEye);

      rightEye.position.set(-0.96, 6.169, 1.305);
      ginger.add(rightEye);

      // Load ginger in the background.
      load();

      // Start the render loop.
      animate();
    }
  };
};

(function() {
  var ginger = new Ginger();
  ginger.init();
})();
<|endoftext|>


<commit_before>import {Router} from 'aurelia-router';
import {Todos} from './todos';

export class App {
  static inject() { return [Router]; }

  constructor(router) {
    this.router = router;
    this.router.configure(this.configureRoutes);
  }

  configureRoutes(cfg) {
    cfg.title = "TodoMVC";
    cfg.map([
      { route: ['', ':filter'],   moduleId: 'todos' }
    ]);
  }
}
<commit_msg>cleaned up code<commit_after>import {Router} from 'aurelia-router';
import {Todos} from './todos';

export class App {
  static inject() { return [Router]; }

  constructor(router) {
    this.router = router;
    this.router.configure(this.configureRoutes);
  }

  configureRoutes(cfg) {
    cfg.title = "TodoMVC";
    cfg.map([
      { route: ['', ':filter'], moduleId: 'todos' }
    ]);
  }
}
<|endoftext|>


<commit_before>// Load wetfish basic
var $ = require('wetfish-basic');
require('dragondrop');

// Miscellaneous helper functions
var helper =
{
    // Used to stack elements ontop of eachother as you move them
    layers: 0,

    addElement: function(element, options)
    {
        $('.workspace').el[0].appendChild(element);

        if(options.centered)
        {
            $(element).style({
                'position': 'absolute',
                'left': ($(window).width() / 2 - $(element).width() / 2) + 'px',
                'top': ($(window).height() / 2 - $(element).height() / 2) + 'px',
            });
        }

        if(options.duration)
        {
            setTimeout(function()
            {
                $(element).remove();
            }, options.duration);
        }

        $(element).dragondrop();

        $(element).on('dragstart', function()
        {
            helper.layers++;
            $(this).style({'z-index': helper.layers});
        });
    },

    addImage: function(src)
    {
        var image = document.createElement('img');
        $(image).attr('src', src);

        helper.addElement(image, {'centered': true});
    },

    random: function(min, max)
    {
        return Math.round(Math.random() * (max - min)) + min;
    }
};

module.exports = helper;
<commit_msg>Always add new images on the top layer<commit_after>// Load wetfish basic
var $ = require('wetfish-basic');
require('dragondrop');

// Miscellaneous helper functions
var helper =
{
    // Used to stack elements ontop of eachother as you move them
    layers: 0,

    addElement: function(element, options)
    {
        $('.workspace').el[0].appendChild(element);

        if(options.centered)
        {
            $(element).style({
                'position': 'absolute',
                'left': ($(window).width() / 2 - $(element).width() / 2) + 'px',
                'top': ($(window).height() / 2 - $(element).height() / 2) + 'px',
            });
        }

        if(options.duration)
        {
            setTimeout(function()
            {
                $(element).remove();
            }, options.duration);
        }

        $(element).dragondrop();

        $(element).on('dragstart', function()
        {
            helper.layers++;
            $(this).style({'z-index': helper.layers});
        });
    },

    addImage: function(src)
    {
        var image = document.createElement('img');
        $(image).attr('src', src);
        $(image).style({'z-index': helper.layers + 1});

        helper.addElement(image, {'centered': true});
    },

    random: function(min, max)
    {
        return Math.round(Math.random() * (max - min)) + min;
    }
};

module.exports = helper;
<|endoftext|>


<commit_before>var assert = require('assert');
var runner = require('./lib/runner');
var test = runner.test.bind(runner);

var util = require('../src/util');
runner.subject('util');

runner.subject('normalizeLink');

test('returns only host and pathname', function() {
  var link = 'http://some-domain.com/some-path?some-query#some-fragment';
  assert.equal(util.normalizeLink(link), 'some-domain.com/some-path');
});

test("does not include 'www'", function() {
  assert.equal(util.normalizeLink('http://www.some-domain.com/'), 'some-domain.com/');
});

runner.subject('callOn');

test('returns function that calls original on nth call', function() {
  var calls = 0;
  function fn() { calls += 1; }
  var deferredFn = util.callOn(2, fn);
  deferredFn();
  assert.equal(calls, 0, 'not yet called');
  deferredFn();
  assert.equal(calls, 1, 'called');
  deferredFn();
  assert.equal(calls, 2, 'subsequent calls pass through');
});

runner.subject('nthIndexOf');

test('returns nth index of search value', function() {
  var string = 'first line\nsecond line\nthird line\n';
  assert.equal(util.nthIndexOf(string, '\n', 2), 22);
  assert.equal(util.nthIndexOf(string, 'f', 1), 0, 'handles edge cases');
});

test("returns '-1' if not found, like indexOf", function() {
  var string = 'first line\nsecond line\nthird line\n';
  assert.equal(util.nthIndexOf(string, '\n', 4), -1, 'not found if out of bounds');
  assert.equal(util.nthIndexOf(string, '1', 1), -1, 'not found if true');
});

runner.report();
<commit_msg>Minor test refactor<commit_after>var assert = require('assert');
var runner = require('./lib/runner');
var test = runner.test.bind(runner);

var util = require('../src/util');
runner.subject('util');

runner.subject('normalizeLink');

test('returns only host and pathname', function() {
  var link = 'http://some-domain.com/some-path?some-query#some-fragment';
  assert.equal(util.normalizeLink(link), 'some-domain.com/some-path');
});

test("does not include 'www'", function() {
  assert.equal(util.normalizeLink('http://www.some-domain.com/'), 'some-domain.com/');
});

runner.subject('callOn');

test('returns function that calls original on nth call', function() {
  var calls = 0;
  function fn() { calls += 1; }
  var deferredFn = util.callOn(2, fn);
  deferredFn();
  assert.equal(calls, 0, 'not yet called');
  deferredFn();
  assert.equal(calls, 1, 'called');
  deferredFn();
  assert.equal(calls, 2, 'subsequent calls pass through');
});

(function() {
  var string = 'first line\nsecond line\nthird line\n';

  runner.subject('nthIndexOf');

  test('returns nth index of search value', function() {
    assert.equal(util.nthIndexOf(string, '\n', 2), 22);
    assert.equal(util.nthIndexOf(string, 'f', 1), 0, 'handles edge cases');
  });

  test("returns '-1' if not found, like indexOf", function() {
    assert.equal(util.nthIndexOf(string, '\n', 4), -1, 'not found if out of bounds');
    assert.equal(util.nthIndexOf(string, '1', 1), -1, 'not found if true');
  });
}());

runner.report();
<|endoftext|>


<commit_before>'use strict';

const React = require('react');
const ReactDOM = require('react-dom');
const moment = require('moment');
//const fetch = require('whatwg-fetch');
const LineChart = require('react-d3-basic').LineChart;

(() => {
  const endMaker = (date, range) => {
    return moment(date)
      .add(1, range)
      .subtract(1, 'millisecond')
  };

  class Content extends React.Component{
    constructor() {
      super();
      const now = moment(),
            today = moment()
              .year(now.year())
              .month(now.month())
              .day(now.day())
              .hour(0)
              .minute(0)
              .second(0)
              .millisecond(0);
      this.state = {
        startDate: today,
        endDate: endMaker(today, 'day'),
        range: 'day'
      };
    }
    previous() {
      this.setState({
        startDate: this.state.startDate.subtract(1, this.state.range),
        endDate: endMaker(this.state.startDate, this.state.range)
      });
    }
    next() {
      this.setState({
        startDate: this.state.startDate.add(1, this.state.range),
        endDate: endMaker(this.state.startDate, this.state.range)
      });
    }
    timespan(e) {
      this.setState({
        range: e.target.value,
        endDate: endMaker(this.state.startDate, e.target.value)
      });
    }
    render() {
      return(

The {this.state.range} starts at {this.state.startDate.format()}

The {this.state.range} ends at {this.state.endDate.format()}

          <button onClick={() => this.previous()}>Previous</button>
          <select onChange={(e) => this.timespan(e)}>
            <option value="day">Day</option>
            <option value="week">Week</option>
            <option value="month">Month</option>
            <option value="year">Year</option>
          </select>
          <button onClick={() => this.next()}>Next</button>

      )
    }
  };

  ReactDOM.render(
    <Content />,
    document.getElementById('app')
  );
})()
<commit_msg>Extracted rendered controls as separate component<commit_after>'use strict';

const React = require('react');
const ReactDOM = require('react-dom');
const moment = require('moment');
//const fetch = require('whatwg-fetch');
const LineChart = require('react-d3-basic').LineChart;

(() => {
  const endMaker = (date, range) => {
    return moment(date)
      .add(1, range)
      .subtract(1, 'millisecond')
  };

  class Content extends React.Component{
    constructor() {
      super();
      const now = moment(),
            today = moment()
              .year(now.year())
              .month(now.month())
              .day(now.day())
              .hour(0)
              .minute(0)
              .second(0)
              .millisecond(0);
      this.state = {
        startDate: today,
        endDate: endMaker(today, 'day'),
        range: 'day'
      };
    }
    previous() {
      this.setState({
        startDate: this.state.startDate.subtract(1, this.state.range),
        endDate: endMaker(this.state.startDate, this.state.range)
      });
    }
    next() {
      this.setState({
        startDate: this.state.startDate.add(1, this.state.range),
        endDate: endMaker(this.state.startDate, this.state.range)
      });
    }
    timespan(e) {
      this.setState({
        range: e.target.value,
        endDate: endMaker(this.state.startDate, e.target.value)
      });
    }
    render() {
      return(
        <Controls
          startDate={this.state.startDate}
          endDate={this.state.endDate}
          range={this.state.range}
          timespan={(e) => this.timespan(e)}
          previous={() => this.previous()}
          next={() => this.next()}
        />
      )
    }
  };

  function Controls(props) {
    return(

{props.range}

{props.startDate.format('M/D/YYYY h:mm a')} - {props.endDate.format('M/D/YYYY h:mm a')}

        <button onClick={() => props.previous()}>Previous</button>
        <select onChange={(e) => props.timespan(e)}>
          <option value="day">Day</option>
          <option value="week">Week</option>
          <option value="month">Month</option>
          <option value="year">Year</option>
        </select>
        <button onClick={() => props.next()}>Next</button>

    )
  };

  ReactDOM.render(
    <Content />,
    document.getElementById('app')
  );
})()
<|endoftext|>


<commit_before>hyloEnv.onUser(function(user) {

  // segment
  analytics.identify(user.id, {
    email: user.email,
    firstName: user.first_name,
    lastName: user.last_name,
    name: user.name,
    provider: user.linkedAccounts[0].provider_key,
    created: user.date_created
  }, {
    integrations: {
      Intercom: {
        user_hash: '<%= OpenSSL::HMAC.hexdigest("sha256", "fwnUBkiU2spjAlzNPDNCJhoI4iBQ66ap6XOnTznL", user.id) %>'
      }
    }
  });

  // rollbar
  _rollbarConfig.payload.person = {
    id: user.id,
    username: user.name,
    email: user.email
  };

  //intercom
  window.intercomSettings = {
    name: user.name,
    email: user.email,
    created_at: user.date_created,
    app_id: "wwelodje"
  };

(function(){
  var w=window;
  var ic=w.Intercom;
  if(typeof ic==="function"){
    ic('reattach_activator');
    ic('update',intercomSettings);
  }
  else {
    var d=document;
    var i=function() {
      i.c(arguments)
    };
    i.q=[];
    i.c=function(args) {
      i.q.push(args)
    };
    w.Intercom=i;
    function l(){
      var s=d.createElement('script');
      s.type='text/javascript';
      s.async=true;
      s.src='https://widget.intercom.io/widget/wwelodje';
      var x=d.getElementsByTagName('script')[0];
      x.parentNode.insertBefore(s,x);
    }
    if(w.attachEvent){
      w.attachEvent('onload',l);
    }
    else {
      w.addEventListener('load',l,false);
    }
  }
})()

});

window.fbAsyncInit = function() {
  FB.init({appId: hyloEnv.fb.appId, xfbml: true, version: 'v2.1'});
};

(function(d, s, id){
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) {return;}
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

// Prevents backspace except in the case of textareas and text inputs to prevent user navigation.
$(document).keydown(function (e) {
  var preventKeyPress;
  if (e.keyCode == 8) {
    var d = e.srcElement || e.target;
    switch (d.tagName.toUpperCase()) {
      case 'TEXTAREA':
        preventKeyPress = d.readOnly || d.disabled;
        break;
      case 'INPUT':
        preventKeyPress = d.readOnly || d.disabled ||
        (d.attributes["type"] && $.inArray(d.attributes["type"].value.toLowerCase(), ["radio", "checkbox", "submit", "button"]) >= 0);
        break;
      case 'DIV':
        preventKeyPress = d.readOnly || d.disabled || !(d.attributes["contentEditable"] && d.attributes["contentEditable"].value == "true");
        break;
      default:
        preventKeyPress = true;
        break;
    }
  }
  else
    preventKeyPress = false;

  if (preventKeyPress) {
    console.log("preventing backspace");
    e.preventDefault();
  }
});
<commit_msg>add secure key for intercom<commit_after>hyloEnv.onUser(function(user) {

  // segment
  analytics.identify(user.id, {
    email: user.email,
    firstName: user.first_name,
    lastName: user.last_name,
    name: user.name,
    provider: user.linkedAccounts[0].provider_key,
    created: user.date_created
  });

  // rollbar
  _rollbarConfig.payload.person = {
    id: user.id,
    username: user.name,
    email: user.email
  };

  //intercom
  window.intercomSettings = {
    name: user.name,
    email: user.email,
    created_at: user.date_created,
    app_id: "wwelodje",
    user_hash:  'hash_hmac("sha256", $user->email, "wn5VnqcseKp5ihXlonHGmvukuI9R4HSb34K6CFFo")'
  };

  (function(){
    var w=window;
    var ic=w.Intercom;
    if(typeof ic==="function"){
      ic('reattach_activator');
      ic('update',intercomSettings);
    }
    else {
      var d=document;
      var i=function() {
        i.c(arguments)
      };
      i.q=[];
      i.c=function(args) {
        i.q.push(args)
      };
      w.Intercom=i;
      function l(){
        var s=d.createElement('script');
        s.type='text/javascript';
        s.async=true;
        s.src='https://widget.intercom.io/widget/wwelodje';
        var x=d.getElementsByTagName('script')[0];
        x.parentNode.insertBefore(s,x);
      }
      if(w.attachEvent){
        w.attachEvent('onload',l);
      }
      else {
        w.addEventListener('load',l,false);
      }
    }
  })()

});

window.fbAsyncInit = function() {
  FB.init({appId: hyloEnv.fb.appId, xfbml: true, version: 'v2.1'});
};

(function(d, s, id){
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) {return;}
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_US/sdk.js";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));

// Prevents backspace except in the case of textareas and text inputs to prevent user navigation.
$(document).keydown(function (e) {
  var preventKeyPress;
  if (e.keyCode == 8) {
    var d = e.srcElement || e.target;
    switch (d.tagName.toUpperCase()) {
      case 'TEXTAREA':
        preventKeyPress = d.readOnly || d.disabled;
        break;
      case 'INPUT':
        preventKeyPress = d.readOnly || d.disabled ||
        (d.attributes["type"] && $.inArray(d.attributes["type"].value.toLowerCase(), ["radio", "checkbox", "submit", "button"]) >= 0);
        break;
      case 'DIV':
        preventKeyPress = d.readOnly || d.disabled || !(d.attributes["contentEditable"] && d.attributes["contentEditable"].value == "true");
        break;
      default:
        preventKeyPress = true;
        break;
    }
  }
  else
    preventKeyPress = false;

  if (preventKeyPress) {
    console.log("preventing backspace");
    e.preventDefault();
  }
});
<|endoftext|>


<commit_before>import express from 'express';
import path from 'path';
import logger from 'morgan';
import bodyParser from 'body-parser';
import routes from './routes';

const app = express();
app.disable('x-powered-by');

// View engine setup
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'pug');

app.use(logger('dev', {
  skip: () => app.get('env') === 'test'
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, '../public')));

// Routes
app.use('/', routes);

// Catch 404 and forward to error handler
app.use((req, res, next) => {
  const err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// Error handler
app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
  res
    .status(err.status || 500)
    .render('error', {
      message: err.message
    });
});

export default app;
<commit_msg>Trigger build<commit_after>import express from 'express';
import path from 'path';
import logger from 'morgan';
import bodyParser from 'body-parser';
import routes from './routes';

const app = express();
app.disable('x-powered-by');

// View engine setup
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'pug');

app.use(logger('dev', {
  skip: () => app.get('env') === 'test'
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, '../public')));

// Routes
app.use('/', routes);

// Catch 404 and forward to error handler
app.use((req, res, next) => {
  const err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// Error handler
app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
  res
    .status(err.status || 500)
    .render('error', {
      message: err.message
    });
});

export default app;

<|endoftext|>


<commit_before>(function poll() {
  if (typeof ynabToolKit !== 'undefined' && ynabToolKit.actOnChangeInit === true) {
    ynabToolKit.enterInRegisterNow = (function () {
      let accountsController;
      let transactionViewModel;

      // this function was taken pretty much verbatim from YNAB source code
      // they have a function called generateUpcomingTransactionNow which takes
      // a list of entity ids to generate.
      function enterTransactionInRegisterNow(transactionsToEnter) {
        let entityManger = transactionViewModel.getEntityManager();
        entityManger.openChangeSet();

        let transactionIds = transactionsToEnter.map((t) => t.get('entityId'));

        try {
          transactionViewModel.getYNABDatabase()
            .generateUpcomingTransactionNow(transactionIds)
            .then(() => {
              entityManger.closeChangeSet();
              accountsController.send('closeModal');
            });
        } catch (e) {
          accountsController.send('closeModal');
          ynabToolKit.shared.showFeatureErrorModal('Enter In Register Now');
        }
      }

      function addOptionToContextMenu() {
        let selectedTransactions = accountsController.get('areChecked');
        let canEnterNow = selectedTransactions.every((t) => t.get('isScheduledTransaction'));

        if (!canEnterNow) return;

        $('.modal-account-edit-transaction-list .modal-list')
          .prepend(
            $(`

                <button class="button-list ynab-toolkit-enter-in-register-now">

                  Enter In Register Now
                </button>

`).click(() => {
                enterTransactionInRegisterNow(selectedTransactions);
              })
          );
      }

      return {
        invoke() {
          if (window.YNABFEATURES['enter-scheduled-transaction-now']) {
            return;
          }

          accountsController = ynabToolKit.shared.containerLookup('controller:accounts');
          transactionViewModel = accountsController.get('transactionViewModel');
          addOptionToContextMenu();
        },

        observe(changedNodes) {
          if (changedNodes.has('ynab-u modal-popup\nmodal-account-edit-transaction-list ember-view modal-overlay active')) {
            ynabToolKit.enterInRegisterNow.invoke();
          }
        }
      };
    }());

    ynabToolKit.enterInRegisterNow.invoke();
  } else {
    setTimeout(poll, 250);
  }
}());
<commit_msg>fix for when window.YNABFEATURES is undefined i.e. on the login page<commit_after>(function poll() {
  if (typeof ynabToolKit !== 'undefined' && ynabToolKit.actOnChangeInit === true) {
    ynabToolKit.enterInRegisterNow = (function () {
      let accountsController;
      let transactionViewModel;

      // this function was taken pretty much verbatim from YNAB source code
      // they have a function called generateUpcomingTransactionNow which takes
      // a list of entity ids to generate.
      function enterTransactionInRegisterNow(transactionsToEnter) {
        let entityManger = transactionViewModel.getEntityManager();
        entityManger.openChangeSet();

        let transactionIds = transactionsToEnter.map((t) => t.get('entityId'));

        try {
          transactionViewModel.getYNABDatabase()
            .generateUpcomingTransactionNow(transactionIds)
            .then(() => {
              entityManger.closeChangeSet();
              accountsController.send('closeModal');
            });
        } catch (e) {
          accountsController.send('closeModal');
          ynabToolKit.shared.showFeatureErrorModal('Enter In Register Now');
        }
      }

      function addOptionToContextMenu() {
        let selectedTransactions = accountsController.get('areChecked');
        let canEnterNow = selectedTransactions.every((t) => t.get('isScheduledTransaction'));

        if (!canEnterNow) return;

        $('.modal-account-edit-transaction-list .modal-list')
          .prepend(
            $(`

                <button class="button-list ynab-toolkit-enter-in-register-now">

                  Enter In Register Now
                </button>

`).click(() => {
                enterTransactionInRegisterNow(selectedTransactions);
              })
          );
      }

      return {
        invoke() {
          if (window.YNABFEATURES && window.YNABFEATURES.hasOwnProperty('enter-scheduled-transaction-now') && window.YNABFEATURES['enter-scheduled-transaction-now']) {
            return;
          }

          accountsController = ynabToolKit.shared.containerLookup('controller:accounts');
          transactionViewModel = accountsController.get('transactionViewModel');
          addOptionToContextMenu();
        },

        observe(changedNodes) {
          if (changedNodes.has('ynab-u modal-popup\nmodal-account-edit-transaction-list ember-view modal-overlay active')) {
            ynabToolKit.enterInRegisterNow.invoke();
          }
        }
      };
    }());

    ynabToolKit.enterInRegisterNow.invoke();
  } else {
    setTimeout(poll, 250);
  }
}());
<|endoftext|>


<commit_before>/* global L,
          API_URL,
          SHORT_CITY_NAMES,
          REVERSE_URL,
          map,
          sendClick
*/
"use strict";

/**
 * Un grand merci a @etalab, @yohanboniface, @cquest sans qui ce projet n"existerai pas.
 * Une grande partie de ce code vient de @etalab/adresse.data.gouv.fr
 */

var searchPoints = L.geoJson(null, {
  onEachFeature: function(feature, layer) {
    layer.on("click", function() {
      var zoom=16;
      switch (feature.properties.type) {
        case "housenumber":
          zoom = 18;
          break;
        case "street":
          zoom = 16;
          break;
        case "village":
          zoom = 12;
          break;
        case "city":
          zoom = 12;
          break;
        case "locality"
          zoom = 16;
          break;
        case "hamlet",
          zoom = 16;
          break;
        case "commune",
          zoom = 12;
          break;
        default:
          zoom = 16;
      }
      map.setView([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], zoom);
      sendClick(feature);
    });
    layer.bindPopup(feature.properties.name + "");
  }
});

var showSearchPoints = function(geojson) {
  searchPoints.clearLayers();
  searchPoints.addData(geojson);
};

var formatResult = function(feature, el) {
  var details = [],
    detailsContainer = L.DomUtil.create("small", "", el),
    title = L.DomUtil.create("strong", "", el);
  var types = {
    housenumber: "numéro",
    street: "rue",
    locality: "lieu-dit",
    hamlet: "hamlet",
    village: "village",
    city: "ville",
    commune: "commune"
  };
  title.innerHTML = feature.properties.name;
  if (types[feature.properties.type]) {
    L.DomUtil.create("span", "type", title).innerHTML = types[feature.properties.type];
  }
  if (feature.properties.city && feature.properties.city !== feature.properties.name) {
    details.push(feature.properties.city);
  }
  if (feature.properties.context) {
    details.push(feature.properties.context);
  }
  detailsContainer.innerHTML = details.join(", ");
};

/* eslint-disable no-unused-vars */
var photonControlOptions = {
  resultsHandler: showSearchPoints,
  placeholder: "Ex. 6 quai de la tourelle cergy…",
  position: "topright",
  url: API_URL,
  formatResult: formatResult,
  noResultLabel: "Aucun résultat",
  feedbackLabel: "Signaler",
  feedbackEmail: "julien.noblet+cad-killer@gmail.com",
  minChar: function(val) {
    return SHORT_CITY_NAMES.indexOf(val) !== -1 || val.length >= 3;
  },
  submitDelay: 200
};
/* eslint-enable no-unused-vars */

/* eslint-disable no-unused-vars */
var photonReverseControlOptions = {
  resultsHandler: showSearchPoints,
  position: "topleft",
  url: REVERSE_URL,
  formatResult: formatResult,
  noResultLabel: "Aucun résultat",
  tooltipLabel: "Cliquer sur la carte pour obtenir l\'adresse"
};
/* eslint-enable no-unused-vars */

var myPhoton = new L.Control.Photon(photonControlOptions);

searchPoints.addTo(map);

map.addControl(myPhoton);

/* eslint-disable no-proto */
myPhoton.search.__proto__.setChoice = function(choice) {
  choice = choice || this.RESULTS[this.CURRENT];
  if (choice) {
    sendSearch(choice.feature);
    this.hide();
    this.input.value = "";
    this.fire("selected", {
      choice: choice.feature
    });
    this.onSelected(choice.feature);
  }
};
/* eslint-enable no-proto*/
<commit_msg>Fix eslint<commit_after>/* global L,
          API_URL,
          SHORT_CITY_NAMES,
          REVERSE_URL,
          map,
          sendClick
*/
"use strict";

/**
 * Un grand merci a @etalab, @yohanboniface, @cquest sans qui ce projet n"existerai pas.
 * Une grande partie de ce code vient de @etalab/adresse.data.gouv.fr
 */

var searchPoints = L.geoJson(null, {
  onEachFeature: function(feature, layer) {
    layer.on("click", function() {
      var zoom=16;
      switch (feature.properties.type) {
        case "housenumber":
          zoom = 18;
          break;
        case "street":
          zoom = 16;
          break;
        case "village":
          zoom = 12;
          break;
        case "city":
          zoom = 12;
          break;
        case "locality":
          zoom = 16;
          break;
        case "hamlet":
          zoom = 16;
          break;
        case "commune":
          zoom = 12;
          break;
        default:
          zoom = 16;
      }
      map.setView([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], zoom);
      sendClick(feature);
    });
    layer.bindPopup(feature.properties.name + "");
  }
});

var showSearchPoints = function(geojson) {
  searchPoints.clearLayers();
  searchPoints.addData(geojson);
};

var formatResult = function(feature, el) {
  var details = [],
    detailsContainer = L.DomUtil.create("small", "", el),
    title = L.DomUtil.create("strong", "", el);
  var types = {
    housenumber: "numéro",
    street: "rue",
    locality: "lieu-dit",
    hamlet: "hamlet",
    village: "village",
    city: "ville",
    commune: "commune"
  };
  title.innerHTML = feature.properties.name;
  if (types[feature.properties.type]) {
    L.DomUtil.create("span", "type", title).innerHTML = types[feature.properties.type];
  }
  if (feature.properties.city && feature.properties.city !== feature.properties.name) {
    details.push(feature.properties.city);
  }
  if (feature.properties.context) {
    details.push(feature.properties.context);
  }
  detailsContainer.innerHTML = details.join(", ");
};

/* eslint-disable no-unused-vars */
var photonControlOptions = {
  resultsHandler: showSearchPoints,
  placeholder: "Ex. 6 quai de la tourelle cergy…",
  position: "topright",
  url: API_URL,
  formatResult: formatResult,
  noResultLabel: "Aucun résultat",
  feedbackLabel: "Signaler",
  feedbackEmail: "julien.noblet+cad-killer@gmail.com",
  minChar: function(val) {
    return SHORT_CITY_NAMES.indexOf(val) !== -1 || val.length >= 3;
  },
  submitDelay: 200
};
/* eslint-enable no-unused-vars */

/* eslint-disable no-unused-vars */
var photonReverseControlOptions = {
  resultsHandler: showSearchPoints,
  position: "topleft",
  url: REVERSE_URL,
  formatResult: formatResult,
  noResultLabel: "Aucun résultat",
  tooltipLabel: "Cliquer sur la carte pour obtenir l\'adresse"
};
/* eslint-enable no-unused-vars */

var myPhoton = new L.Control.Photon(photonControlOptions);

searchPoints.addTo(map);

map.addControl(myPhoton);

/* eslint-disable no-proto */
myPhoton.search.__proto__.setChoice = function(choice) {
  choice = choice || this.RESULTS[this.CURRENT];
  if (choice) {
    sendSearch(choice.feature);
    this.hide();
    this.input.value = "";
    this.fire("selected", {
      choice: choice.feature
    });
    this.onSelected(choice.feature);
  }
};
/* eslint-enable no-proto*/
<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var api = require('./routes/api');

var app = express();

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));

// PUBLIC
app.use('/', express.static(path.resolve(__dirname, '../public')));

// API
app.use('/api', api);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.send({
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500).end();
});

module.exports = app;
<commit_msg>added Cache Control for images<commit_after>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var api = require('./routes/api');

var app = express();

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));

// PUBLIC
app.use('/img', express.static(path.resolve(__dirname, '../public/img'),{ maxAge: 31557600000 }));
app.use('/', express.static(path.resolve(__dirname, '../public')));

// API
app.use('/api', api);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.send({
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500).end();
});

module.exports = app;
<|endoftext|>