diff --git a/Makefile b/Makefile
index b3bd444..b750655 100644
--- a/Makefile
+++ b/Makefile
@@ -43,14 +43,9 @@
 NAME = `$(CAT) framework/appinfo.json | $(GREP) '"id"' | $(CUT) -d \" -f 4`
 VERSION = `$(CAT) framework/appinfo.json | $(GREP) '"version"' | $(CUT) -d \" -f 4`
 
-all :: js copy_js package deploy run
+all :: copy_js package deploy run
 
-custom :: js copy_js package deploy
-
-clean :: clean_libs
-
-clean_libs:
-	-$(RM_RF) lib
+custom :: copy_js package deploy
 
 package:
 ifeq ($(UNAME), Linux)
@@ -93,35 +88,4 @@
 endif
 
 copy_js:
-	cp lib/cordova.js framework/cordova-$(PGVERSION).js
-
-js: lib/cordova.js
-
-lib/cordova.js: js/cordova-core.js js/acceleration.js js/accelerometer.js js/application.js js/audio.js js/camera.js js/compass.js js/contacts.js js/debugconsole.js js/device.js js/file.js js/geolocation.js js/map.js js/mojo.js js/mouse.js js/network.js js/notification.js js/orientation.js js/position.js js/service.js js/sms.js js/telephony.js js/window.js js/windowproperties.js lib/thumbs.0.5.2.js
-	$(MKPATH) lib
-	$(RM_F) $@
-	$(CAT) js/cordova-core.js >> $@
-	$(CAT) js/acceleration.js >> $@
-	$(CAT) js/accelerometer.js >> $@
-	$(CAT) js/application.js >> $@
-	$(CAT) js/audio.js >> $@
-	$(CAT) js/camera.js >> $@
-	$(CAT) js/contacts.js >> $@
-	$(CAT) js/compass.js >> $@
-	$(CAT) js/debugconsole.js >> $@
-	$(CAT) js/device.js >> $@
-	$(CAT) js/file.js >> $@
-	$(CAT) js/geolocation.js >> $@
-	$(CAT) js/map.js >> $@
-	$(CAT) js/mojo.js >> $@
-	$(CAT) js/mouse.js >> $@
-	$(CAT) js/network.js >> $@
-	$(CAT) js/notification.js >> $@
-	$(CAT) js/orientation.js >> $@
-	$(CAT) js/position.js >> $@
-	$(CAT) js/service.js >> $@
-	$(CAT) js/sms.js >> $@
-	$(CAT) js/telephony.js >> $@
-	$(CAT) js/window.js >> $@
-	$(CAT) js/windowproperties.js >> $@
-	$(CAT) lib/thumbs.0.5.2.js >> $@
\ No newline at end of file
+	cp lib/cordova.webos.js framework/cordova-$(PGVERSION).js
diff --git a/README.md b/README.md
index 907977d..e0a16e5 100755
--- a/README.md
+++ b/README.md
@@ -10,7 +10,6 @@
 -----------------------------------------------------
 Open a terminal, and navigate to the root Cordova webOS folder (where this readme.md file is located). A Makefile resides here; running make here will package your application, and install it to either the emulator, or the device. Or you can run make on individual target tasks:
 
-   - `make js` - builds Cordova.js from source javascript files to libs/Cordova.js
    - `make copy_js` - copies libs/Cordova.js to framework/Cordova.js - modify this path if you want Cordova.js in another location
    - `make package` - builds the webOS app (located in framework/) into an webOS .ipk installer package in the Cordova_root/palm/ folder
    - `make deploy` - installs the .ipk package to a device if detected, otherwise the emulator if its running 
@@ -38,9 +37,7 @@
 
 Notes & Caveats
 -----------------------------------------------------
- - In order to use the vibration API on palm, your application needs to have a "com.palm.*" namespace, as vibration on webOS is a private API. The caveat of doing this is that you are essentially indicating that your app should pretend to be a "Palm app" (rather than a Nitobi app, for example) ... and as a result your app will be denied from the Palm app catalog.
- - Currently the map.show function can only accept one position, as Palm uses google maps as its native maps application, and it only can take one marker as a parameter.
- - Touch event not supported, natively. Cordova now includes event handlers for mouse & touch events - please see the example app bundled with Cordova-webOS
+ - In order to use the vibration API on webOS, your application needs to have a "com.palm.*" namespace, as vibration on webOS is a private API. The caveat of doing this is that you are essentially indicating that your app should pretend to be a "Palm app" (rather than a Nitobi app, for example) ... and as a result your app will be denied from the App Catalog.
  - If using Lawnchair, the only supported adaptor is webkitsqlite.
  - html select boxes are implemented by Cordova, not supported natively (believe it or not). only the most basic functionality is implemented, so be aware using this control could cause problems.
  - To enable verbose logging, add the file framework_config.json to your framework/www/ folder, containing the following json content: { "logLevel": 99 }
@@ -49,4 +46,4 @@
 Helpful Links
 -----------------------------------------------------
   - Cordova Wiki: 				[wiki.apache.org/cordova](http://wiki.apache.org/cordova/)
-  - Palm webOS developer site: 	[developer.palm.com](http://developer.palm.com)
+  - HP webOS developer site: 	[developer.palm.com](http://developer.palm.com)
diff --git a/js/acceleration.js b/js/acceleration.js
deleted file mode 100644
index ce58b4c..0000000
--- a/js/acceleration.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class contains acceleration information
- * @constructor
- * @param {Number} x The force applied by the device in the x-axis.
- * @param {Number} y The force applied by the device in the y-axis.
- * @param {Number} z The force applied by the device in the z-axis.
- */
-function Acceleration(x, y, z) {
-	/*
-	 * The force applied by the device in the x-axis.
-	 */
-	this.x = x;
-	/*
-	 * The force applied by the device in the y-axis.
-	 */
-	this.y = y;
-	/*
-	 * The force applied by the device in the z-axis.
-	 */
-	this.z = z;
-	/*
-	 * The time that the acceleration was obtained.
-	 */
-	this.timestamp = new Date().getTime();
-};
-
-/*
- * This class specifies the options for requesting acceleration data.
- * @constructor
- */
-function AccelerationOptions() {
-	/*
-	 * The timeout after which if acceleration data cannot be obtained the errorCallback
-	 * is called.
-	 */
-	this.timeout = 10000;
-};
-
diff --git a/js/accelerometer.js b/js/accelerometer.js
deleted file mode 100644
index 670720c..0000000
--- a/js/accelerometer.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to device accelerometer data.
- * @constructor
- */
-function Accelerometer() {
-	/*
-	 * The last known acceleration.
-	 */
-	this.lastAcceleration = null;
-};
-
-/*
- * Tells WebOS to put higher priority on accelerometer resolution. Also relaxes the internal garbage collection events.
- * @param {Boolean} state
- * Dependencies: Mojo.windowProperties
- * Example:
- * 		navigator.accelerometer.setFastAccelerometer(true)
- */
-Accelerometer.prototype.setFastAccelerometer = function(state) {
-	navigator.windowProperties.fastAccelerometer = state;
-	navigator.window.setWindowProperties();
-};
-
-/*
- * Asynchronously aquires the current acceleration.
- * @param {Function} successCallback The function to call when the acceleration
- * data is available
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the acceleration data.
- * @param {AccelerationOptions} options The options for getting the accelerometer data
- * such as timeout.
- */
-
-Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) {
-
-    var referenceTime = 0;
-    if (this.lastAcceleration)
-        referenceTime = this.lastAcceleration.timestamp;
-    else
-        this.start();
- 
-    var timeout = 20000;
-    var interval = 500;
-    if (typeof(options) == 'object' && options.interval)
-        interval = options.interval;
- 
-    if (typeof(successCallback) != 'function')
-        successCallback = function() {};
-    if (typeof(errorCallback) != 'function')
-        errorCallback = function() {};
- 
-    var dis = this;
-    var delay = 0;
-    var timer = setInterval(function() {
-        delay += interval;
- 
-		//if we have a new acceleration, call success and cancel the timer
-        if (typeof(dis.lastAcceleration) == 'object' && dis.lastAcceleration != null && dis.lastAcceleration.timestamp > referenceTime) {
-            successCallback(dis.lastAcceleration);
-            clearInterval(timer);
-        } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer
-            errorCallback();
-            clearInterval(timer);
-        }
-		//else the interval gets called again
-    }, interval);
-};
-
-
-/*
- * Asynchronously aquires the acceleration repeatedly at a given interval.
- * @param {Function} successCallback The function to call each time the acceleration
- * data is available
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the acceleration data.
- * @param {AccelerationOptions} options The options for getting the accelerometer data
- * such as timeout.
- */
-
-Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) {
-	this.getCurrentAcceleration(successCallback, errorCallback, options);
-	// TODO: add the interval id to a list so we can clear all watches
- 	var frequency = (options != undefined)? options.frequency : 10000;
-	var that = this;
-	return setInterval(function() {
-		that.getCurrentAcceleration(successCallback, errorCallback, options);
-	}, frequency);
-};
-
-/*
- * Clears the specified accelerometer watch.
- * @param {String} watchId The ID of the watch returned from #watchAcceleration.
- */
-Accelerometer.prototype.clearWatch = function(watchId) {
-	clearInterval(watchId);
-};
-
-/*
- * Starts the native acceleration listener.
- */
-
-Accelerometer.prototype.start = function() {
-	var that = this;
-	//Mojo.Event.listen(document, "acceleration", function(event) {
-	document.addEventListener("acceleration", function(event) {
-		var accel = new Acceleration(event.accelX, event.accelY, event.accelZ);
-		that.lastAcceleration = accel;
-	});
-};
-
-if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer();
-
diff --git a/js/application.js b/js/application.js
deleted file mode 100644
index d432eca..0000000
--- a/js/application.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-function Application() {
-	
-};
-
-/*
- * Tell webOS to activate the current page of your app, bringing it into focus.
- * Example:
- * 		navigator.application.activate();
- */	
-Application.prototype.activate = function() {
-	PalmSystem.activate();
-};
-
-/*
- * Tell webOS to deactivate your app.
- * Example:
- *		navigator.application.deactivate();
- */	
-Application.prototype.deactivate = function() {
-	PalmSystem.deactivate();
-};
-
-/*
- * Returns the identifier of the current running application (e.g. com.yourdomain.yourapp).
- * Example:
- *		navigator.application.getIdentifier();
- */
-Application.prototype.getIdentifier = function() {
-	return PalmSystem.identifier;
-};
-
-if (typeof navigator.application == "undefined") navigator.application = new Application();
-
diff --git a/js/audio.js b/js/audio.js
deleted file mode 100644
index 1285e92..0000000
--- a/js/audio.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the device audio
- * @constructor
- */
-
-Cordova.overrideAudio = function() {
-	
-	Cordova.MojoAudio = Audio;
-	
-	Audio = function(src) {
-		this.src = src;							
-	};
-
-	Audio.prototype.play = function() {
-		// this.src = src;
-		// The 'end' event listener doesn't seem to work, so we have to call stop before playing
-		// otherwise, we'll never be able to play again
-		if (this.paused && !this.stopped) {
-			this.paused = false;
-			this.playing = true;	
-			this.audioPlayer.play();
-		} else {
-			if (this.audioPlayer)
-				this.stop();
-			if (!this.playing) {
-				this.paused = false;
-				this.playing = true;	
-				this.stopped = false;
-				this.audioPlayer = new Cordova.MojoAudio();
-				var file = Mojo.appPath + this.src;
-				if (this.audioPlayer.palm) {
-					this.audioPlayer.mojo.audioClass = "media";
-				}
-				this.audioPlayer.src = file;
-		
-				//event doesn't work, see above
-				this.audioPlayer.addEventListener('end', this.endHandler, false);
-				this.audioPlayer.play();
-			}
-		}
-	};
-
-	Audio.prototype.pause = function() {
-		if (this.stopped)
-			return;
-		this.paused = true;	
-		if (this.playing) {
-			this.playing = false;
-			this.stopped = false;
-			this.audioPlayer.pause();
-		} else {
-			this.playing = false;	
-			this.paused = false;
-			this.stopped = true;
-		}
-	};
-
-	Audio.prototype.stop = function() {
-		this.audioPlayer.pause();	
-		this.audioPlayer.src = null;
-		this.playing = false;	
-		this.paused = false;
-		this.stopped = true;
-	};
-
-	// End event handler not working (see comment in Audio.prototype.play)
-	Audio.prototype.endHandler = function () {
-		this.audioPlayer.removeEventListener('end', endHandler, false);
-		this.audioPlayer.pause();	
-		this.audioPlayer.src = null;
-		this.paused = false;
-		this.stopped = true;
-	};
-
-	/*
-	 * This class contains information about any Media errors.
-	 * @constructor
-	 */
-	MediaError = function() {
-		this.code = null,
-		this.message = "";
-	};
-
-	MediaError.MEDIA_ERR_ABORTED 		= 1;
-	MediaError.MEDIA_ERR_NETWORK 		= 2;
-	MediaError.MEDIA_ERR_DECODE 		= 3;
-	MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
-
-}
-
-document.addEventListener("deviceready", Cordova.overrideAudio, false);
-
diff --git a/js/camera.js b/js/camera.js
deleted file mode 100644
index 0c80146..0000000
--- a/js/camera.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the device camera.
- * @constructor
- */
-function Camera() {
-	
-};
-
-/*
- * @param {Function} successCallback
- * @param {Function} errorCallback
- * @param {Object} options
- */
-Camera.prototype.getPicture = function(successCallback, errorCallback, options) {
-
-	var filename = "";
-
-	if (typeof options != 'undefined' && typeof options.filename != 'undefined') {
-		filename = options.filename;
-	}	
-
-	this.service = navigator.service.Request('palm://com.palm.applicationManager', {
-		method: 'launch',
-		parameters: {
-		id: 'com.palm.app.camera',
-		params: {
-				appId: 'com.palm.app.camera',
-				name: 'capture',
-				sublaunch: true,
-				filename: filename
-			}
-		},
-		onSuccess: successCallback,
-		onFailure: errorCallback
-	});	
-};
-
-if (typeof navigator.camera == 'undefined') navigator.camera = new Camera();
-
diff --git a/js/compass.js b/js/compass.js
deleted file mode 100644
index d79a4aa..0000000
--- a/js/compass.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to device compass data.
- * @constructor
- */
-function Compass() {
-  /*
-	 * The last known heading.
-	 */
-	this.lastHeading = null;//new CompassHeading;
-};
-
-/*
- * Asynchronously aquires the current compass heading.
- * @param {Function} successCallback The function to call when the compass
- * data is available
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the compass data.
- * @param {CompassOptions} options The options for getting the compass data
- * such as timeout.
- */
-
-Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) {
-
-    var referenceTime = 0;
-	var compassHeading = new CompassHeading();
-
-    if (this.lastHeading)
-        referenceTime = this.lastHeading.timestamp;
-    else
-        this.start();
- 
-    var timeout = 20000;
-    var interval = 500;
-    if (typeof(options) == 'object' && options.interval)
-        interval = options.interval;
- 
-    if (typeof(successCallback) != 'function')
-        successCallback = function() {};
-    if (typeof(errorCallback) != 'function')
-        errorCallback = function() {};
- 
-    var dis = this;
-    var delay = 0;
-    var timer = setInterval(function() {
-        delay += interval;
- 
-		//if we have a new compass heading, call success and cancel the timer
-        if (typeof(dis.lastHeading) == 'object' && dis.lastHeading != null && dis.lastHeading.timestamp > referenceTime) {
-
-			compassHeading.timestamp = new Date(referenceTime);
-			compassHeading.magneticHeading = dis.lastHeading.magHeading;
-			compassHeading.trueHeading = dis.lastHeading.trueHeading;
-			
-			if (dis.lastHeading.headingAccuracy === undefined)
-				compassHeading.headingAccuracy = 1;
-			else
-				compassHeading.headingAccuracy = dis.lastHeading.headingAccuracy;
-
-			successCallback(compassHeading);
-
-            //successCallback(dis.lastHeading.magHeading);
-            clearInterval(timer);
-        } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer
-            errorCallback();
-            clearInterval(timer);
-        }
-		//else the interval gets called again
-    }, interval);
-};
-
-
-/*
- * Asynchronously aquires the compass heading repeatedly at a given interval.
- * @param {Function} successCallback The function to call each time the acceleration
- * data is available
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the compass data.
- * @param {CompassOptions} options The options for getting the compass data
- * such as timeout.
- */
-
-Compass.prototype.watchHeading = function(successCallback, errorCallback, options) {
-	this.getCurrentHeading(successCallback, errorCallback, options);
-	// TODO: add the interval id to a list so we can clear all watches
- 	var frequency = (options != undefined)? options.frequency : 10000;
-	var that = this;
-	return setInterval(function() {
-		that.getCurrentHeading(successCallback, errorCallback, options);
-	}, frequency);
-};
-
-/*
- * Clears the specified heading watch.
- * @param {String} watchId The ID of the watch returned from #watchHeading.
- */
-Compass.prototype.clearWatch = function(watchId) {
-	clearInterval(watchId);
-};
-
-/*
- * Starts the native compass listener.
- */
-
-Compass.prototype.start = function() {
-	var that = this;
-	//Mojo.Event.listen(document, "acceleration", function(event) {
-	document.addEventListener("compass", function(event) {
-		var heading={};
-    heading.trueHeading=event.trueHeading;
-    heading.magHeading=event.magHeading;
-    heading.timestamp = new Date().getTime();
-		that.lastHeading = heading;
-	});
-};
-
-function CompassHeading(mHeading, tHeading, accuracy, time) {
-	if (mHeading === undefined)
-		this.magneticHeading = null;
-	else
-		this.magneticHeading = mHeading;
-		
-	if (tHeading === undefined)
-		this.trueHeading = null;
-	else
-		this.trueHeading = tHeading;
-		
-	if (accuracy === undefined)	
-		this.headingAccuracy = null;
-	else
-		this.headingAccuracy = accuracy;
-		
-	if (time === undefined)	
-		this.timestamp = new Date();
-	else
-		this.timestamp = new Date(time);
-};
-
-function CompassError() {
-	this.code = null;
-	this.message = "";	
-};
-
-CompassError.COMPASS_INTERNAL_ERR = 0;
-CompassError.COMPASS_NOT_SUPPORTED = 20;
-
-if (typeof navigator.compass == "undefined") navigator.compass = new Compass();
diff --git a/js/contacts.js b/js/contacts.js
deleted file mode 100644
index 3a11064..0000000
--- a/js/contacts.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the device contacts.
- * @constructor
- */
-
-function Contacts() {
-	
-};
-
-function Contact() {
-    this.phones = [];
-    this.emails = [];
-	this.name = {
-		givenName: "",
-		familyName: "",
-		formatted: ""
-	};
-	this.id = "";
-};
-
-Contact.prototype.displayName = function()
-{
-    // TODO: can be tuned according to prefs
-	return this.givenName + " " + this.familyName;
-};
-
-function ContactsFilter(name) {
-	if (name)
-		this.name = name;
-	else
-		this.name = "";
-};
-
-/*
- * @param {ContactsFilter} filter Object with filter properties. filter.name only for now.
- * @param {function} successCallback Callback function on success
- * @param {function} errorCallback Callback function on failure
- * @param {object} options Object with properties .page and .limit for paging
- */
-
-Contacts.prototype.find = function(filter, successCallback, errorCallback, options) {
-	errorCallback({ name: "ContactsError", message: "Cordova Palm contacts not implemented" });
-};
-
-Contacts.prototype.success_callback = function(contacts_iterator) {
-};
-
-if (typeof navigator.contacts == "undefined") navigator.contacts = new Contacts();
diff --git a/js/cordova-core.js b/js/cordova-core.js
deleted file mode 100644
index 1120792..0000000
--- a/js/cordova-core.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-if (typeof(DeviceInfo) != 'object')
-    DeviceInfo = {};
-
-function Cordova() {
-	ready = true;
-	available = true;
-	sceneController = null;	
-}; 
-
-
-Cordova.exec = function(win, fail, clazz, action, args) {
-
- setTimeout(function() { 
-	 Cordova.plugins[clazz].execute(action, args, win, fail); 
-   }, 0);
-
-}
-
-Cordova.checkArgs = function(args, func) {
-    if (typeof args == 'object')
-        func.apply(null, args);
-    else
-        func(args);
-}
-
-Cordova.callback = function(success, win, fail) {
-	if (success)
-		win();
-	else
-		fail();    
-}
-
-// translates the action into an API call
-accelerometerAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'setFastAccelerometer':				
-				Cordova.checkArgs(args, navigator.accelerometer.setFastAccelerometer);    
-				actionFound = true; 
-				break;
-			case 'getCurrentAcceleration':
-				Cordova.checkArgs(args, navigator.accelerometer.getCurrentAcceleration);
-				actionFound = true;
-				break;	
-			case 'watchAcceleration':
-			    Cordova.checkArgs(args, navigator.accelerometer.watchAcceleration);
-			    actionFound = true;
-			    break;
-			case 'clearWatch':
-			    Cordova.checkArgs(args, navigator.accelerometer.clearWatch);
-			    actionFound = true;
-			    break;
-			case 'start':
-			    Cordova.checkArgs(args, navigator.accelerometer.start);
-			    actionFound = true;
-			    break;      		
-		}
-
-        Cordova.callback(actionFound, win, fail);
-    }
-}
-
-applicationAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'activate':				
-				Cordova.checkArgs(args, navigator.application.activate);    
-				actionFound = true; 
-				break;
-			case 'deactivate':
-				Cordova.checkArgs(args, navigator.application.deactivate);
-				actionFound = true;
-				break;	
-			case 'getIdentifier':
-			    Cordova.checkArgs(args, navigator.application.getIdentifier);
-			    actionFound = true;
-			    break;      		
-		}
-
-		Cordova.callback(actionFound, win, fail);       
-    }
-}
-
-cameraAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'getPicture':
-				console.log("in here");
-				Cordova.checkArgs(args, navigator.camera.getPicture);    
-				actionFound = true; 
-				break;      		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-// translates the action into an API call
-compassAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'getCurrentHeading':
-				Cordova.checkArgs(args, navigator.compass.getCurrentHeading);
-				actionFound = true;
-				break;	
-			case 'watchHeading':
-			    Cordova.checkArgs(args, navigator.compass.watchHeading);
-			    actionFound = true;
-			    break;
-			case 'clearWatch':
-			    Cordova.checkArgs(args, navigator.compass.clearWatch);
-			    actionFound = true;
-			    break;
-			case 'start':
-			    Cordova.checkArgs(args, navigator.compass.start);
-			    actionFound = true;
-			    break;      		
-		}
-
-        Cordova.callback(actionFound, win, fail);
-    }
-}
-
-debugAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'log':				
-				Cordova.checkArgs(args, window.debug.log);    
-				actionFound = true; 
-				break;
-		    case 'warn':
-			    Cordova.checkArgs(args, window.debug.warn);    
-			    actionFound = true; 
-			    break;		    
-		    case 'error':
-			    Cordova.checkArgs(args, window.debug.error);    
-			    actionFound = true; 
-			    break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-deviceAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'getDeviceInfo':				
-				Cordova.checkArgs(args, navigator.device.getDeviceInfo);    
-				actionFound = true; 
-				break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-geolocationAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'getCurrentPosition':				
-				Cordova.checkArgs(args, navigator.geolocation.getCurrentPosition);    
-				actionFound = true; 
-				break; 
-			case 'watchPosition':				
-				Cordova.checkArgs(args, navigator.geolocation.watchPosition);    
-				actionFound = true; 
-				break;
-			case 'clearWatch':
-			    Cordova.checkArgs(args, navigator.geolocation.clearWatch);    
-			    actionFound = true; 
-			    break;
-			case 'start':
-			    Cordova.checkArgs(args, navigator.geolocation.start);    
-			    actionFound = true; 
-			    break;
-			case 'stop':
-			    Cordova.checkArgs(args, navigator.geolocation.stop);    
-			    actionFound = true; 
-			    break;								   	          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-mapAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'show':				
-				Cordova.checkArgs(args, navigator.map.show);    
-				actionFound = true; 
-				break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-mouseAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'simulateMouseClick':				
-				Cordova.checkArgs(args, navigator.mouse.simulateMouseClick);    
-				actionFound = true; 
-				break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-} 
-
-networkAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'isReachable':				
-				Cordova.checkArgs(args, navigator.network.isReachable);    
-				actionFound = true; 
-				break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-notificationAPI = {
-    execute: function(action, args, win, fail) {
-		var actionFound = false;
-		switch(action) {
-			case 'alert':				
-				Cordova.checkArgs(args, navigator.notification.alert);    
-				actionFound = true; 
-				break;
-			case 'showBanner':
-				Cordova.checkArgs(args, navigator.notification.showBanner);
-				actionFound = true;
-				break;	
-			case 'newDashboard':
-			    Cordova.checkArgs(args, navigator.notification.newDashboard);
-			    actionFound = true;
-			    break;
-			case 'removeBannerMessage':
-			    Cordova.checkArgs(args, navigator.notification.removeBannerMessage);
-			    actionFound = true;
-			    break;
-			case 'clearBannerMessage':
-			    Cordova.checkArgs(args, navigator.notification.clearBannerMessage);
-			    actionFound = true;
-			    break;
-			case 'vibrate':            
-			    Cordova.checkArgs(args, navigator.notification.vibrate);
-			    actionFound = true;
-			    break;
-			case 'beep':               
-			    Cordova.checkArgs(args, navigator.notification.beep);
-			    actionFound = true;
-			    break;       		
-		}
-
-		Cordova.callback(actionFound, win, fail);
-   }
-}
-
-orientationAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'setOrientation':				
-				Cordova.checkArgs(args, navigator.orientation.setOrientation);    
-				actionFound = true; 
-				break;
-			case 'getOrientation':
-			    Cordova.checkArgs(args, navigator.orientation.getOrientation);    
-			    actionFound = true; 
-			    break;			    
-			case 'start':
-			    Cordova.checkArgs(args, navigator.orientation.start);    
-				actionFound = true; 
-				break;
-			case 'watchOrientation':
-			    Cordova.checkArgs(args, navigator.orientation.watchOrientation);    
-				actionFound = true; 
-				break;
-			case 'clearWatch':
-                Cordova.checkArgs(args, navigator.orientation.clearWatch);    
-			    actionFound = true; 
-			    break;
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-smsAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'send':				
-				Cordova.checkArgs(args, navigator.sms.send);    
-				actionFound = true; 
-				break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-telephonyAPI = {
-    execute: function(action, args, win, fail) {
-        var actionFound = false;
-		switch(action) {
-			case 'send':				
-				Cordova.checkArgs(args, navigator.telephony.send);    
-				actionFound = true; 
-				break;		          		
-		}
-
-		Cordova.callback(actionFound, win, fail);        
-    }
-}
-
-windowAPI = {
-    execute: function(action, args, win, fail) {
-   		var actionFound = false;
-   		switch(action) {
-   			case 'newCard':
-   			    Cordova.checkArgs(args, navigator.window.newCard);  				    
-   				actionFound = true; 
-   				break;
-   			case 'setFullScreen':
-   			  	Cordova.checkArgs(args, navigator.window.setFullScreen);
-   				actionFound = true; 
-   				break;
-   			case 'setWindowProperties':
-   			    Cordova.checkArgs(args, navigator.window.setWindowProperties);
-		        actionFound = true;
-		        break;   			
-   			case 'blockScreenTimeout':
-   			    Cordova.checkArgs(args, navigator.window.blockScreenTimeout);
-   			    actionFound = true;
-		        break;
-   			case 'setSubtleLightbar':
-   			    Cordova.checkArgs(args, navigator.window.setSubtleLightbar);
-   			    actionFound = true;
-   			    break;
-   				   			  	
-   		}
-
-   		Cordova.callback(actionFound, win, fail);
-      }    
-}
-
-// this mapping acts as a shim to the webOS APIs
-Cordova.plugins = {};
-Cordova.plugins['navigator.accelerometer'] = accelerometerAPI;
-Cordova.plugins['navigator.application'] = applicationAPI;
-Cordova.plugins['navigator.camera'] = cameraAPI;
-Cordova.plugins['navigator.compass'] = compassAPI;
-Cordova.plugins['window.debug'] = debugAPI;
-Cordova.plugins['navigator.device'] = deviceAPI;
-Cordova.plugins['navigator.geolocation'] = geolocationAPI;
-Cordova.plugins['navigator.map'] = mapAPI;
-Cordova.plugins['navigator.mouse'] = mouseAPI;
-Cordova.plugins['navigator.network'] = networkAPI; 
-Cordova.plugins['navigator.notification'] = notificationAPI;
-Cordova.plugins['navigator.orientation'] = orientationAPI; 
-Cordova.plugins['navigator.sms'] = smsAPI;
-Cordova.plugins['navigator.telephony'] = telephonyAPI;  
-Cordova.plugins['navigator.window'] = windowAPI;
-
-document.addEventListener('DOMContentLoaded', function () {
-    window.cordova = new Cordova();
-    navigator.device.deviceReady();
-});
diff --git a/js/debugconsole.js b/js/debugconsole.js
deleted file mode 100644
index 23dd8fe..0000000
--- a/js/debugconsole.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the debugging console.
- * @constructor
- */
-function DebugConsole() {
-};
-
-/*
- * Print a normal log message to the console
- * @param {Object|String} message Message or object to print to the console
- */
-DebugConsole.prototype.log = function(message) {
-	if (typeof message == 'object')
-		message = Object.toJSON(message);   
-		
-	this.error(message);
-};
-
-/*
- * Print a warning message to the console
- * @param {Object|String} message Message or object to print to the console
- */
-DebugConsole.prototype.warn = function(message) {
-	if (typeof message == 'object')
-		message = Object.toJSON(message);    
-		
-	this.error(message);
-};
-
-/**
- * Print an error message to the console
- * @param {Object|String} message Message or object to print to the console
- */
-DebugConsole.prototype.error = function(message) {
-	if (typeof message == 'object')
-		message = Object.toJSON(message);
- 
-	console.log(JSON.stringify(message));
-};
-
-if (typeof window.debug == "undefined") window.debug = new DebugConsole();
diff --git a/js/device.js b/js/device.js
deleted file mode 100644
index 9fa543a..0000000
--- a/js/device.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
- * phone, etc.
- * @constructor
- */
-function Device() {
-    this.platform = "palm";
-    this.version  = null;
-    this.name     = null;
-    this.uuid     = null;
-    this.deviceInfo = null;
-};
-
-/*
- * A direct call to return device information.
- * Example:
- *		var deviceinfo = JSON.stringify(navigator.device.getDeviceInfo()).replace(/,/g, ', ');
- */
-Device.prototype.getDeviceInfo = function() {
-	return this.deviceInfo;//JSON.parse(PalmSystem.deviceInfo);
-};
-
-/*
- * needs to be invoked in a <script> nested within the <body> it tells WebOS that the app is ready
-        TODO: see if we can get this added as in a document.write so that the user doesn't have to explicitly call this method
- * Dependencies: Mojo.onKeyUp
- * Example:
- *		navigator.device.deviceReady();
- */	
-Device.prototype.deviceReady = function() {
-
-	// tell webOS this app is ready to show
-	if (window.PalmSystem) {
-		// setup keystroke events for forward and back gestures
-		document.body.addEventListener("keyup", Mojo.onKeyUp, true);
-
-		setTimeout(function() { PalmSystem.stageReady(); PalmSystem.activate(); }, 1);
-		alert = this.showBanner;
-	}
-
-    // fire deviceready event; taken straight from phonegap-iphone
-    // put on a different stack so it always fires after DOMContentLoaded
-    window.setTimeout(function () {
-        var e = document.createEvent('Events');
-        e.initEvent('deviceready');
-        document.dispatchEvent(e);
-    }, 10);
-	
-	this.setUUID();
-	this.setDeviceInfo();
-};
-
-Device.prototype.setDeviceInfo = function() {
-    var parsedData = JSON.parse(PalmSystem.deviceInfo);
-    
-    this.deviceInfo = parsedData;
-    this.version = parsedData.platformVersion;
-    this.name = parsedData.modelName;
-};
-
-Device.prototype.setUUID = function() {
-	//this is the only system property webos provides (may change?)
-	var that = this;
-	this.service = navigator.service.Request('palm://com.palm.preferences/systemProperties', {
-	    method:"Get",
-	    parameters:{"key": "com.palm.properties.nduid" },
-	    onSuccess: function(result) {
-			that.uuid = result["com.palm.properties.nduid"];
-		}
-    });	
-
-
-};
-
-
-if (typeof window.device == 'undefined') window.device = navigator.device = new Device();
-
diff --git a/js/file.js b/js/file.js
deleted file mode 100644
index e585e38..0000000
--- a/js/file.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides generic read and write access to the mobile device file system.
- */
-function File() {
-	/**
-	 * The data of a file.
-	 */
-	this.data = "";
-	/**
-	 * The name of the file.
-	 */
-	this.name = "";
-};
-
-/*
- * Reads a file from the mobile device. This function is asyncronous.
- * @param {String} fileName The name (including the path) to the file on the mobile device. 
- * The file name will likely be device dependant.
- * @param {Function} successCallback The function to call when the file is successfully read.
- * @param {Function} errorCallback The function to call when there is an error reading the file from the device.
- */
-File.prototype.read = function(fileName, successCallback, errorCallback) {
-	//Mojo has no file i/o yet, so we use an xhr. very limited
-	var path = fileName;	//incomplete
-	//Mojo.Log.error(path);
-	navigator.debug.error(path);
-	
-	if (typeof successCallback != 'function')
-		successCallback = function () {};
-	if (typeof errorCallback != 'function')
-		errorCallback = function () {};
-	
-	var xhr = new XMLHttpRequest();
-	xhr.onreadystatechange = function() {
-		if (xhr.readyState == 4) {
-			if (xhr.status == 200 && xhr.responseText != null) {
-				this.data = xhr.responseText;
-				this.name = path;
-				successCallback(this.data);
-			} else {
-				errorCallback({ name: xhr.status, message: "could not read file: " + path });
-			}
-		}
-	};
-	xhr.open("GET", path, true);
-	xhr.send();
-};
-
-/*
- * Writes a file to the mobile device. 
- * @param {File} file The file to write to the device.
- */
-File.prototype.write = function(file) {
-	//Palm does not provide file i/o
-};
-
-if (typeof navigator.file == "undefined") navigator.file = new File();
-
diff --git a/js/geolocation.js b/js/geolocation.js
deleted file mode 100644
index 519b987..0000000
--- a/js/geolocation.js
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to device GPS data.
- * @constructor
- */
-function Geolocation() {
-    /**
-     * The last known GPS position.
-     */
-    this.lastPosition = null;
-    this.lastError = null;
-    this.callbacks = {
-        onLocationChanged: [],
-        onError: []
-    };
-};
-
-/*
- * Asynchronously aquires the current position.
- * @param {Function} successCallback The function to call when the position
- * data is available
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the position data.
- * @param {PositionOptions} options The options for getting the position data
- * such as timeout.
- */
-Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) {
-    /*
-	var referenceTime = 0;
-    if (this.lastPosition)
-        referenceTime = this.lastPosition.timestamp;
-    else
-        this.start(options);
-	*/
-
-    var timeout = 20000;
-    if (typeof(options) == 'object' && options.timeout)
-    timeout = options.timeout;
-
-    if (typeof(successCallback) != 'function')
-    successCallback = function() {};
-    if (typeof(errorCallback) != 'function')
-    errorCallback = function() {};
-
-    /*
-    var dis = this;
-    var delay = 0;
-    var timer = setInterval(function() {
-        delay += interval;
-		
-		//if we have a new position, call success and cancel the timer
-        if (dis.lastPosition && typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) {
-            successCallback(dis.lastPosition);
-            clearInterval(timer);
-        } else if (delay >= timeout) { //else if timeout has occured then call error and cancel the timer
-            errorCallback();
-            clearInterval(timer);
-        }
-		//else the interval gets called again
-    }, interval);
-	*/
-
-    var responseTime;
-    if (timeout <= 5000)
-    responseTime = 1;
-    else if (5000 < timeout <= 20000)
-    responseTime = 2;
-    else
-    responseTime = 3;
-
-    var timer = setTimeout(function() {
-        errorCallback({
-            message: "timeout"
-        });
-    },
-    timeout);
-
-    var startTime = (new Date()).getTime();
-
-    var alias = this;
-
-    // It may be that getCurrentPosition is less reliable than startTracking ... but
-    // not sure if we want to be starting and stopping the tracker if we're not watching.
-    //new Mojo.Service.Request('palm://com.palm.location', {
-    navigator.service.Request('palm://com.palm.location', {
-        method: "getCurrentPosition",
-        parameters: {
-            responseTime: responseTime
-        },
-        onSuccess: function(event) {
-            alias.lastPosition = {
-                coords: {
-                    latitude: event.latitude,
-                    longitude: event.longitude,
-                    altitude: (event.altitude >= 0 ? event.altitude: null),
-                    speed: (event.velocity >= 0 ? event.velocity: null),
-                    heading: (event.heading >= 0 ? event.heading: null),
-                    accuracy: (event.horizAccuracy >= 0 ? event.horizAccuracy: null),
-                    altitudeAccuracy: (event.vertAccuracy >= 0 ? event.vertAccuracy: null)
-                },
-                timestamp: new Date().getTime()
-            };
-
-            var responseTime = alias.lastPosition.timestamp - startTime;
-            if (responseTime <= timeout)
-            {
-                clearTimeout(timer);
-                successCallback(alias.lastPosition);
-            }
-        },
-        onFailure: function() {
-            errorCallback();
-        }
-    });
-
-};
-
-/*
- * Asynchronously aquires the position repeatedly at a given interval.
- * @param {Function} successCallback The function to call each time the position
- * data is available
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the position data.
- * @param {PositionOptions} options The options for getting the position data
- * such as timeout and the frequency of the watch.
- */
-Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) {
-    // Invoke the appropriate callback with a new Position object every time the implementation
-    // determines that the position of the hosting device has changed.
-    var frequency = 10000;
-    if (typeof(options) == 'object' && options.frequency)
-    frequency = options.frequency;
-
-    this.start(options, errorCallback);
-
-    var referenceTime = 0;
-    if (this.lastPosition)
-    referenceTime = this.lastPosition.timestamp;
-
-    var alias = this;
-    return setInterval(function() {
-        // check if we have a new position, if so call our successcallback
-        if (!alias.lastPosition)
-        return;
-
-        if (alias.lastPosition.timestamp > referenceTime)
-        successCallback(alias.lastPosition);
-    },
-    frequency);
-};
-
-
-/*
- * Clears the specified position watch.
- * @param {String} watchId The ID of the watch returned from #watchPosition.
- */
-Geolocation.prototype.clearWatch = function(watchId) {
-    clearInterval(watchId);
-    this.stop();
-};
-
-Geolocation.prototype.start = function(options, errorCallback) {
-    //options.timeout;
-    //options.interval;
-    if (typeof(errorCallback) != 'function')
-    errorCallback = function() {};
-
-    var that = this;
-    var frequency = 10000;
-    if (typeof(options) == 'object' && options.frequency)
-    frequency = options.frequency;
-
-    var responseTime;
-    if (frequency <= 5000)
-    responseTime = 1;
-    else if (5000 < frequency <= 20000)
-    responseTime = 2;
-    else
-    responseTime = 3;
-
-    //location tracking does not support setting a custom interval :P
-    this.trackingHandle = navigator.service.Request('palm://com.palm.location', {
-        method: 'startTracking',
-        parameters: {
-            subscribe: true
-        },
-        onSuccess: function(event) {
-            that.lastPosition = {
-                coords: {
-                    latitude: event.latitude,
-                    longitude: event.longitude,
-                    altitude: (event.altitude >= 0 ? event.altitude: null),
-                    speed: (event.velocity >= 0 ? event.velocity: null),
-                    heading: (event.heading >= 0 ? event.heading: null),
-                    accuracy: (event.horizAccuracy >= 0 ? event.horizAccuracy: null),
-                    altitudeAccuracy: (event.vertAccuracy >= 0 ? event.vertAccuracy: null)
-                },
-                timestamp: new Date().getTime()
-            };
-        },
-        onFailure: function() {
-            errorCallback();
-        }
-    });
-};
-
-Geolocation.prototype.stop = function() {
-    this.trackingHandle.cancel();
-};
-
-if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation();
-
diff --git a/js/map.js b/js/map.js
deleted file mode 100644
index 8b19644..0000000
--- a/js/map.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to native mapping applications on the device.
- */
-function Map() {
-	
-};
-
-/*
- * Shows a native map on the device with pins at the given positions.
- * @param {Array} positions
- */
-Map.prototype.show = function(positions) {
-
-	var jsonPos = {};
-	var pos = null;
-	if (typeof positions == 'object') {
-		// If positions is an array, then get the first only, since google's query
-		// can't take more than one marker (believe it or not).
-		// Otherwise we assume its a single position object.
-		if (positions.length) {
-			pos = positions[0];
-		} else {
-			pos = positions;
-		}
-	} 
-	else if (navigator.geolocation.lastPosition) {
-		pos = navigator.geolocation.lastPosition;
-	} else {
-		// If we don't have a position, lets use nitobi!
-		pos = { coords: { latitude: 49.28305, longitude: -123.10689 } };
-	}
-
-	this.service = navigator.service.Request('palm://com.palm.applicationManager', {
-		method: 'open',
-		parameters: {
-		id: 'com.palm.app.maps',
-		params: {
-			query: "@" + pos.coords.latitude + "," + pos.coords.longitude
-			}
-		}
-	});
-
-};
-
-if (typeof navigator.map == "undefined") navigator.map = new Map();
-
diff --git a/js/mojo.js b/js/mojo.js
deleted file mode 100644
index 1c7949f..0000000
--- a/js/mojo.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-//===========================
-//		Mojo Dependencies - we still need to rely on these minimal parts of the Mojo framework - should try to find if we can get access to lower level APIs
-//							so that we can remove dependence of Mojo
-//===========================
-	
-Mojo = {
-	contentIndicator: false,
-
-	// called by webOS in certain cases
-	relaunch: function() {
-		var launch = JSON.parse(PalmSystem.launchParams);
-		
-		if (launch['palm-command'] && launch['palm-command'] == 'open-app-menu')
-			this.fireEvent(window, "appmenuopen");
-		else
-			this.fireEvent(window, "palmsystem", launch);
-	},
-	
-	// called by webOS when your app gets focus
-	stageActivated: function() {
-		this.fireEvent(window, "activate");
-	},
-
-	// called by webOS when your app loses focus
-	stageDeactivated: function() {
-		this.fireEvent(window, "deactivate");
-	},
-
-	// this is a stub -- called by webOS when orientation changes
-	// but the preferred method is to use the orientationchanged
-	// DOM event
-	screenOrientationChanged: function(dir) {
-	},
-	
-	// used to redirect keyboard events to DOM event "back"
-	onKeyUp: function(e) {
-		if (e.keyCode == 27)
-			this.fireEvent(window, "back");
-	},
-		
-	// private method, used to fire off DOM events
-	fireEvent: function(element, event, data) {
-		var e = document.createEvent("Event");
-		e.initEvent(event, false, true);
-		
-		if (data)
-			e.data = data;
-		
-		element.dispatchEvent(e);
-	},
-	
-	/*
-	 	not sure if these stubs are still needed since the Log object is encapsulated in debugconsole class 
-		and the Service object is encapsulated in the Service class
-	*/
-	// stubs to make v8 happier
-	Service: {},
-	Log: {}
-	
-};
diff --git a/js/mouse.js b/js/mouse.js
deleted file mode 100644
index b002500..0000000
--- a/js/mouse.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-function Mouse() {
-	
-};
-
-/*
- * Possibly useful for automated testing, this call to PalmSystem triggers a mouse click (i.e. touch event). 
- * x coordinate & y coordinate of where the screen was touched and also a true/false flag to tell WebOS if it should simulate the mouse click
- * @param {Number} x
- * @param {Number} y
- * @param {Boolean} state
- * Example:
- *		navigator.mouse.simulateMouseClick(10, 10, true);
- */	
-Mouse.prototype.simulateMouseClick = function(x, y, state) {
-	PalmSystem.simulateMouseClick(x, y, state || true);
-};
-
-if (typeof navigator.mouse == "undefined") navigator.mouse = new Mouse();
-
diff --git a/js/network.js b/js/network.js
deleted file mode 100644
index 12fc57a..0000000
--- a/js/network.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-function Network() {
-    /*
-     * The last known Network status.
-     */
-	this.lastReachability = null;
-};
-
-Network.prototype.isReachable = function(hostName, successCallback, options) {
-	this.request = navigator.service.Request('palm://com.palm.connectionmanager', {
-	    method: 'getstatus',
-	    parameters: {},
-	    onSuccess: function(result) { 
-		
-			var status = NetworkStatus.NOT_REACHABLE;
-			if (result.isInternetConnectionAvailable == true) {
-
-				if (result.wan.state == "connected") {
-					status = NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK;
-				}
-				
-				if (result.wifi.state == "connected") {
-					status = NetworkStatus.REACHABLE_VIA_WIFI_NETWORK;
-				}
-							
-			}
-			successCallback(status); 
-		},
-	    onFailure: function() {}
-	});
-
-};
-
-Network.prototype.connection = function(hostName, successCallback, options) {
-	this.request = navigator.service.Request('palm://com.palm.connectionmanager', {
-	    method: 'getstatus',
-	    parameters: {},
-	    onSuccess: function(result) { 
-			successCallback(result); 
-		},
-	    onFailure: function() {}
-	});	
-};
-
-Network.prototype.connection.type = function(hostName, successCallback, options) {
-	navigator.network.isReachable(hostName,successCallback, options);
-};
-
-function Connection() {
-	this.code = null;
-	this.message = "";
-};
-
-Connection.UNKNOWN = 'unknown';
-Connection.ETHERNET = 'ethernet';
-Connection.WIFI = 'wifi';
-Connection.CELL_2G = '2g';
-Connection.CELL_3G = '3g';
-Connection.CELL_4G = '4g';
-Connection.NONE = 'none';
-
-/*
- * This class contains information about any NetworkStatus.
- * @constructor
- */
-function NetworkStatus() {
-	this.code = null;
-	this.message = "";
-};
-
-NetworkStatus.NOT_REACHABLE = 0;
-NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1;
-NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2;
-
-if (typeof navigator.network == "undefined") navigator.network = new Network();
-
diff --git a/js/notification.js b/js/notification.js
deleted file mode 100644
index 9a3b559..0000000
--- a/js/notification.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to notifications on the device.
- */
-function Notification() {
-
-    };
-
-/*
- * adds a dashboard to the WebOS app
- * @param {String} url
- * @param {String} html
- * Example:
- *		navigator.notification.newDashboard("dashboard.html");
- */
-Notification.prototype.newDashboard = function(url, html) {
-    var win = window.open(url, "_blank", "attributes={\"window\":\"dashboard\"}");
-    html && win.document.write(html);
-    win.PalmSystem.stageReady();
-};
-
-/*
- * Displays a banner notification. If specified, will send your 'response' object as data via the 'palmsystem' DOM event.
- * If no 'icon' filename is specified, will use a small version of your application icon.
- * @param {String} message
- * @param {Object} response
- * @param {String} icon 
- * @param {String} soundClass class of the sound; supported classes are: "ringtones", "alerts", "alarm", "calendar", "notification"
- * @param {String} soundFile partial or full path to the sound file
- * @param {String} soundDurationMs of sound in ms
- * Example:
- *		navigator.notification.showBanner('test message');
- */
-Notification.prototype.showBanner = function(message, response, icon, soundClass, soundFile, soundDurationMs) {
-    var response = response || {
-        banner: true
-    };
-    PalmSystem.addBannerMessage(message, JSON.stringify(response), icon, soundClass, soundFile, soundDurationMs);
-};
-
-/**
- * Remove a banner from the banner area. The category parameter defaults to 'banner'. Will not remove
- * messages that are already displayed.
- * @param {String} category 
-		Value defined by the application and usually same one used in {@link showBanner}. 
-		It is used if you have more than one kind of banner message. 
- */
-Notification.prototype.removeBannerMessage = function(category) {
-    var bannerKey = category || 'banner';
-    var bannerId = this.banners.get(bannerKey);
-    if (bannerId) {
-        try {
-            PalmSystem.removeBannerMessage(bannerId);
-        } catch(removeBannerException) {
-            window.debug.error(removeBannerException.toString());
-        }
-    }
-};
-
-/*
- * Remove all pending banner messages from the banner area. Will not remove messages that are already displayed.
- */
-Notification.prototype.clearBannerMessage = function() {
-    PalmSystem.clearBannerMessage();
-};
-
-/*
- * This function vibrates the device
- * @param {number} duration The duration in ms to vibrate for.
- * @param {number} intensity The intensity of the vibration
- */
-Notification.prototype.vibrate = function(duration, intensity) {
-    //the intensity for palm is inverted; 0=high intensity, 100=low intensity
-    //this is opposite from our api, so we invert
-    if (isNaN(intensity) || intensity > 100 || intensity <= 0)
-    intensity = 0;
-    else
-    intensity = 100 - intensity;
-
-    // if the app id does not have the namespace "com.palm.", an error will be thrown here
-    //this.vibhandle = new Mojo.Service.Request("palm://com.palm.vibrate", {
-    this.vibhandle = navigator.service.Request("palm://com.palm.vibrate", {
-        method: 'vibrate',
-        parameters: {
-            'period': intensity,
-            'duration': duration
-        }
-    },
-    false);
-};
-
-/* 
- * Plays the specified sound
- * @param {String} soundClass class of the sound; supported classes are: "ringtones", "alerts", "alarm", "calendar", "notification"
- * @param {String} soundFile partial or full path to the sound file
- * @param {String} soundDurationMs of sound in ms
- */
-Notification.prototype.beep = function(soundClass, soundFile, soundDurationMs) {
-    PalmSystem.playSoundNotification(soundClass, soundFile, soundDurationMs);
-};
-
-/*
- * displays a notification
- * @param {String} message
- * @param {Object} response
- * @param {String} icon
- */
-Notification.prototype.alert = function(message, response, icon) {
-    var response = response || {
-        banner: true
-    };
-    navigator.notification.showBanner(message, response, icon);
-};
-
-if (typeof navigator.notification == 'undefined') {
-    navigator.notification = new Notification();
-    alert = navigator.notification.alert;
-}
-
diff --git a/js/orientation.js b/js/orientation.js
deleted file mode 100644
index c45ba65..0000000
--- a/js/orientation.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the device orientation.
- * @constructor
- */
-function Orientation() {
-	this.started = false;
-};
-
-/*
- * Manually sets the orientation of the application window. 
- * 'up', 'down', 'left' or 'right' used to specify fixed window orientation
- * 'free' WebOS will change the window orientation to match the device orientation
- * @param {String} orientation
- * Example:
- *		navigator.orientation.setOrientation('up');
- */
-Orientation.prototype.setOrientation = function(orientation) {
-	PalmSystem.setWindowOrientation(orientation);   
-};
-
-/*
- * Returns the current window orientation
- */
-Orientation.prototype.getCurrentOrientation = function() {
-  	return PalmSystem.windowOrientation;
-};
-
-/*
- * Starts the native orientationchange event listener.
- */  
-Orientation.prototype.start = function (successCallback) {
-	var that = this;
-	// This subscribes the callback once for the successCallback function
-	that.callback = function (e) {
-		document.removeEventListener("orientationChanged", that.callback);
-		successCallback(e.orientation);
-	}
-	
-	document.addEventListener("orientationChanged", that.callback);
-	
-	// This subscribes setOrientation to be constantly updating the currentOrientation property
-	document.addEventListener("orientationchange", function(event) {
-		var orient = null;
-		switch (event.position) {
-			case 0: orient = DisplayOrientation.FACE_UP; break;
-			case 1: orient = DisplayOrientation.FACE_DOWN; break;
-			case 2: orient = DisplayOrientation.PORTRAIT; break;
-			case 3: orient = DisplayOrientation.REVERSE_PORTRAIT; break;
-			case 4: orient = DisplayOrientation.LANDSCAPE_RIGHT_UP; break;
-			case 5: orient = DisplayOrientation.LANDSCAPE_LEFT_UP; break;
-			default: return; 	//orientationchange event seems to get thrown sometimes with a null event position
-		}
-		that.setOrientation(orient);
-	});
-	this.started = true;
-};
-
-/*
- * Asynchronously aquires the orientation repeatedly at a given interval.
- * @param {Function} successCallback The function to call each time the orientation
- * data is available.
- * @param {Function} errorCallback The function to call when there is an error 
- * getting the orientation data.
- */             
-Orientation.prototype.watchOrientation = function(successCallback, errorCallback, options) {
-	// Invoke the appropriate callback with a new Position object every time the implementation 
-	// determines that the position of the hosting device has changed. 
-	this.getCurrentOrientation(successCallback, errorCallback);
-	var interval = 1000;
-	if (options && !isNaN(options.interval))
-		interval = options.interval;
-	var that = this;
-	return setInterval(function() {
-		that.getCurrentOrientation(successCallback, errorCallback);
-	}, interval);
-};
-       
-/*
- * Clears the specified orientation watch.
- * @param {String} watchId The ID of the watch returned from #watchOrientation.
- */     
-Orientation.prototype.clearWatch = function(watchId) {
-	clearInterval(watchId);
-};
-  
-/*
- * This class encapsulates the possible orientation values.
- * @constructor
- */  
-function DisplayOrientation() {
-	this.code = null;
-	this.message = "";
-};
-
-DisplayOrientation.PORTRAIT = 0;
-DisplayOrientation.REVERSE_PORTRAIT = 1;
-DisplayOrientation.LANDSCAPE_LEFT_UP = 2;
-DisplayOrientation.LANDSCAPE_RIGHT_UP = 3;
-DisplayOrientation.FACE_UP = 4;
-DisplayOrientation.FACE_DOWN = 5;
-
-if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation();
-
diff --git a/js/position.js b/js/position.js
deleted file mode 100644
index 5954730..0000000
--- a/js/position.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-function Position(coords) {
-	this.coords = coords;
-    this.timestamp = new Date().getTime();
-};
-
-function Coordinates(lat, lng, alt, acc, head, vel, altacc) {
-	/*
-	 * The latitude of the position.
-	 */
-	this.latitude = lat;
-	/*
-	 * The longitude of the position,
-	 */
-	this.longitude = lng;
-	/*
-	 * The accuracy of the position.
-	 */
-	this.accuracy = acc;
-	/*
-	 * The altitude of the position.
-	 */
-	this.altitude = alt;
-	/*
-	 * The direction the device is moving at the position.
-	 */
-	this.heading = head;
-	/*
-	 * The velocity with which the device is moving at the position.
-	 */
-	this.speed = vel;
-	/*
-	 * The altitude accuracy of the position.
-	 */
-	this.altitudeAccuracy = (typeof(altacc) != 'undefined') ? altacc : null;
-};
-
-/*
- * This class specifies the options for requesting position data.
- * @constructor
- */
-function PositionOptions() {
-	/*
-	 * Specifies the desired position accuracy.
-	 */
-	this.enableHighAccuracy = true;
-	/*
-	 * The timeout after which if position data cannot be obtained the errorCallback
-	 * is called.
-	 */
-	this.timeout = 10000;
-};
-
-/*
- * This class contains information about any GSP errors.
- * @constructor
- */
-function PositionError() {
-	this.code = null;
-	this.message = "";
-};
-
-PositionError.UNKNOWN_ERROR = 0;
-PositionError.PERMISSION_DENIED = 1;
-PositionError.POSITION_UNAVAILABLE = 2;
-PositionError.TIMEOUT = 3;
-
diff --git a/js/service.js b/js/service.js
deleted file mode 100644
index 7a062fb..0000000
--- a/js/service.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-function Service() {
-	
-};
-
-Service.prototype.Request = function (uri, params) {
-	var req = new PalmServiceBridge();
-	var url = uri + "/" + (params.method || "");
-	req.url = url;
-
-	this.req = req;
-	this.url = url;
-	this.params = params || {};
-	
-	this.call(params);
-	
-	return this;
-};
-
-Service.prototype.call = function(params) {
-	var onsuccess = null;
-	var onfailure = null;
-	var oncomplete = null;
-
-	if (typeof params.onSuccess === 'function')
-		onsuccess = params.onSuccess;
-
-	if (typeof params.onFailure === 'function')
-		onerror = params.onFailure;
-
-	if (typeof params.onComplete === 'function')
-		oncomplete = params.onComplete;
-
-	this.req.onservicecallback = callback;
-
-	function callback(msg) {
-		var response = JSON.parse(msg);
-
-		if ((response.errorCode) && onfailure)
-			onfailure(response);
-		else if (onsuccess)
-			onsuccess(response);
-		
-		if (oncomplete)
-			oncomplete(response);
-	}
-
-	this.data = (typeof params.parameters === 'object') ? JSON.stringify(params.parameters) : '{}';
-
-	this.req.call(this.url, this.data);
-}
-
-if (typeof navigator.service == "undefined") navigator.service = new Service();
-
diff --git a/js/sms.js b/js/sms.js
deleted file mode 100644
index ba8adb3..0000000
--- a/js/sms.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the device SMS functionality.
- * @constructor
- */
-function Sms() {
-
-    };
-
-/*
- * Sends an SMS message.
- * @param {Integer} number The phone number to send the message to.
- * @param {String} message The contents of the SMS message to send.
- * @param {Function} successCallback The function to call when the SMS message is sent.
- * @param {Function} errorCallback The function to call when there is an error sending the SMS message.
- * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy.
- */
-Sms.prototype.send = function(number, message, successCallback, errorCallback, options) {
-    try {
-        this.service = navigator.service.Request('palm://com.palm.applicationManager', {
-            method: 'launch',
-            parameters: {
-                id: "com.palm.app.messaging",
-                params: {
-                    composeAddress: number,
-                    messageText: message
-                }
-            }
-        });
-        successCallback();
-    } catch(ex) {
-        errorCallback({
-            name: "SMSerror",
-            message: ex.name + ": " + ex.message
-        });
-    }
-};
-
-if (typeof navigator.sms == "undefined") navigator.sms = new Sms();
-
diff --git a/js/telephony.js b/js/telephony.js
deleted file mode 100644
index 7bda4ef..0000000
--- a/js/telephony.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * This class provides access to the telephony features of the device.
- * @constructor
- */
-function Telephony() {
-    this.number = "";
-};
-
-/*
- * Calls the specifed number.
- * @param {Integer} number The number to be called.
- */
-Telephony.prototype.send = function(number) {
-    this.number = number;
-    this.service = navigator.service.Request('palm://com.palm.applicationManager', {
-        method: 'open',
-        parameters: {
-            target: "tel://" + number
-        }
-    });
-};
-
-if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony();
-
diff --git a/js/window.js b/js/window.js
deleted file mode 100644
index ebdab41..0000000
--- a/js/window.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-function Window() {
-
-    };
-
-/*
- * This is a thin wrapper for 'window.open()' which optionally sets document contents to 'html', and calls 'PalmSystem.stageReady()'
- * on your new card. Note that this new card will not come with your framework (if any) or anything for that matter.
- * @param {String} url
- * @param {String} html
- * Example:
- *		navigator.window.newCard('about:blank', '<html><body>Hello again!</body></html>');
- */
-Window.prototype.newCard = function(url, html) {
-    var win = window.open(url || "");
-    if (html)
-        win.document.write(html);
-    win.PalmSystem.stageReady();
-};
-
-/*
- * Enable or disable full screen display (full screen removes the app menu bar and the rounded corners of the screen).
- * @param {Boolean} state
- * Example:
- *		navigator.window.setFullScreen(true);
- */
-Window.prototype.setFullScreen = function(state) {
-    // valid state values are: true or false
-    PalmSystem.enableFullScreenMode(state);
-};
-
-/*
- * used to set the window properties of the WebOS app
- * @param {Object} props
- * Example:
- * 		private method used by other member functions - ideally we shouldn't call this method
- */
-Window.prototype.setWindowProperties = function(props) {
-    if (typeof props === 'object')
-        navigator.windowProperties = props;
-
-    PalmSystem.setWindowProperties(props || this.windowProperties);
-};
-
-/*
- * Enable or disable screen timeout. When enabled, the device screen will not dim. This is useful for navigation, clocks or other "dock" apps.
- * @param {Boolean} state
- * Example:
- *		navigator.window.blockScreenTimeout(true);
- */
-Window.prototype.blockScreenTimeout = function(state) {
-    navigator.windowProperties.blockScreenTimeout = state;
-    this.setWindowProperties();
-};
-
-/*
- * Sets the lightbar to be a little dimmer for screen locked notifications.
- * @param {Boolean} state
- * Example:
- *		navigator.window.setSubtleLightbar(true);
- */
-Window.prototype.setSubtleLightbar = function(state) {
-    navigator.windowProperties.setSubtleLightbar = state;
-    this.setWindowProperties();
-};
-
-if (typeof navigator.window == 'undefined') navigator.window = new Window();
-
diff --git a/js/windowproperties.js b/js/windowproperties.js
deleted file mode 100644
index 2b749f5..0000000
--- a/js/windowproperties.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * Object for storing WebOS window properties
- */
-function WindowProperties() {
-    blockScreenTimeout = false;
-    setSubtleLightbar = false;
-    fastAccelerometer = false;
-};
-
-if (typeof navigator.windowProperties == 'undefined') navigator.windowProperties = new WindowProperties();
diff --git a/lib/cordova.webos-debug.js b/lib/cordova.webos-debug.js
new file mode 100644
index 0000000..87d0f32
--- /dev/null
+++ b/lib/cordova.webos-debug.js
@@ -0,0 +1,116 @@
+// 
+
+// File generated at :: Tue Oct 30 2012 10:12:55 GMT+0100 (W. Europe Standard Time)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+try {eval("\nvar require,\n    define;\n\n(function () {\n    var modules = {};\n    // Stack of moduleIds currently being built.\n    var requireStack = [];\n    // Map of module ID -> index into requireStack of modules currently being built.\n    var inProgressModules = {};\n\n    function build(module) {\n        var factory = module.factory;\n        module.exports = {};\n        delete module.factory;\n        factory(require, module.exports, module);\n        return module.exports;\n    }\n\n    require = function (id) {\n        if (!modules[id]) {\n            throw \"module \" + id + \" not found\";\n        } else if (id in inProgressModules) {\n            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;\n            throw \"Cycle in require graph: \" + cycle;\n        }\n        if (modules[id].factory) {\n            try {\n                inProgressModules[id] = requireStack.length;\n                requireStack.push(id);\n                return build(modules[id]);\n            } finally {\n                delete inProgressModules[id];\n                requireStack.pop();\n            }\n        }\n        return modules[id].exports;\n    };\n\n    define = function (id, factory) {\n        if (modules[id]) {\n            throw \"module \" + id + \" already defined\";\n        }\n\n        modules[id] = {\n            id: id,\n            factory: factory\n        };\n    };\n\n    define.remove = function (id) {\n        delete modules[id];\n    };\n\n})();\n\n//Export for use in node\nif (typeof module === \"object\" && typeof require === \"function\") {\n    module.exports.require = require;\n    module.exports.define = define;\n}\n\n//@ sourceURL=lib\\scripts\\require.js")} catch(e) {console.log("exception: in lib\scripts\require.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova\", function(require, exports, module) {\n\n\nvar channel = require('cordova/channel');\n\n/**\n * Listen for DOMContentLoaded and notify our channel subscribers.\n */\ndocument.addEventListener('DOMContentLoaded', function() {\n    channel.onDOMContentLoaded.fire();\n}, false);\nif (document.readyState == 'complete' || document.readyState == 'interactive') {\n    channel.onDOMContentLoaded.fire();\n}\n\n/**\n * Intercept calls to addEventListener + removeEventListener and handle deviceready,\n * resume, and pause events.\n */\nvar m_document_addEventListener = document.addEventListener;\nvar m_document_removeEventListener = document.removeEventListener;\nvar m_window_addEventListener = window.addEventListener;\nvar m_window_removeEventListener = window.removeEventListener;\n\n/**\n * Houses custom event handlers to intercept on document + window event listeners.\n */\nvar documentEventHandlers = {},\n    windowEventHandlers = {};\n\ndocument.addEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    if (typeof documentEventHandlers[e] != 'undefined') {\n        documentEventHandlers[e].subscribe(handler);\n    } else {\n        m_document_addEventListener.call(document, evt, handler, capture);\n    }\n};\n\nwindow.addEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    if (typeof windowEventHandlers[e] != 'undefined') {\n        windowEventHandlers[e].subscribe(handler);\n    } else {\n        m_window_addEventListener.call(window, evt, handler, capture);\n    }\n};\n\ndocument.removeEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    // If unsubscribing from an event that is handled by a plugin\n    if (typeof documentEventHandlers[e] != \"undefined\") {\n        documentEventHandlers[e].unsubscribe(handler);\n    } else {\n        m_document_removeEventListener.call(document, evt, handler, capture);\n    }\n};\n\nwindow.removeEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    // If unsubscribing from an event that is handled by a plugin\n    if (typeof windowEventHandlers[e] != \"undefined\") {\n        windowEventHandlers[e].unsubscribe(handler);\n    } else {\n        m_window_removeEventListener.call(window, evt, handler, capture);\n    }\n};\n\nfunction createEvent(type, data) {\n    var event = document.createEvent('Events');\n    event.initEvent(type, false, false);\n    if (data) {\n        for (var i in data) {\n            if (data.hasOwnProperty(i)) {\n                event[i] = data[i];\n            }\n        }\n    }\n    return event;\n}\n\nif(typeof window.console === \"undefined\") {\n    window.console = {\n        log:function(){}\n    };\n}\n\nvar cordova = {\n    define:define,\n    require:require,\n    /**\n     * Methods to add/remove your own addEventListener hijacking on document + window.\n     */\n    addWindowEventHandler:function(event) {\n        return (windowEventHandlers[event] = channel.create(event));\n    },\n    addStickyDocumentEventHandler:function(event) {\n        return (documentEventHandlers[event] = channel.createSticky(event));\n    },\n    addDocumentEventHandler:function(event) {\n        return (documentEventHandlers[event] = channel.create(event));\n    },\n    removeWindowEventHandler:function(event) {\n        delete windowEventHandlers[event];\n    },\n    removeDocumentEventHandler:function(event) {\n        delete documentEventHandlers[event];\n    },\n    /**\n     * Retrieve original event handlers that were replaced by Cordova\n     *\n     * @return object\n     */\n    getOriginalHandlers: function() {\n        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},\n        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};\n    },\n    /**\n     * Method to fire event from native code\n     * bNoDetach is required for events which cause an exception which needs to be caught in native code\n     */\n    fireDocumentEvent: function(type, data, bNoDetach) {\n        var evt = createEvent(type, data);\n        if (typeof documentEventHandlers[type] != 'undefined') {\n            if( bNoDetach ) {\n              documentEventHandlers[type].fire(evt);\n            }\n            else {\n              setTimeout(function() {\n                  documentEventHandlers[type].fire(evt);\n              }, 0);\n            }\n        } else {\n            document.dispatchEvent(evt);\n        }\n    },\n    fireWindowEvent: function(type, data) {\n        var evt = createEvent(type,data);\n        if (typeof windowEventHandlers[type] != 'undefined') {\n            setTimeout(function() {\n                windowEventHandlers[type].fire(evt);\n            }, 0);\n        } else {\n            window.dispatchEvent(evt);\n        }\n    },\n\n    /**\n     * Plugin callback mechanism.\n     */\n    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.\n    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.\n    callbackId: Math.floor(Math.random() * 2000000000),\n    callbacks:  {},\n    callbackStatus: {\n        NO_RESULT: 0,\n        OK: 1,\n        CLASS_NOT_FOUND_EXCEPTION: 2,\n        ILLEGAL_ACCESS_EXCEPTION: 3,\n        INSTANTIATION_EXCEPTION: 4,\n        MALFORMED_URL_EXCEPTION: 5,\n        IO_EXCEPTION: 6,\n        INVALID_ACTION: 7,\n        JSON_EXCEPTION: 8,\n        ERROR: 9\n    },\n\n    /**\n     * Called by native code when returning successful result from an action.\n     */\n    callbackSuccess: function(callbackId, args) {\n        try {\n            cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);\n        } catch (e) {\n            console.log(\"Error in error callback: \" + callbackId + \" = \"+e);\n        }\n    },\n\n    /**\n     * Called by native code when returning error result from an action.\n     */\n    callbackError: function(callbackId, args) {\n        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.\n        // Derive success from status.\n        try {\n            cordova.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);\n        } catch (e) {\n            console.log(\"Error in error callback: \" + callbackId + \" = \"+e);\n        }\n    },\n\n    /**\n     * Called by native code when returning the result from an action.\n     */\n    callbackFromNative: function(callbackId, success, status, message, keepCallback) {\n        var callback = cordova.callbacks[callbackId];\n        if (callback) {\n            if (success && status == cordova.callbackStatus.OK) {\n                callback.success && callback.success(message);\n            } else if (!success) {\n                callback.fail && callback.fail(message);\n            }\n\n            // Clear callback if not expecting any more results\n            if (!keepCallback) {\n                delete cordova.callbacks[callbackId];\n            }\n        }\n    },\n    addConstructor: function(func) {\n        channel.onCordovaReady.subscribe(function() {\n            try {\n                func();\n            } catch(e) {\n                console.log(\"Failed to run constructor: \" + e);\n            }\n        });\n    }\n};\n\n// Register pause, resume and deviceready channels as events on document.\nchannel.onPause = cordova.addDocumentEventHandler('pause');\nchannel.onResume = cordova.addDocumentEventHandler('resume');\nchannel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');\n\nmodule.exports = cordova;\n\n});\n\n//@ sourceURL=lib/cordova.js")} catch(e) {console.log("exception: in lib/cordova.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/builder\", function(require, exports, module) {\n\nvar utils = require('cordova/utils');\n\nfunction each(objects, func, context) {\n    for (var prop in objects) {\n        if (objects.hasOwnProperty(prop)) {\n            func.apply(context, [objects[prop], prop]);\n        }\n    }\n}\n\nfunction assignOrWrapInDeprecateGetter(obj, key, value, message) {\n    if (message) {\n        utils.defineGetter(obj, key, function() {\n            window.console && console.log(message);\n            return value;\n        });\n    } else {\n        obj[key] = value;\n    }\n}\n\nfunction include(parent, objects, clobber, merge) {\n    each(objects, function (obj, key) {\n        try {\n          var result = obj.path ? require(obj.path) : {};\n\n          if (clobber) {\n              // Clobber if it doesn't exist.\n              if (typeof parent[key] === 'undefined') {\n                  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);\n              } else if (typeof obj.path !== 'undefined') {\n                  // If merging, merge properties onto parent, otherwise, clobber.\n                  if (merge) {\n                      recursiveMerge(parent[key], result);\n                  } else {\n                      assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);\n                  }\n              }\n              result = parent[key];\n          } else {\n            // Overwrite if not currently defined.\n            if (typeof parent[key] == 'undefined') {\n              assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);\n            } else if (merge && typeof obj.path !== 'undefined') {\n              // If merging, merge parent onto result\n              recursiveMerge(result, parent[key]);\n              parent[key] = result;\n            } else {\n              // Set result to what already exists, so we can build children into it if they exist.\n              result = parent[key];\n            }\n          }\n\n          if (obj.children) {\n            include(result, obj.children, clobber, merge);\n          }\n        } catch(e) {\n          utils.alert('Exception building cordova JS globals: ' + e + ' for key \"' + key + '\"');\n        }\n    });\n}\n\n/**\n * Merge properties from one object onto another recursively.  Properties from\n * the src object will overwrite existing target property.\n *\n * @param target Object to merge properties into.\n * @param src Object to merge properties from.\n */\nfunction recursiveMerge(target, src) {\n    for (var prop in src) {\n        if (src.hasOwnProperty(prop)) {\n            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {\n                // If the target object is a constructor override off prototype.\n                target.prototype[prop] = src[prop];\n            } else {\n                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(\n                        target[prop], src[prop]) : src[prop];\n            }\n        }\n    }\n    return target;\n}\n\nmodule.exports = {\n    build: function (objects) {\n        return {\n            intoButDoNotClobber: function (target) {\n                include(target, objects, false, false);\n            },\n            intoAndClobber: function(target) {\n                include(target, objects, true, false);\n            },\n            intoAndMerge: function(target) {\n                include(target, objects, true, true);\n            }\n        };\n    }\n};\n\n});\n\n//@ sourceURL=lib\\common\\builder.js")} catch(e) {console.log("exception: in lib\common\builder.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/channel\", function(require, exports, module) {\n\nvar utils = require('cordova/utils'),\n    nextGuid = 1;\n\n/**\n * Custom pub-sub \"channel\" that can have functions subscribed to it\n * This object is used to define and control firing of events for\n * cordova initialization, as well as for custom events thereafter.\n *\n * The order of events during page load and Cordova startup is as follows:\n *\n * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.\n * onNativeReady*              Internal event that indicates the Cordova native side is ready.\n * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.\n * onCordovaInfoReady*         Internal event fired when device properties are available.\n * onCordovaConnectionReady*   Internal event fired when the connection property has been set.\n * onDeviceReady*              User event fired to indicate that Cordova is ready\n * onResume                    User event fired to indicate a start/resume lifecycle event\n * onPause                     User event fired to indicate a pause lifecycle event\n * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).\n *\n * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.\n * All listeners that subscribe after the event is fired will be executed right away.\n *\n * The only Cordova events that user code should register for are:\n *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript\n *      pause                 App has moved to background\n *      resume                App has returned to foreground\n *\n * Listeners can be registered as:\n *      document.addEventListener(\"deviceready\", myDeviceReadyListener, false);\n *      document.addEventListener(\"resume\", myResumeListener, false);\n *      document.addEventListener(\"pause\", myPauseListener, false);\n *\n * The DOM lifecycle events should be used for saving and restoring state\n *      window.onload\n *      window.onunload\n *\n */\n\n/**\n * Channel\n * @constructor\n * @param type  String the channel name\n */\nvar Channel = function(type, sticky) {\n    this.type = type;\n    // Map of guid -> function.\n    this.handlers = {};\n    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.\n    this.state = sticky ? 1 : 0;\n    // Used in sticky mode to remember args passed to fire().\n    this.fireArgs = null;\n    // Used by onHasSubscribersChange to know if there are any listeners.\n    this.numHandlers = 0;\n    // Function that is called when the first listener is subscribed, or when\n    // the last listener is unsubscribed.\n    this.onHasSubscribersChange = null;\n},\n    channel = {\n        /**\n         * Calls the provided function only after all of the channels specified\n         * have been fired. All channels must be sticky channels.\n         */\n        join: function(h, c) {\n            var len = c.length,\n                i = len,\n                f = function() {\n                    if (!(--i)) h();\n                };\n            for (var j=0; j<len; j++) {\n                if (c[j].state === 0) {\n                    throw Error('Can only use join with sticky channels.');\n                }\n                c[j].subscribe(f);\n            }\n            if (!len) h();\n        },\n        create: function(type) {\n            return channel[type] = new Channel(type, false);\n        },\n        createSticky: function(type) {\n            return channel[type] = new Channel(type, true);\n        },\n\n        /**\n         * cordova Channels that must fire before \"deviceready\" is fired.\n         */\n        deviceReadyChannelsArray: [],\n        deviceReadyChannelsMap: {},\n\n        /**\n         * Indicate that a feature needs to be initialized before it is ready to be used.\n         * This holds up Cordova's \"deviceready\" event until the feature has been initialized\n         * and Cordova.initComplete(feature) is called.\n         *\n         * @param feature {String}     The unique feature name\n         */\n        waitForInitialization: function(feature) {\n            if (feature) {\n                var c = channel[feature] || this.createSticky(feature);\n                this.deviceReadyChannelsMap[feature] = c;\n                this.deviceReadyChannelsArray.push(c);\n            }\n        },\n\n        /**\n         * Indicate that initialization code has completed and the feature is ready to be used.\n         *\n         * @param feature {String}     The unique feature name\n         */\n        initializationComplete: function(feature) {\n            var c = this.deviceReadyChannelsMap[feature];\n            if (c) {\n                c.fire();\n            }\n        }\n    };\n\nfunction forceFunction(f) {\n    if (typeof f != 'function') throw \"Function required as first argument!\";\n}\n\n/**\n * Subscribes the given function to the channel. Any time that\n * Channel.fire is called so too will the function.\n * Optionally specify an execution context for the function\n * and a guid that can be used to stop subscribing to the channel.\n * Returns the guid.\n */\nChannel.prototype.subscribe = function(f, c) {\n    // need a function to call\n    forceFunction(f);\n    if (this.state == 2) {\n        f.apply(c || this, this.fireArgs);\n        return;\n    }\n\n    var func = f,\n        guid = f.observer_guid;\n    if (typeof c == \"object\") { func = utils.close(c, f); }\n\n    if (!guid) {\n        // first time any channel has seen this subscriber\n        guid = '' + nextGuid++;\n    }\n    func.observer_guid = guid;\n    f.observer_guid = guid;\n\n    // Don't add the same handler more than once.\n    if (!this.handlers[guid]) {\n        this.handlers[guid] = func;\n        this.numHandlers++;\n        if (this.numHandlers == 1) {\n            this.onHasSubscribersChange && this.onHasSubscribersChange();\n        }\n    }\n};\n\n/**\n * Unsubscribes the function with the given guid from the channel.\n */\nChannel.prototype.unsubscribe = function(f) {\n    // need a function to unsubscribe\n    forceFunction(f);\n\n    var guid = f.observer_guid,\n        handler = this.handlers[guid];\n    if (handler) {\n        delete this.handlers[guid];\n        this.numHandlers--;\n        if (this.numHandlers === 0) {\n            this.onHasSubscribersChange && this.onHasSubscribersChange();\n        }\n    }\n};\n\n/**\n * Calls all functions subscribed to this channel.\n */\nChannel.prototype.fire = function(e) {\n    var fail = false,\n        fireArgs = Array.prototype.slice.call(arguments);\n    // Apply stickiness.\n    if (this.state == 1) {\n        this.state = 2;\n        this.fireArgs = fireArgs;\n    }\n    if (this.numHandlers) {\n        // Copy the values first so that it is safe to modify it from within\n        // callbacks.\n        var toCall = [];\n        for (var item in this.handlers) {\n            toCall.push(this.handlers[item]);\n        }\n        for (var i = 0; i < toCall.length; ++i) {\n            toCall[i].apply(this, fireArgs);\n        }\n        if (this.state == 2 && this.numHandlers) {\n            this.numHandlers = 0;\n            this.handlers = {};\n            this.onHasSubscribersChange && this.onHasSubscribersChange();\n        }\n    }\n};\n\n\n// defining them here so they are ready super fast!\n// DOM event that is received when the web page is loaded and parsed.\nchannel.createSticky('onDOMContentLoaded');\n\n// Event to indicate the Cordova native side is ready.\nchannel.createSticky('onNativeReady');\n\n// Event to indicate that all Cordova JavaScript objects have been created\n// and it's time to run plugin constructors.\nchannel.createSticky('onCordovaReady');\n\n// Event to indicate that device properties are available\nchannel.createSticky('onCordovaInfoReady');\n\n// Event to indicate that the connection property has been set.\nchannel.createSticky('onCordovaConnectionReady');\n\n// Event to indicate that Cordova is ready\nchannel.createSticky('onDeviceReady');\n\n// Event to indicate a resume lifecycle event\nchannel.create('onResume');\n\n// Event to indicate a pause lifecycle event\nchannel.create('onPause');\n\n// Event to indicate a destroy lifecycle event\nchannel.createSticky('onDestroy');\n\n// Channels that must fire before \"deviceready\" is fired.\nchannel.waitForInitialization('onCordovaReady');\nchannel.waitForInitialization('onCordovaConnectionReady');\n\nmodule.exports = channel;\n\n});\n\n//@ sourceURL=lib\\common\\channel.js")} catch(e) {console.log("exception: in lib\common\channel.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/commandProxy\", function(require, exports, module) {\n\n\n// internal map of proxy function\nvar CommandProxyMap = {};\n\nmodule.exports = {\n\n    // example: cordova.commandProxy.add(\"Accelerometer\",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);\n    add:function(id,proxyObj) {\n        console.log(\"adding proxy for \" + id);\n        CommandProxyMap[id] = proxyObj;\n        return proxyObj;\n    },\n\n    // cordova.commandProxy.remove(\"Accelerometer\");\n    remove:function(id) {\n        var proxy = CommandProxyMap[id];\n        delete CommandProxyMap[id];\n        CommandProxyMap[id] = null;\n        return proxy;\n    },\n\n    get:function(service,action) {\n        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );\n    }\n};\n});\n\n//@ sourceURL=lib\\common\\commandProxy.js")} catch(e) {console.log("exception: in lib\common\commandProxy.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/common\", function(require, exports, module) {\n\nmodule.exports = {\n    objects: {\n        cordova: {\n            path: 'cordova',\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                },\n                logger: {\n                    path: 'cordova/plugin/logger'\n                }\n            }\n        },\n        Cordova: {\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                }\n            }\n        },\n        navigator: {\n            children: {\n                notification: {\n                    path: 'cordova/plugin/notification'\n                },\n                accelerometer: {\n                    path: 'cordova/plugin/accelerometer'\n                },\n                battery: {\n                    path: 'cordova/plugin/battery'\n                },\n                camera:{\n                    path: 'cordova/plugin/Camera'\n                },\n                compass:{\n                    path: 'cordova/plugin/compass'\n                },\n                connection: {\n                    path: 'cordova/plugin/network'\n                },\n                contacts: {\n                    path: 'cordova/plugin/contacts'\n                },\n                device:{\n                    children:{\n                        capture: {\n                            path: 'cordova/plugin/capture'\n                        }\n                    }\n                },\n                geolocation: {\n                    path: 'cordova/plugin/geolocation'\n                },\n                globalization: {\n                    path: 'cordova/plugin/globalization'\n                },\n                network: {\n                    children: {\n                        connection: {\n                            path: 'cordova/plugin/network',\n                            deprecated: 'navigator.network.connection is deprecated. Use navigator.connection instead.'\n                        }\n                    }\n                },\n                splashscreen: {\n                    path: 'cordova/plugin/splashscreen'\n                }\n            }\n        },\n        Acceleration: {\n            path: 'cordova/plugin/Acceleration'\n        },\n        Camera:{\n            path: 'cordova/plugin/CameraConstants'\n        },\n        CameraPopoverOptions: {\n            path: 'cordova/plugin/CameraPopoverOptions'\n        },\n        CaptureError: {\n            path: 'cordova/plugin/CaptureError'\n        },\n        CaptureAudioOptions:{\n            path: 'cordova/plugin/CaptureAudioOptions'\n        },\n        CaptureImageOptions: {\n            path: 'cordova/plugin/CaptureImageOptions'\n        },\n        CaptureVideoOptions: {\n            path: 'cordova/plugin/CaptureVideoOptions'\n        },\n        CompassHeading:{\n            path: 'cordova/plugin/CompassHeading'\n        },\n        CompassError:{\n            path: 'cordova/plugin/CompassError'\n        },\n        ConfigurationData: {\n            path: 'cordova/plugin/ConfigurationData'\n        },\n        Connection: {\n            path: 'cordova/plugin/Connection'\n        },\n        Contact: {\n            path: 'cordova/plugin/Contact'\n        },\n        ContactAddress: {\n            path: 'cordova/plugin/ContactAddress'\n        },\n        ContactError: {\n            path: 'cordova/plugin/ContactError'\n        },\n        ContactField: {\n            path: 'cordova/plugin/ContactField'\n        },\n        ContactFindOptions: {\n            path: 'cordova/plugin/ContactFindOptions'\n        },\n        ContactName: {\n            path: 'cordova/plugin/ContactName'\n        },\n        ContactOrganization: {\n            path: 'cordova/plugin/ContactOrganization'\n        },\n        Coordinates: {\n            path: 'cordova/plugin/Coordinates'\n        },\n        device: {\n            path: 'cordova/plugin/device'\n        },\n        DirectoryEntry: {\n            path: 'cordova/plugin/DirectoryEntry'\n        },\n        DirectoryReader: {\n            path: 'cordova/plugin/DirectoryReader'\n        },\n        Entry: {\n            path: 'cordova/plugin/Entry'\n        },\n        File: {\n            path: 'cordova/plugin/File'\n        },\n        FileEntry: {\n            path: 'cordova/plugin/FileEntry'\n        },\n        FileError: {\n            path: 'cordova/plugin/FileError'\n        },\n        FileReader: {\n            path: 'cordova/plugin/FileReader'\n        },\n        FileSystem: {\n            path: 'cordova/plugin/FileSystem'\n        },\n        FileTransfer: {\n            path: 'cordova/plugin/FileTransfer'\n        },\n        FileTransferError: {\n            path: 'cordova/plugin/FileTransferError'\n        },\n        FileUploadOptions: {\n            path: 'cordova/plugin/FileUploadOptions'\n        },\n        FileUploadResult: {\n            path: 'cordova/plugin/FileUploadResult'\n        },\n        FileWriter: {\n            path: 'cordova/plugin/FileWriter'\n        },\n        Flags: {\n            path: 'cordova/plugin/Flags'\n        },\n        GlobalizationError: {\n            path: 'cordova/plugin/GlobalizationError'\n        },\n        LocalFileSystem: {\n            path: 'cordova/plugin/LocalFileSystem'\n        },\n        Media: {\n            path: 'cordova/plugin/Media'\n        },\n        MediaError: {\n            path: 'cordova/plugin/MediaError'\n        },\n        MediaFile: {\n            path: 'cordova/plugin/MediaFile'\n        },\n        MediaFileData:{\n            path: 'cordova/plugin/MediaFileData'\n        },\n        Metadata:{\n            path: 'cordova/plugin/Metadata'\n        },\n        Position: {\n            path: 'cordova/plugin/Position'\n        },\n        PositionError: {\n            path: 'cordova/plugin/PositionError'\n        },\n        ProgressEvent: {\n            path: 'cordova/plugin/ProgressEvent'\n        },\n        requestFileSystem:{\n            path: 'cordova/plugin/requestFileSystem'\n        },\n        resolveLocalFileSystemURI:{\n            path: 'cordova/plugin/resolveLocalFileSystemURI'\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib\\common\\common.js")} catch(e) {console.log("exception: in lib\common\common.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/exec\", function(require, exports, module) {\n\n/**\n * Execute a cordova command.  It is up to the native side whether this action\n * is synchronous or asynchronous.  The native side can return:\n *      Synchronous: PluginResult object as a JSON string\n *      Asynchrounous: Empty string \"\"\n * If async, the native side will cordova.callbackSuccess or cordova.callbackError,\n * depending upon the result of the action.\n *\n * @param {Function} success    The success callback\n * @param {Function} fail       The fail callback\n * @param {String} service      The name of the service to use\n * @param {String} action       Action to be run in cordova\n * @param {String[]} [args]     Zero or more arguments to pass to the method\n */\n\nvar plugins = {\n    \"Device\": require('cordova/plugin/webos/device'),\n    \"NetworkStatus\": require('cordova/plugin/webos/network'),\n    \"Compass\": require('cordova/plugin/webos/compass'),\n    \"Camera\": require('cordova/plugin/webos/camera'),\n    \"Accelerometer\" : require('cordova/plugin/webos/accelerometer'),\n    \"Notification\" : require('cordova/plugin/webos/notification'),\n    \"Geolocation\": require('cordova/plugin/webos/geolocation')\n};\n\nmodule.exports = function(success, fail, service, action, args) {\n    try {\n        console.error(\"exec:call plugin:\"+service+\":\"+action);\n        plugins[service][action](success, fail, args);\n    }\n    catch(e) {\n        console.error(\"missing exec: \" + service + \".\" + action);\n        console.error(args);\n        console.error(e);\n        console.error(e.stack);\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\exec.js")} catch(e) {console.log("exception: in lib\webos\exec.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/platform\", function(require, exports, module) {\n\nmodule.exports = {\n    id: \"webos\",\n    initialize: function() {\n        if (window.PalmSystem) {\n            window.PalmSystem.stageReady();\n        }\n        window.Mojo = window.Mojo || {};\n        window.Mojo.stageActivated = function() {\n            console.error(\"stageActivated\");\n        };\n    },\n    objects: {\n        requestFileSystem:{\n            path: 'cordova/plugin/webos/requestfilesystem'\n        },\n        FileReader: {\n            path: \"cordova/plugin/webos/filereader\"\n        }\n    },\n    merges: {\n        navigator: {\n            children: {\n                service: {\n                    path: \"cordova/plugin/webos/service\"\n                },\n                application: {\n                    path: \"cordova/plugin/webos/application\"\n                },\n                window: {\n                    path: \"cordova/plugin/webos/window\"\n                },\n                notification: {\n                    path: \"cordova/plugin/webos/notification\"\n                },\n                orientation: {\n                    path: \"cordova/plugin/webos/orientation\"\n                },\n                keyboard: {\n                    path: \"cordova/plugin/webos/keyboard\"\n                }\n            }\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\platform.js")} catch(e) {console.log("exception: in lib\webos\platform.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Acceleration\", function(require, exports, module) {\n\nvar Acceleration = function(x, y, z, timestamp) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n    this.timestamp = timestamp || (new Date()).getTime();\n};\n\nmodule.exports = Acceleration;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Acceleration.js")} catch(e) {console.log("exception: in lib\common\plugin\Acceleration.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Camera\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    Camera = require('cordova/plugin/CameraConstants');\n\nvar cameraExport = {};\n\n// Tack on the Camera Constants to the base camera plugin.\nfor (var key in Camera) {\n    cameraExport[key] = Camera[key];\n}\n\n/**\n * Gets a picture from source defined by \"options.sourceType\", and returns the\n * image as defined by the \"options.destinationType\" option.\n\n * The defaults are sourceType=CAMERA and destinationType=FILE_URI.\n *\n * @param {Function} successCallback\n * @param {Function} errorCallback\n * @param {Object} options\n */\ncameraExport.getPicture = function(successCallback, errorCallback, options) {\n    options = options || {};\n    // successCallback required\n    if (typeof successCallback != \"function\") {\n        console.log(\"Camera Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback != \"function\")) {\n        console.log(\"Camera Error: errorCallback is not a function\");\n        return;\n    }\n\n    var quality = 50;\n    if (typeof options.quality == \"number\") {\n        quality = options.quality;\n    } else if (typeof options.quality == \"string\") {\n        var qlity = parseInt(options.quality, 10);\n        if (isNaN(qlity) === false) {\n            quality = qlity.valueOf();\n        }\n    }\n\n    var destinationType = Camera.DestinationType.FILE_URI;\n    if (typeof options.destinationType == \"number\") {\n        destinationType = options.destinationType;\n    }\n\n    var sourceType = Camera.PictureSourceType.CAMERA;\n    if (typeof options.sourceType == \"number\") {\n        sourceType = options.sourceType;\n    }\n\n    var targetWidth = -1;\n    if (typeof options.targetWidth == \"number\") {\n        targetWidth = options.targetWidth;\n    } else if (typeof options.targetWidth == \"string\") {\n        var width = parseInt(options.targetWidth, 10);\n        if (isNaN(width) === false) {\n            targetWidth = width.valueOf();\n        }\n    }\n\n    var targetHeight = -1;\n    if (typeof options.targetHeight == \"number\") {\n        targetHeight = options.targetHeight;\n    } else if (typeof options.targetHeight == \"string\") {\n        var height = parseInt(options.targetHeight, 10);\n        if (isNaN(height) === false) {\n            targetHeight = height.valueOf();\n        }\n    }\n\n    var encodingType = Camera.EncodingType.JPEG;\n    if (typeof options.encodingType == \"number\") {\n        encodingType = options.encodingType;\n    }\n\n    var mediaType = Camera.MediaType.PICTURE;\n    if (typeof options.mediaType == \"number\") {\n        mediaType = options.mediaType;\n    }\n    var allowEdit = false;\n    if (typeof options.allowEdit == \"boolean\") {\n        allowEdit = options.allowEdit;\n    } else if (typeof options.allowEdit == \"number\") {\n        allowEdit = options.allowEdit <= 0 ? false : true;\n    }\n    var correctOrientation = false;\n    if (typeof options.correctOrientation == \"boolean\") {\n        correctOrientation = options.correctOrientation;\n    } else if (typeof options.correctOrientation == \"number\") {\n        correctOrientation = options.correctOrientation <=0 ? false : true;\n    }\n    var saveToPhotoAlbum = false;\n    if (typeof options.saveToPhotoAlbum == \"boolean\") {\n        saveToPhotoAlbum = options.saveToPhotoAlbum;\n    } else if (typeof options.saveToPhotoAlbum == \"number\") {\n        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;\n    }\n    var popoverOptions = null;\n    if (typeof options.popoverOptions == \"object\") {\n        popoverOptions = options.popoverOptions;\n    }\n\n    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,\n                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];\n\n    exec(successCallback, errorCallback, \"Camera\", \"takePicture\", args);\n};\n\ncameraExport.cleanup = function(successCallback, errorCallback) {\n    exec(successCallback, errorCallback, \"Camera\", \"cleanup\", []);\n};\n\nmodule.exports = cameraExport;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Camera.js")} catch(e) {console.log("exception: in lib\common\plugin\Camera.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CameraConstants\", function(require, exports, module) {\n\nmodule.exports = {\n  DestinationType:{\n    DATA_URL: 0,         // Return base64 encoded string\n    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)\n  },\n  EncodingType:{\n    JPEG: 0,             // Return JPEG encoded image\n    PNG: 1               // Return PNG encoded image\n  },\n  MediaType:{\n    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType\n    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL\n    ALLMEDIA : 2         // allow selection from all media types\n  },\n  PictureSourceType:{\n    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)\n    CAMERA : 1,          // Take picture from camera\n    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)\n  },\n  PopoverArrowDirection:{\n      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover\n      ARROW_DOWN : 2,\n      ARROW_LEFT : 4,\n      ARROW_RIGHT : 8,\n      ARROW_ANY : 15\n  }\n};\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CameraConstants.js")} catch(e) {console.log("exception: in lib\common\plugin\CameraConstants.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CameraPopoverOptions\", function(require, exports, module) {\n\nvar Camera = require('cordova/plugin/CameraConstants');\n\n/**\n * Encapsulates options for iOS Popover image picker\n */\nvar CameraPopoverOptions = function(x,y,width,height,arrowDir){\n    // information of rectangle that popover should be anchored to\n    this.x = x || 0;\n    this.y = y || 32;\n    this.width = width || 320;\n    this.height = height || 480;\n    // The direction of the popover arrow\n    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;\n};\n\nmodule.exports = CameraPopoverOptions;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CameraPopoverOptions.js")} catch(e) {console.log("exception: in lib\common\plugin\CameraPopoverOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureAudioOptions\", function(require, exports, module) {\n\n/**\n * Encapsulates all audio capture operation configuration options.\n */\nvar CaptureAudioOptions = function(){\n    // Upper limit of sound clips user can record. Value must be equal or greater than 1.\n    this.limit = 1;\n    // Maximum duration of a single sound clip in seconds.\n    this.duration = 0;\n    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureAudioOptions;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CaptureAudioOptions.js")} catch(e) {console.log("exception: in lib\common\plugin\CaptureAudioOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureError\", function(require, exports, module) {\n\n/**\n * The CaptureError interface encapsulates all errors in the Capture API.\n */\nvar CaptureError = function(c) {\n   this.code = c || null;\n};\n\n// Camera or microphone failed to capture image or sound.\nCaptureError.CAPTURE_INTERNAL_ERR = 0;\n// Camera application or audio capture application is currently serving other capture request.\nCaptureError.CAPTURE_APPLICATION_BUSY = 1;\n// Invalid use of the API (e.g. limit parameter has value less than one).\nCaptureError.CAPTURE_INVALID_ARGUMENT = 2;\n// User exited camera application or audio capture application before capturing anything.\nCaptureError.CAPTURE_NO_MEDIA_FILES = 3;\n// The requested capture operation is not supported.\nCaptureError.CAPTURE_NOT_SUPPORTED = 20;\n\nmodule.exports = CaptureError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CaptureError.js")} catch(e) {console.log("exception: in lib\common\plugin\CaptureError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureImageOptions\", function(require, exports, module) {\n\n/**\n * Encapsulates all image capture operation configuration options.\n */\nvar CaptureImageOptions = function(){\n    // Upper limit of images user can take. Value must be equal or greater than 1.\n    this.limit = 1;\n    // The selected image mode. Must match with one of the elements in supportedImageModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureImageOptions;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CaptureImageOptions.js")} catch(e) {console.log("exception: in lib\common\plugin\CaptureImageOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureVideoOptions\", function(require, exports, module) {\n\n/**\n * Encapsulates all video capture operation configuration options.\n */\nvar CaptureVideoOptions = function(){\n    // Upper limit of videos user can record. Value must be equal or greater than 1.\n    this.limit = 1;\n    // Maximum duration of a single video clip in seconds.\n    this.duration = 0;\n    // The selected video mode. Must match with one of the elements in supportedVideoModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureVideoOptions;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CaptureVideoOptions.js")} catch(e) {console.log("exception: in lib\common\plugin\CaptureVideoOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CompassError\", function(require, exports, module) {\n\n/**\n *  CompassError.\n *  An error code assigned by an implementation when an error has occurred\n * @constructor\n */\nvar CompassError = function(err) {\n    this.code = (err !== undefined ? err : null);\n};\n\nCompassError.COMPASS_INTERNAL_ERR = 0;\nCompassError.COMPASS_NOT_SUPPORTED = 20;\n\nmodule.exports = CompassError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CompassError.js")} catch(e) {console.log("exception: in lib\common\plugin\CompassError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CompassHeading\", function(require, exports, module) {\n\nvar CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {\n  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);\n  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);\n  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);\n  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());\n};\n\nmodule.exports = CompassHeading;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\CompassHeading.js")} catch(e) {console.log("exception: in lib\common\plugin\CompassHeading.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ConfigurationData\", function(require, exports, module) {\n\n/**\n * Encapsulates a set of parameters that the capture device supports.\n */\nfunction ConfigurationData() {\n    // The ASCII-encoded string in lower case representing the media type.\n    this.type = null;\n    // The height attribute represents height of the image or video in pixels.\n    // In the case of a sound clip this attribute has value 0.\n    this.height = 0;\n    // The width attribute represents width of the image or video in pixels.\n    // In the case of a sound clip this attribute has value 0\n    this.width = 0;\n}\n\nmodule.exports = ConfigurationData;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ConfigurationData.js")} catch(e) {console.log("exception: in lib\common\plugin\ConfigurationData.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Connection\", function(require, exports, module) {\n\n/**\n * Network status\n */\nmodule.exports = {\n        UNKNOWN: \"unknown\",\n        ETHERNET: \"ethernet\",\n        WIFI: \"wifi\",\n        CELL_2G: \"2g\",\n        CELL_3G: \"3g\",\n        CELL_4G: \"4g\",\n        NONE: \"none\"\n};\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Connection.js")} catch(e) {console.log("exception: in lib\common\plugin\Connection.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Contact\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils');\n\n/**\n* Converts primitives into Complex Object\n* Currently only used for Date fields\n*/\nfunction convertIn(contact) {\n    var value = contact.birthday;\n    try {\n      contact.birthday = new Date(parseFloat(value));\n    } catch (exception){\n      console.log(\"Cordova Contact convertIn error: exception creating date.\");\n    }\n    return contact;\n}\n\n/**\n* Converts Complex objects into primitives\n* Only conversion at present is for Dates.\n**/\n\nfunction convertOut(contact) {\n    var value = contact.birthday;\n    if (value !== null) {\n        // try to make it a Date object if it is not already\n        if (!utils.isDate(value)){\n            try {\n                value = new Date(value);\n            } catch(exception){\n                value = null;\n            }\n        }\n        if (utils.isDate(value)){\n            value = value.valueOf(); // convert to milliseconds\n        }\n        contact.birthday = value;\n    }\n    return contact;\n}\n\n/**\n* Contains information about a single contact.\n* @constructor\n* @param {DOMString} id unique identifier\n* @param {DOMString} displayName\n* @param {ContactName} name\n* @param {DOMString} nickname\n* @param {Array.<ContactField>} phoneNumbers array of phone numbers\n* @param {Array.<ContactField>} emails array of email addresses\n* @param {Array.<ContactAddress>} addresses array of addresses\n* @param {Array.<ContactField>} ims instant messaging user ids\n* @param {Array.<ContactOrganization>} organizations\n* @param {DOMString} birthday contact's birthday\n* @param {DOMString} note user notes about contact\n* @param {Array.<ContactField>} photos\n* @param {Array.<ContactField>} categories\n* @param {Array.<ContactField>} urls contact's web sites\n*/\nvar Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,\n    ims, organizations, birthday, note, photos, categories, urls) {\n    this.id = id || null;\n    this.rawId = null;\n    this.displayName = displayName || null;\n    this.name = name || null; // ContactName\n    this.nickname = nickname || null;\n    this.phoneNumbers = phoneNumbers || null; // ContactField[]\n    this.emails = emails || null; // ContactField[]\n    this.addresses = addresses || null; // ContactAddress[]\n    this.ims = ims || null; // ContactField[]\n    this.organizations = organizations || null; // ContactOrganization[]\n    this.birthday = birthday || null;\n    this.note = note || null;\n    this.photos = photos || null; // ContactField[]\n    this.categories = categories || null; // ContactField[]\n    this.urls = urls || null; // ContactField[]\n};\n\n/**\n* Removes contact from device storage.\n* @param successCB success callback\n* @param errorCB error callback\n*/\nContact.prototype.remove = function(successCB, errorCB) {\n    var fail = function(code) {\n        errorCB(new ContactError(code));\n    };\n    if (this.id === null) {\n        fail(ContactError.UNKNOWN_ERROR);\n    }\n    else {\n        exec(successCB, fail, \"Contacts\", \"remove\", [this.id]);\n    }\n};\n\n/**\n* Creates a deep copy of this Contact.\n* With the contact ID set to null.\n* @return copy of this Contact\n*/\nContact.prototype.clone = function() {\n    var clonedContact = utils.clone(this);\n    var i;\n    clonedContact.id = null;\n    clonedContact.rawId = null;\n    // Loop through and clear out any id's in phones, emails, etc.\n    if (clonedContact.phoneNumbers) {\n        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {\n            clonedContact.phoneNumbers[i].id = null;\n        }\n    }\n    if (clonedContact.emails) {\n        for (i = 0; i < clonedContact.emails.length; i++) {\n            clonedContact.emails[i].id = null;\n        }\n    }\n    if (clonedContact.addresses) {\n        for (i = 0; i < clonedContact.addresses.length; i++) {\n            clonedContact.addresses[i].id = null;\n        }\n    }\n    if (clonedContact.ims) {\n        for (i = 0; i < clonedContact.ims.length; i++) {\n            clonedContact.ims[i].id = null;\n        }\n    }\n    if (clonedContact.organizations) {\n        for (i = 0; i < clonedContact.organizations.length; i++) {\n            clonedContact.organizations[i].id = null;\n        }\n    }\n    if (clonedContact.categories) {\n        for (i = 0; i < clonedContact.categories.length; i++) {\n            clonedContact.categories[i].id = null;\n        }\n    }\n    if (clonedContact.photos) {\n        for (i = 0; i < clonedContact.photos.length; i++) {\n            clonedContact.photos[i].id = null;\n        }\n    }\n    if (clonedContact.urls) {\n        for (i = 0; i < clonedContact.urls.length; i++) {\n            clonedContact.urls[i].id = null;\n        }\n    }\n    return clonedContact;\n};\n\n/**\n* Persists contact to device storage.\n* @param successCB success callback\n* @param errorCB error callback\n*/\nContact.prototype.save = function(successCB, errorCB) {\n  var fail = function(code) {\n      errorCB(new ContactError(code));\n  };\n    var success = function(result) {\n      if (result) {\n          if (typeof successCB === 'function') {\n              var fullContact = require('cordova/plugin/contacts').create(result);\n              successCB(convertIn(fullContact));\n          }\n      }\n      else {\n          // no Entry object returned\n          fail(ContactError.UNKNOWN_ERROR);\n      }\n  };\n    var dupContact = convertOut(utils.clone(this));\n    exec(success, fail, \"Contacts\", \"save\", [dupContact]);\n};\n\n\nmodule.exports = Contact;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Contact.js")} catch(e) {console.log("exception: in lib\common\plugin\Contact.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactAddress\", function(require, exports, module) {\n\n/**\n* Contact address.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code\n* @param formatted // NOTE: not a W3C standard\n* @param streetAddress\n* @param locality\n* @param region\n* @param postalCode\n* @param country\n*/\n\nvar ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {\n    this.id = null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n    this.type = type || null;\n    this.formatted = formatted || null;\n    this.streetAddress = streetAddress || null;\n    this.locality = locality || null;\n    this.region = region || null;\n    this.postalCode = postalCode || null;\n    this.country = country || null;\n};\n\nmodule.exports = ContactAddress;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ContactAddress.js")} catch(e) {console.log("exception: in lib\common\plugin\ContactAddress.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactError\", function(require, exports, module) {\n\n/**\n *  ContactError.\n *  An error code assigned by an implementation when an error has occurred\n * @constructor\n */\nvar ContactError = function(err) {\n    this.code = (typeof err != 'undefined' ? err : null);\n};\n\n/**\n * Error codes\n */\nContactError.UNKNOWN_ERROR = 0;\nContactError.INVALID_ARGUMENT_ERROR = 1;\nContactError.TIMEOUT_ERROR = 2;\nContactError.PENDING_OPERATION_ERROR = 3;\nContactError.IO_ERROR = 4;\nContactError.NOT_SUPPORTED_ERROR = 5;\nContactError.PERMISSION_DENIED_ERROR = 20;\n\nmodule.exports = ContactError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ContactError.js")} catch(e) {console.log("exception: in lib\common\plugin\ContactError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactField\", function(require, exports, module) {\n\n/**\n* Generic contact field.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard\n* @param type\n* @param value\n* @param pref\n*/\nvar ContactField = function(type, value, pref) {\n    this.id = null;\n    this.type = (type && type.toString()) || null;\n    this.value = (value && value.toString()) || null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n};\n\nmodule.exports = ContactField;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ContactField.js")} catch(e) {console.log("exception: in lib\common\plugin\ContactField.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactFindOptions\", function(require, exports, module) {\n\n/**\n * ContactFindOptions.\n * @constructor\n * @param filter used to match contacts against\n * @param multiple boolean used to determine if more than one contact should be returned\n */\n\nvar ContactFindOptions = function(filter, multiple) {\n    this.filter = filter || '';\n    this.multiple = (typeof multiple != 'undefined' ? multiple : false);\n};\n\nmodule.exports = ContactFindOptions;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ContactFindOptions.js")} catch(e) {console.log("exception: in lib\common\plugin\ContactFindOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactName\", function(require, exports, module) {\n\n/**\n* Contact name.\n* @constructor\n* @param formatted // NOTE: not part of W3C standard\n* @param familyName\n* @param givenName\n* @param middle\n* @param prefix\n* @param suffix\n*/\nvar ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {\n    this.formatted = formatted || null;\n    this.familyName = familyName || null;\n    this.givenName = givenName || null;\n    this.middleName = middle || null;\n    this.honorificPrefix = prefix || null;\n    this.honorificSuffix = suffix || null;\n};\n\nmodule.exports = ContactName;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ContactName.js")} catch(e) {console.log("exception: in lib\common\plugin\ContactName.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactOrganization\", function(require, exports, module) {\n\n/**\n* Contact organization.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard\n* @param name\n* @param dept\n* @param title\n* @param startDate\n* @param endDate\n* @param location\n* @param desc\n*/\n\nvar ContactOrganization = function(pref, type, name, dept, title) {\n    this.id = null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n    this.type = type || null;\n    this.name = name || null;\n    this.department = dept || null;\n    this.title = title || null;\n};\n\nmodule.exports = ContactOrganization;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ContactOrganization.js")} catch(e) {console.log("exception: in lib\common\plugin\ContactOrganization.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Coordinates\", function(require, exports, module) {\n\n/**\n * This class contains position information.\n * @param {Object} lat\n * @param {Object} lng\n * @param {Object} alt\n * @param {Object} acc\n * @param {Object} head\n * @param {Object} vel\n * @param {Object} altacc\n * @constructor\n */\nvar Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {\n    /**\n     * The latitude of the position.\n     */\n    this.latitude = lat;\n    /**\n     * The longitude of the position,\n     */\n    this.longitude = lng;\n    /**\n     * The accuracy of the position.\n     */\n    this.accuracy = acc;\n    /**\n     * The altitude of the position.\n     */\n    this.altitude = (alt !== undefined ? alt : null);\n    /**\n     * The direction the device is moving at the position.\n     */\n    this.heading = (head !== undefined ? head : null);\n    /**\n     * The velocity with which the device is moving at the position.\n     */\n    this.speed = (vel !== undefined ? vel : null);\n\n    if (this.speed === 0 || this.speed === null) {\n        this.heading = NaN;\n    }\n\n    /**\n     * The altitude accuracy of the position.\n     */\n    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;\n};\n\nmodule.exports = Coordinates;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Coordinates.js")} catch(e) {console.log("exception: in lib\common\plugin\Coordinates.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/DirectoryEntry\", function(require, exports, module) {\n\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('cordova/plugin/Entry'),\n    FileError = require('cordova/plugin/FileError'),\n    DirectoryReader = require('cordova/plugin/DirectoryReader');\n\n/**\n * An interface representing a directory on the file system.\n *\n * {boolean} isFile always false (readonly)\n * {boolean} isDirectory always true (readonly)\n * {DOMString} name of the directory, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the directory (readonly)\n * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)\n */\nvar DirectoryEntry = function(name, fullPath) {\n     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);\n};\n\nutils.extend(DirectoryEntry, Entry);\n\n/**\n * Creates a new DirectoryReader to read entries from this directory\n */\nDirectoryEntry.prototype.createReader = function() {\n    return new DirectoryReader(this.fullPath);\n};\n\n/**\n * Creates or looks up a directory\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory\n * @param {Flags} options to create or exclusively create the directory\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var entry = new DirectoryEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getDirectory\", [this.fullPath, path, options]);\n};\n\n/**\n * Deletes a directory and all of it's contents\n *\n * @param {Function} successCallback is called with no parameters\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"removeRecursively\", [this.fullPath]);\n};\n\n/**\n * Creates or looks up a file\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file\n * @param {Flags} options to create or exclusively create the file\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var FileEntry = require('cordova/plugin/FileEntry');\n        var entry = new FileEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFile\", [this.fullPath, path, options]);\n};\n\nmodule.exports = DirectoryEntry;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\DirectoryEntry.js")} catch(e) {console.log("exception: in lib\common\plugin\DirectoryEntry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/DirectoryReader\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError') ;\n\n/**\n * An interface that lists the files and directories in a directory.\n */\nfunction DirectoryReader(path) {\n    this.path = path || null;\n}\n\n/**\n * Returns a list of entries from a directory.\n *\n * @param {Function} successCallback is called with a list of entries\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var retVal = [];\n        for (var i=0; i<result.length; i++) {\n            var entry = null;\n            if (result[i].isDirectory) {\n                entry = new (require('cordova/plugin/DirectoryEntry'))();\n            }\n            else if (result[i].isFile) {\n                entry = new (require('cordova/plugin/FileEntry'))();\n            }\n            entry.isDirectory = result[i].isDirectory;\n            entry.isFile = result[i].isFile;\n            entry.name = result[i].name;\n            entry.fullPath = result[i].fullPath;\n            retVal.push(entry);\n        }\n        successCallback(retVal);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"readEntries\", [this.path]);\n};\n\nmodule.exports = DirectoryReader;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\DirectoryReader.js")} catch(e) {console.log("exception: in lib\common\plugin\DirectoryReader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Entry\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    Metadata = require('cordova/plugin/Metadata');\n\n/**\n * Represents a file or directory on the local file system.\n *\n * @param isFile\n *            {boolean} true if Entry is a file (readonly)\n * @param isDirectory\n *            {boolean} true if Entry is a directory (readonly)\n * @param name\n *            {DOMString} name of the file or directory, excluding the path\n *            leading to it (readonly)\n * @param fullPath\n *            {DOMString} the absolute full path to the file or directory\n *            (readonly)\n */\nfunction Entry(isFile, isDirectory, name, fullPath, fileSystem) {\n    this.isFile = (typeof isFile != 'undefined'?isFile:false);\n    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);\n    this.name = name || '';\n    this.fullPath = fullPath || '';\n    this.filesystem = fileSystem || null;\n}\n\n/**\n * Look up the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n */\nEntry.prototype.getMetadata = function(successCallback, errorCallback) {\n  var success = typeof successCallback !== 'function' ? null : function(lastModified) {\n      var metadata = new Metadata(lastModified);\n      successCallback(metadata);\n  };\n  var fail = typeof errorCallback !== 'function' ? null : function(code) {\n      errorCallback(new FileError(code));\n  };\n\n  exec(success, fail, \"File\", \"getMetadata\", [this.fullPath]);\n};\n\n/**\n * Set the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n * @param metadataObject\n *            {Object} keys and values to set\n */\nEntry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {\n\n  exec(successCallback, errorCallback, \"File\", \"setMetadata\", [this.fullPath, metadataObject]);\n};\n\n/**\n * Move a file or directory to a new location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to move this entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new DirectoryEntry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n    // user must specify parent Entry\n    if (!parent) {\n        fail(FileError.NOT_FOUND_ERR);\n        return;\n    }\n    // source path\n    var srcPath = this.fullPath,\n        // entry name\n        name = newName || this.name,\n        success = function(entry) {\n            if (entry) {\n                if (typeof successCallback === 'function') {\n                    // create appropriate Entry object\n                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);\n                    try {\n                        successCallback(result);\n                    }\n                    catch (e) {\n                        console.log('Error invoking callback: ' + e);\n                    }\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"moveTo\", [srcPath, parent.fullPath, name]);\n};\n\n/**\n * Copy a directory to a different location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to copy the entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new Entry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n\n    // user must specify parent Entry\n    if (!parent) {\n        fail(FileError.NOT_FOUND_ERR);\n        return;\n    }\n\n        // source path\n    var srcPath = this.fullPath,\n        // entry name\n        name = newName || this.name,\n        // success callback\n        success = function(entry) {\n            if (entry) {\n                if (typeof successCallback === 'function') {\n                    // create appropriate Entry object\n                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);\n                    try {\n                        successCallback(result);\n                    }\n                    catch (e) {\n                        console.log('Error invoking callback: ' + e);\n                    }\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"copyTo\", [srcPath, parent.fullPath, name]);\n};\n\n/**\n * Return a URL that can be used to identify this entry.\n */\nEntry.prototype.toURL = function() {\n    // fullPath attribute contains the full URL\n    return this.fullPath;\n};\n\n/**\n * Returns a URI that can be used to identify this entry.\n *\n * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.\n * @return uri\n */\nEntry.prototype.toURI = function(mimeType) {\n    console.log(\"DEPRECATED: Update your code to use 'toURL'\");\n    // fullPath attribute contains the full URI\n    return this.toURL();\n};\n\n/**\n * Remove a file or directory. It is an error to attempt to delete a\n * directory that is not empty. It is an error to attempt to delete a\n * root directory of a file system.\n *\n * @param successCallback {Function} called with no parameters\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.remove = function(successCallback, errorCallback) {\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"remove\", [this.fullPath]);\n};\n\n/**\n * Look up the parent DirectoryEntry of this entry.\n *\n * @param successCallback {Function} called with the parent DirectoryEntry object\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.getParent = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');\n        var entry = new DirectoryEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getParent\", [this.fullPath]);\n};\n\nmodule.exports = Entry;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Entry.js")} catch(e) {console.log("exception: in lib\common\plugin\Entry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/File\", function(require, exports, module) {\n\n/**\n * Constructor.\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\n\nvar File = function(name, fullPath, type, lastModifiedDate, size){\n    this.name = name || '';\n    this.fullPath = fullPath || null;\n    this.type = type || null;\n    this.lastModifiedDate = lastModifiedDate || null;\n    this.size = size || 0;\n};\n\nmodule.exports = File;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\File.js")} catch(e) {console.log("exception: in lib\common\plugin\File.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileEntry\", function(require, exports, module) {\n\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('cordova/plugin/Entry'),\n    FileWriter = require('cordova/plugin/FileWriter'),\n    File = require('cordova/plugin/File'),\n    FileError = require('cordova/plugin/FileError');\n\n/**\n * An interface representing a file on the file system.\n *\n * {boolean} isFile always true (readonly)\n * {boolean} isDirectory always false (readonly)\n * {DOMString} name of the file, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the file (readonly)\n * {FileSystem} filesystem on which the file resides (readonly)\n */\nvar FileEntry = function(name, fullPath) {\n     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);\n};\n\nutils.extend(FileEntry, Entry);\n\n/**\n * Creates a new FileWriter associated with the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new FileWriter\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.createWriter = function(successCallback, errorCallback) {\n    this.file(function(filePointer) {\n        var writer = new FileWriter(filePointer);\n\n        if (writer.fileName === null || writer.fileName === \"\") {\n            if (typeof errorCallback === \"function\") {\n                errorCallback(new FileError(FileError.INVALID_STATE_ERR));\n            }\n        } else {\n            if (typeof successCallback === \"function\") {\n                successCallback(writer);\n            }\n        }\n    }, errorCallback);\n};\n\n/**\n * Returns a File that represents the current state of the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new File object\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.file = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(f) {\n        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);\n        successCallback(file);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFileMetadata\", [this.fullPath]);\n};\n\n\nmodule.exports = FileEntry;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileEntry.js")} catch(e) {console.log("exception: in lib\common\plugin\FileEntry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileError\", function(require, exports, module) {\n\n/**\n * FileError\n */\nfunction FileError(error) {\n  this.code = error || null;\n}\n\n// File error codes\n// Found in DOMException\nFileError.NOT_FOUND_ERR = 1;\nFileError.SECURITY_ERR = 2;\nFileError.ABORT_ERR = 3;\n\n// Added by File API specification\nFileError.NOT_READABLE_ERR = 4;\nFileError.ENCODING_ERR = 5;\nFileError.NO_MODIFICATION_ALLOWED_ERR = 6;\nFileError.INVALID_STATE_ERR = 7;\nFileError.SYNTAX_ERR = 8;\nFileError.INVALID_MODIFICATION_ERR = 9;\nFileError.QUOTA_EXCEEDED_ERR = 10;\nFileError.TYPE_MISMATCH_ERR = 11;\nFileError.PATH_EXISTS_ERR = 12;\n\nmodule.exports = FileError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileError.js")} catch(e) {console.log("exception: in lib\common\plugin\FileError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileReader\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\n/**\n * This class reads the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To read from the SD card, the file name is \"sdcard/my_file.txt\"\n * @constructor\n */\nvar FileReader = function() {\n    this.fileName = \"\";\n\n    this.readyState = 0; // FileReader.EMPTY\n\n    // File data\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onloadstart = null;    // When the read starts.\n    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)\n    this.onload = null;         // When the read has successfully completed.\n    this.onerror = null;        // When the read has failed (see errors).\n    this.onloadend = null;      // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.\n};\n\n// States\nFileReader.EMPTY = 0;\nFileReader.LOADING = 1;\nFileReader.DONE = 2;\n\n/**\n * Abort reading file.\n */\nFileReader.prototype.abort = function() {\n    this.result = null;\n\n    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {\n      return;\n    }\n\n    this.readyState = FileReader.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === 'function') {\n        this.onabort(new ProgressEvent('abort', {target:this}));\n    }\n    // If load end callback\n    if (typeof this.onloadend === 'function') {\n        this.onloadend(new ProgressEvent('loadend', {target:this}));\n    }\n};\n\n/**\n * Read text file.\n *\n * @param file          {File} File object containing file properties\n * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)\n */\nFileReader.prototype.readAsText = function(file, encoding) {\n    // Figure out pathing\n    this.fileName = '';\n    if (typeof file.fullPath === 'undefined') {\n        this.fileName = file;\n    } else {\n        this.fileName = file.fullPath;\n    }\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    // Default encoding is UTF-8\n    var enc = encoding ? encoding : \"UTF-8\";\n\n    var me = this;\n\n    // Read file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // Save result\n            me.result = r;\n\n            // If onload callback\n            if (typeof me.onload === \"function\") {\n                me.onload(new ProgressEvent(\"load\", {target:me}));\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // null result\n            me.result = null;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        }, \"File\", \"readAsText\", [this.fileName, enc]);\n};\n\n\n/**\n * Read file and return data as a base64 encoded data url.\n * A data url is of the form:\n *      data:[<mediatype>][;base64],<data>\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsDataURL = function(file) {\n    this.fileName = \"\";\n    if (typeof file.fullPath === \"undefined\") {\n        this.fileName = file;\n    } else {\n        this.fileName = file.fullPath;\n    }\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    var me = this;\n\n    // Read file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // Save result\n            me.result = r;\n\n            // If onload callback\n            if (typeof me.onload === \"function\") {\n                me.onload(new ProgressEvent(\"load\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            me.result = null;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        }, \"File\", \"readAsDataURL\", [this.fileName]);\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsBinaryString = function(file) {\n    // TODO - Can't return binary data to browser.\n    console.log('method \"readAsBinaryString\" is not supported at this time.');\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsArrayBuffer = function(file) {\n    // TODO - Can't return binary data to browser.\n    console.log('This method is not supported at this time.');\n};\n\nmodule.exports = FileReader;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileReader.js")} catch(e) {console.log("exception: in lib\common\plugin\FileReader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileSystem\", function(require, exports, module) {\n\nvar DirectoryEntry = require('cordova/plugin/DirectoryEntry');\n\n/**\n * An interface representing a file system\n *\n * @constructor\n * {DOMString} name the unique name of the file system (readonly)\n * {DirectoryEntry} root directory of the file system (readonly)\n */\nvar FileSystem = function(name, root) {\n    this.name = name || null;\n    if (root) {\n        this.root = new DirectoryEntry(root.name, root.fullPath);\n    }\n};\n\nmodule.exports = FileSystem;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileSystem.js")} catch(e) {console.log("exception: in lib\common\plugin\FileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileTransfer\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    FileTransferError = require('cordova/plugin/FileTransferError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\nfunction newProgressEvent(result) {\n    var pe = new ProgressEvent();\n    pe.lengthComputable = result.lengthComputable;\n    pe.loaded = result.loaded;\n    pe.total = result.total;\n    return pe;\n}\n\nvar idCounter = 0;\n\n/**\n * FileTransfer uploads a file to a remote server.\n * @constructor\n */\nvar FileTransfer = function() {\n    this._id = ++idCounter;\n    this.onprogress = null; // optional callback\n};\n\n/**\n* Given an absolute file path, uploads a file on the device to a remote server\n* using a multipart HTTP request.\n* @param filePath {String}           Full path of the file on the device\n* @param server {String}             URL of the server to receive the file\n* @param successCallback (Function}  Callback to be invoked when upload has completed\n* @param errorCallback {Function}    Callback to be invoked upon error\n* @param options {FileUploadOptions} Optional parameters such as file name and mimetype\n* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n*/\nFileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {\n    // sanity parameter checking\n    if (!filePath || !server) throw new Error(\"FileTransfer.upload requires filePath and server URL parameters at the minimum.\");\n    // check for options\n    var fileKey = null;\n    var fileName = null;\n    var mimeType = null;\n    var params = null;\n    var chunkedMode = true;\n    var headers = null;\n    if (options) {\n        fileKey = options.fileKey;\n        fileName = options.fileName;\n        mimeType = options.mimeType;\n        headers = options.headers;\n        if (options.chunkedMode !== null || typeof options.chunkedMode != \"undefined\") {\n            chunkedMode = options.chunkedMode;\n        }\n        if (options.params) {\n            params = options.params;\n        }\n        else {\n            params = {};\n        }\n    }\n\n    var fail = function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);\n        errorCallback(error);\n    };\n\n    var self = this;\n    var win = function(result) {\n        if (typeof result.lengthComputable != \"undefined\") {\n            if (self.onprogress) {\n                return self.onprogress(newProgressEvent(result));\n            }\n        } else {\n            return successCallback(result);\n        }\n    };\n    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id]);\n};\n\n/**\n * Downloads a file form a given URL and saves it to the specified directory.\n * @param source {String}          URL of the server to receive the file\n * @param target {String}         Full path of the file on the device\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n */\nFileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {\n    // sanity parameter checking\n    if (!source || !target) throw new Error(\"FileTransfer.download requires source URI and target URI parameters at the minimum.\");\n    var self = this;\n    var win = function(result) {\n        if (typeof result.lengthComputable != \"undefined\") {\n            if (self.onprogress) {\n                return self.onprogress(newProgressEvent(result));\n            }\n        } else {\n            var entry = null;\n            if (result.isDirectory) {\n                entry = new (require('cordova/plugin/DirectoryEntry'))();\n            }\n            else if (result.isFile) {\n                entry = new (require('cordova/plugin/FileEntry'))();\n            }\n            entry.isDirectory = result.isDirectory;\n            entry.isFile = result.isFile;\n            entry.name = result.name;\n            entry.fullPath = result.fullPath;\n            successCallback(entry);\n        }\n    };\n\n    var fail = function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);\n        errorCallback(error);\n    };\n\n    exec(win, errorCallback, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);\n};\n\n/**\n * Aborts the ongoing file transfer on this object\n * @param successCallback {Function}  Callback to be invoked upon success\n * @param errorCallback {Function}    Callback to be invoked upon error\n */\nFileTransfer.prototype.abort = function(successCallback, errorCallback) {\n    exec(successCallback, errorCallback, 'FileTransfer', 'abort', [this._id]);\n};\n\nmodule.exports = FileTransfer;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileTransfer.js")} catch(e) {console.log("exception: in lib\common\plugin\FileTransfer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileTransferError\", function(require, exports, module) {\n\n/**\n * FileTransferError\n * @constructor\n */\nvar FileTransferError = function(code, source, target, status) {\n    this.code = code || null;\n    this.source = source || null;\n    this.target = target || null;\n    this.http_status = status || null;\n};\n\nFileTransferError.FILE_NOT_FOUND_ERR = 1;\nFileTransferError.INVALID_URL_ERR = 2;\nFileTransferError.CONNECTION_ERR = 3;\nFileTransferError.ABORT_ERR = 4;\n\nmodule.exports = FileTransferError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileTransferError.js")} catch(e) {console.log("exception: in lib\common\plugin\FileTransferError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileUploadOptions\", function(require, exports, module) {\n\n/**\n * Options to customize the HTTP request used to upload files.\n * @constructor\n * @param fileKey {String}   Name of file request parameter.\n * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.\n * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.\n * @param params {Object}    Object with key: value params to send to the server.\n * @param headers {Object}   Keys are header names, values are header values. Multiple\n *                           headers of the same name are not supported.\n */\nvar FileUploadOptions = function(fileKey, fileName, mimeType, params, headers) {\n    this.fileKey = fileKey || null;\n    this.fileName = fileName || null;\n    this.mimeType = mimeType || null;\n    this.params = params || null;\n    this.headers = headers || null;\n};\n\nmodule.exports = FileUploadOptions;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileUploadOptions.js")} catch(e) {console.log("exception: in lib\common\plugin\FileUploadOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileUploadResult\", function(require, exports, module) {\n\n/**\n * FileUploadResult\n * @constructor\n */\nvar FileUploadResult = function() {\n    this.bytesSent = 0;\n    this.responseCode = null;\n    this.response = null;\n};\n\nmodule.exports = FileUploadResult;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileUploadResult.js")} catch(e) {console.log("exception: in lib\common\plugin\FileUploadResult.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileWriter\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\n/**\n * This class writes to the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To write to the SD card, the file name is \"sdcard/my_file.txt\"\n *\n * @constructor\n * @param file {File} File object containing file properties\n * @param append if true write to the end of the file, otherwise overwrite the file\n */\nvar FileWriter = function(file) {\n    this.fileName = \"\";\n    this.length = 0;\n    if (file) {\n        this.fileName = file.fullPath || file;\n        this.length = file.size || 0;\n    }\n    // default is to write at the beginning of the file\n    this.position = 0;\n\n    this.readyState = 0; // EMPTY\n\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onwritestart = null;   // When writing starts\n    this.onprogress = null;     // While writing the file, and reporting partial file data\n    this.onwrite = null;        // When the write has successfully completed.\n    this.onwriteend = null;     // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.\n    this.onerror = null;        // When the write has failed (see errors).\n};\n\n// States\nFileWriter.INIT = 0;\nFileWriter.WRITING = 1;\nFileWriter.DONE = 2;\n\n/**\n * Abort writing file.\n */\nFileWriter.prototype.abort = function() {\n    // check for invalid state\n    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // set error\n    this.error = new FileError(FileError.ABORT_ERR);\n\n    this.readyState = FileWriter.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === \"function\") {\n        this.onabort(new ProgressEvent(\"abort\", {\"target\":this}));\n    }\n\n    // If write end callback\n    if (typeof this.onwriteend === \"function\") {\n        this.onwriteend(new ProgressEvent(\"writeend\", {\"target\":this}));\n    }\n};\n\n/**\n * Writes data to the file\n *\n * @param text to be written\n */\nFileWriter.prototype.write = function(text) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":me}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // position always increases by bytes written because file would be extended\n            me.position += r;\n            // The length of the file is now where we are done writing.\n\n            me.length = me.position;\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"write\", [this.fileName, text, this.position]);\n};\n\n/**\n * Moves the file pointer to the location specified.\n *\n * If the offset is a negative number the position of the file\n * pointer is rewound.  If the offset is greater than the file\n * size the position is set to the end of the file.\n *\n * @param offset is the location to move the file pointer to.\n */\nFileWriter.prototype.seek = function(offset) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    if (!offset && offset !== 0) {\n        return;\n    }\n\n    // See back from end of file.\n    if (offset < 0) {\n        this.position = Math.max(offset + this.length, 0);\n    }\n    // Offset is bigger than file size so set position\n    // to the end of the file.\n    else if (offset > this.length) {\n        this.position = this.length;\n    }\n    // Offset is between 0 and file size so set the position\n    // to start writing.\n    else {\n        this.position = offset;\n    }\n};\n\n/**\n * Truncates the file to the size specified.\n *\n * @param size to chop the file at.\n */\nFileWriter.prototype.truncate = function(size) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":this}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Update the length of the file\n            me.length = r;\n            me.position = Math.min(me.position, r);\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"truncate\", [this.fileName, size]);\n};\n\nmodule.exports = FileWriter;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\FileWriter.js")} catch(e) {console.log("exception: in lib\common\plugin\FileWriter.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Flags\", function(require, exports, module) {\n\n/**\n * Supplies arguments to methods that lookup or create files and directories.\n *\n * @param create\n *            {boolean} file or directory if it doesn't exist\n * @param exclusive\n *            {boolean} used with create; if true the command will fail if\n *            target path exists\n */\nfunction Flags(create, exclusive) {\n    this.create = create || false;\n    this.exclusive = exclusive || false;\n}\n\nmodule.exports = Flags;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Flags.js")} catch(e) {console.log("exception: in lib\common\plugin\Flags.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/GlobalizationError\", function(require, exports, module) {\n\n\n/**\n * Globalization error object\n *\n * @constructor\n * @param code\n * @param message\n */\nvar GlobalizationError = function(code, message) {\n    this.code = code || null;\n    this.message = message || '';\n};\n\n// Globalization error codes\nGlobalizationError.UNKNOWN_ERROR = 0;\nGlobalizationError.FORMATTING_ERROR = 1;\nGlobalizationError.PARSING_ERROR = 2;\nGlobalizationError.PATTERN_ERROR = 3;\n\nmodule.exports = GlobalizationError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\GlobalizationError.js")} catch(e) {console.log("exception: in lib\common\plugin\GlobalizationError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/LocalFileSystem\", function(require, exports, module) {\n\nvar exec = require('cordova/exec');\n\n/**\n * Represents a local file system.\n */\nvar LocalFileSystem = function() {\n\n};\n\nLocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence\nLocalFileSystem.PERSISTENT = 1; //persistent\n\nmodule.exports = LocalFileSystem;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\LocalFileSystem.js")} catch(e) {console.log("exception: in lib\common\plugin\LocalFileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Media\", function(require, exports, module) {\n\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\nvar mediaObjects = {};\n\n/**\n * This class provides access to the device media, interfaces to both sound and video\n *\n * @constructor\n * @param src                   The file name or url to play\n * @param successCallback       The callback to be called when the file is done playing or recording.\n *                                  successCallback()\n * @param errorCallback         The callback to be called if there is an error.\n *                                  errorCallback(int errorCode) - OPTIONAL\n * @param statusCallback        The callback to be called when media status has changed.\n *                                  statusCallback(int statusCode) - OPTIONAL\n */\nvar Media = function(src, successCallback, errorCallback, statusCallback) {\n\n    // successCallback optional\n    if (successCallback && (typeof successCallback !== \"function\")) {\n        console.log(\"Media Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback !== \"function\")) {\n        console.log(\"Media Error: errorCallback is not a function\");\n        return;\n    }\n\n    // statusCallback optional\n    if (statusCallback && (typeof statusCallback !== \"function\")) {\n        console.log(\"Media Error: statusCallback is not a function\");\n        return;\n    }\n\n    this.id = utils.createUUID();\n    mediaObjects[this.id] = this;\n    this.src = src;\n    this.successCallback = successCallback;\n    this.errorCallback = errorCallback;\n    this.statusCallback = statusCallback;\n    this._duration = -1;\n    this._position = -1;\n    exec(null, this.errorCallback, \"Media\", \"create\", [this.id, this.src]);\n};\n\n// Media messages\nMedia.MEDIA_STATE = 1;\nMedia.MEDIA_DURATION = 2;\nMedia.MEDIA_POSITION = 3;\nMedia.MEDIA_ERROR = 9;\n\n// Media states\nMedia.MEDIA_NONE = 0;\nMedia.MEDIA_STARTING = 1;\nMedia.MEDIA_RUNNING = 2;\nMedia.MEDIA_PAUSED = 3;\nMedia.MEDIA_STOPPED = 4;\nMedia.MEDIA_MSG = [\"None\", \"Starting\", \"Running\", \"Paused\", \"Stopped\"];\n\n// \"static\" function to return existing objs.\nMedia.get = function(id) {\n    return mediaObjects[id];\n};\n\n/**\n * Start or resume playing audio file.\n */\nMedia.prototype.play = function(options) {\n    exec(null, null, \"Media\", \"startPlayingAudio\", [this.id, this.src, options]);\n};\n\n/**\n * Stop playing audio file.\n */\nMedia.prototype.stop = function() {\n    var me = this;\n    exec(function() {\n        me._position = 0;\n    }, this.errorCallback, \"Media\", \"stopPlayingAudio\", [this.id]);\n};\n\n/**\n * Seek or jump to a new time in the track..\n */\nMedia.prototype.seekTo = function(milliseconds) {\n    var me = this;\n    exec(function(p) {\n        me._position = p;\n    }, this.errorCallback, \"Media\", \"seekToAudio\", [this.id, milliseconds]);\n};\n\n/**\n * Pause playing audio file.\n */\nMedia.prototype.pause = function() {\n    exec(null, this.errorCallback, \"Media\", \"pausePlayingAudio\", [this.id]);\n};\n\n/**\n * Get duration of an audio file.\n * The duration is only set for audio that is playing, paused or stopped.\n *\n * @return      duration or -1 if not known.\n */\nMedia.prototype.getDuration = function() {\n    return this._duration;\n};\n\n/**\n * Get position of audio.\n */\nMedia.prototype.getCurrentPosition = function(success, fail) {\n    var me = this;\n    exec(function(p) {\n        me._position = p;\n        success(p);\n    }, fail, \"Media\", \"getCurrentPositionAudio\", [this.id]);\n};\n\n/**\n * Start recording audio file.\n */\nMedia.prototype.startRecord = function() {\n    exec(null, this.errorCallback, \"Media\", \"startRecordingAudio\", [this.id, this.src]);\n};\n\n/**\n * Stop recording audio file.\n */\nMedia.prototype.stopRecord = function() {\n    exec(null, this.errorCallback, \"Media\", \"stopRecordingAudio\", [this.id]);\n};\n\n/**\n * Release the resources.\n */\nMedia.prototype.release = function() {\n    exec(null, this.errorCallback, \"Media\", \"release\", [this.id]);\n};\n\n/**\n * Adjust the volume.\n */\nMedia.prototype.setVolume = function(volume) {\n    exec(null, null, \"Media\", \"setVolume\", [this.id, volume]);\n};\n\n/**\n * Audio has status update.\n * PRIVATE\n *\n * @param id            The media object id (string)\n * @param msgType       The 'type' of update this is\n * @param value         Use of value is determined by the msgType\n */\nMedia.onStatus = function(id, msgType, value) {\n\n    var media = mediaObjects[id];\n\n    if(media) {\n        switch(msgType) {\n            case Media.MEDIA_STATE :\n                media.statusCallback && media.statusCallback(value);\n                if(value == Media.MEDIA_STOPPED) {\n                    media.successCallback && media.successCallback();\n                }\n                break;\n            case Media.MEDIA_DURATION :\n                media._duration = value;\n                break;\n            case Media.MEDIA_ERROR :\n                media.errorCallback && media.errorCallback(value);\n                break;\n            case Media.MEDIA_POSITION :\n                media._position = Number(value);\n                break;\n            default :\n                console && console.error && console.error(\"Unhandled Media.onStatus :: \" + msgType);\n                break;\n        }\n    }\n    else {\n         console && console.error && console.error(\"Received Media.onStatus callback for unknown media :: \" + id);\n    }\n\n};\n\nmodule.exports = Media;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Media.js")} catch(e) {console.log("exception: in lib\common\plugin\Media.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaError\", function(require, exports, module) {\n\n/**\n * This class contains information about any Media errors.\n*/\n/*\n According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror\n We should never be creating these objects, we should just implement the interface\n which has 1 property for an instance, 'code'\n\n instead of doing :\n    errorCallbackFunction( new MediaError(3,'msg') );\nwe should simply use a literal :\n    errorCallbackFunction( {'code':3} );\n */\n\n var _MediaError = window.MediaError;\n\n\nif(!_MediaError) {\n    window.MediaError = _MediaError = function(code, msg) {\n        this.code = (typeof code != 'undefined') ? code : null;\n        this.message = msg || \"\"; // message is NON-standard! do not use!\n    };\n}\n\n_MediaError.MEDIA_ERR_NONE_ACTIVE    = _MediaError.MEDIA_ERR_NONE_ACTIVE    || 0;\n_MediaError.MEDIA_ERR_ABORTED        = _MediaError.MEDIA_ERR_ABORTED        || 1;\n_MediaError.MEDIA_ERR_NETWORK        = _MediaError.MEDIA_ERR_NETWORK        || 2;\n_MediaError.MEDIA_ERR_DECODE         = _MediaError.MEDIA_ERR_DECODE         || 3;\n_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;\n// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.\n// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes\n_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;\n\nmodule.exports = _MediaError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\MediaError.js")} catch(e) {console.log("exception: in lib\common\plugin\MediaError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaFile\", function(require, exports, module) {\n\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    File = require('cordova/plugin/File'),\n    CaptureError = require('cordova/plugin/CaptureError');\n/**\n * Represents a single file.\n *\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\nvar MediaFile = function(name, fullPath, type, lastModifiedDate, size){\n    MediaFile.__super__.constructor.apply(this, arguments);\n};\n\nutils.extend(MediaFile, File);\n\n/**\n * Request capture format data for a specific file and type\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n */\nMediaFile.prototype.getFormatData = function(successCallback, errorCallback) {\n    if (typeof this.fullPath === \"undefined\" || this.fullPath === null) {\n        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));\n    } else {\n        exec(successCallback, errorCallback, \"Capture\", \"getFormatData\", [this.fullPath, this.type]);\n    }\n};\n\nmodule.exports = MediaFile;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\MediaFile.js")} catch(e) {console.log("exception: in lib\common\plugin\MediaFile.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaFileData\", function(require, exports, module) {\n\n/**\n * MediaFileData encapsulates format information of a media file.\n *\n * @param {DOMString} codecs\n * @param {long} bitrate\n * @param {long} height\n * @param {long} width\n * @param {float} duration\n */\nvar MediaFileData = function(codecs, bitrate, height, width, duration){\n    this.codecs = codecs || null;\n    this.bitrate = bitrate || 0;\n    this.height = height || 0;\n    this.width = width || 0;\n    this.duration = duration || 0;\n};\n\nmodule.exports = MediaFileData;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\MediaFileData.js")} catch(e) {console.log("exception: in lib\common\plugin\MediaFileData.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Metadata\", function(require, exports, module) {\n\n/**\n * Information about the state of the file or directory\n *\n * {Date} modificationTime (readonly)\n */\nvar Metadata = function(time) {\n    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);\n};\n\nmodule.exports = Metadata;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Metadata.js")} catch(e) {console.log("exception: in lib\common\plugin\Metadata.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Position\", function(require, exports, module) {\n\nvar Coordinates = require('cordova/plugin/Coordinates');\n\nvar Position = function(coords, timestamp) {\n    if (coords) {\n        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);\n    } else {\n        this.coords = new Coordinates();\n    }\n    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();\n};\n\nmodule.exports = Position;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\Position.js")} catch(e) {console.log("exception: in lib\common\plugin\Position.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/PositionError\", function(require, exports, module) {\n\n/**\n * Position error object\n *\n * @constructor\n * @param code\n * @param message\n */\nvar PositionError = function(code, message) {\n    this.code = code || null;\n    this.message = message || '';\n};\n\nPositionError.PERMISSION_DENIED = 1;\nPositionError.POSITION_UNAVAILABLE = 2;\nPositionError.TIMEOUT = 3;\n\nmodule.exports = PositionError;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\PositionError.js")} catch(e) {console.log("exception: in lib\common\plugin\PositionError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ProgressEvent\", function(require, exports, module) {\n\n// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill\n// Feature test: See if we can instantiate a native ProgressEvent;\n// if so, use that approach,\n// otherwise fill-in with our own implementation.\n//\n// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.\nvar ProgressEvent = (function() {\n    /*\n    var createEvent = function(data) {\n        var event = document.createEvent('Events');\n        event.initEvent('ProgressEvent', false, false);\n        if (data) {\n            for (var i in data) {\n                if (data.hasOwnProperty(i)) {\n                    event[i] = data[i];\n                }\n            }\n            if (data.target) {\n                // TODO: cannot call <some_custom_object>.dispatchEvent\n                // need to first figure out how to implement EventTarget\n            }\n        }\n        return event;\n    };\n    try {\n        var ev = createEvent({type:\"abort\",target:document});\n        return function ProgressEvent(type, data) {\n            data.type = type;\n            return createEvent(data);\n        };\n    } catch(e){\n    */\n        return function ProgressEvent(type, dict) {\n            this.type = type;\n            this.bubbles = false;\n            this.cancelBubble = false;\n            this.cancelable = false;\n            this.lengthComputable = false;\n            this.loaded = dict && dict.loaded ? dict.loaded : 0;\n            this.total = dict && dict.total ? dict.total : 0;\n            this.target = dict && dict.target ? dict.target : null;\n        };\n    //}\n})();\n\nmodule.exports = ProgressEvent;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\ProgressEvent.js")} catch(e) {console.log("exception: in lib\common\plugin\ProgressEvent.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/accelerometer\", function(require, exports, module) {\n\n/**\n * This class provides access to device accelerometer data.\n * @constructor\n */\nvar utils = require(\"cordova/utils\"),\n    exec = require(\"cordova/exec\"),\n    Acceleration = require('cordova/plugin/Acceleration');\n\n// Is the accel sensor running?\nvar running = false;\n\n// Keeps reference to watchAcceleration calls.\nvar timers = {};\n\n// Array of listeners; used to keep track of when we should call start and stop.\nvar listeners = [];\n\n// Last returned acceleration object from native\nvar accel = null;\n\n// Tells native to start.\nfunction start() {\n    exec(function(a) {\n        var tempListeners = listeners.slice(0);\n        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);\n        for (var i = 0, l = tempListeners.length; i < l; i++) {\n            tempListeners[i].win(accel);\n        }\n    }, function(e) {\n        var tempListeners = listeners.slice(0);\n        for (var i = 0, l = tempListeners.length; i < l; i++) {\n            tempListeners[i].fail(e);\n        }\n    }, \"Accelerometer\", \"start\", []);\n    running = true;\n}\n\n// Tells native to stop.\nfunction stop() {\n    exec(null, null, \"Accelerometer\", \"stop\", []);\n    running = false;\n}\n\n// Adds a callback pair to the listeners array\nfunction createCallbackPair(win, fail) {\n    return {win:win, fail:fail};\n}\n\n// Removes a win/fail listener pair from the listeners array\nfunction removeListeners(l) {\n    var idx = listeners.indexOf(l);\n    if (idx > -1) {\n        listeners.splice(idx, 1);\n        if (listeners.length === 0) {\n            stop();\n        }\n    }\n}\n\nvar accelerometer = {\n    /**\n     * Asynchronously acquires the current acceleration.\n     *\n     * @param {Function} successCallback    The function to call when the acceleration data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)\n     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)\n     */\n    getCurrentAcceleration: function(successCallback, errorCallback, options) {\n        // successCallback required\n        if (typeof successCallback !== \"function\") {\n            throw \"getCurrentAcceleration must be called with at least a success callback function as first parameter.\";\n        }\n\n        var p;\n        var win = function(a) {\n            removeListeners(p);\n            successCallback(a);\n        };\n        var fail = function(e) {\n            removeListeners(p);\n            errorCallback(e);\n        };\n\n        p = createCallbackPair(win, fail);\n        listeners.push(p);\n\n        if (!running) {\n            start();\n        }\n    },\n\n    /**\n     * Asynchronously acquires the acceleration repeatedly at a given interval.\n     *\n     * @param {Function} successCallback    The function to call each time the acceleration data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)\n     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)\n     * @return String                       The watch id that must be passed to #clearWatch to stop watching.\n     */\n    watchAcceleration: function(successCallback, errorCallback, options) {\n        // Default interval (10 sec)\n        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;\n\n        // successCallback required\n        if (typeof successCallback !== \"function\") {\n            throw \"watchAcceleration must be called with at least a success callback function as first parameter.\";\n        }\n\n        // Keep reference to watch id, and report accel readings as often as defined in frequency\n        var id = utils.createUUID();\n\n        var p = createCallbackPair(function(){}, function(e) {\n            removeListeners(p);\n            errorCallback(e);\n        });\n        listeners.push(p);\n\n        timers[id] = {\n            timer:window.setInterval(function() {\n                if (accel) {\n                    successCallback(accel);\n                }\n            }, frequency),\n            listeners:p\n        };\n\n        if (running) {\n            // If we're already running then immediately invoke the success callback\n            // but only if we have retrieved a value, sample code does not check for null ...\n            if(accel) {\n                successCallback(accel);\n            }\n        } else {\n            start();\n        }\n\n        return id;\n    },\n\n    /**\n     * Clears the specified accelerometer watch.\n     *\n     * @param {String} id       The id of the watch returned from #watchAcceleration.\n     */\n    clearWatch: function(id) {\n        // Stop javascript timer & remove from timer list\n        if (id && timers[id]) {\n            window.clearInterval(timers[id].timer);\n            removeListeners(timers[id].listeners);\n            delete timers[id];\n        }\n    }\n};\n\nmodule.exports = accelerometer;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\accelerometer.js")} catch(e) {console.log("exception: in lib\common\plugin\accelerometer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/battery\", function(require, exports, module) {\n\n/**\n * This class contains information about the current battery status.\n * @constructor\n */\nvar cordova = require('cordova'),\n    exec = require('cordova/exec');\n\nfunction handlers() {\n  return battery.channels.batterystatus.numHandlers +\n         battery.channels.batterylow.numHandlers +\n         battery.channels.batterycritical.numHandlers;\n}\n\nvar Battery = function() {\n    this._level = null;\n    this._isPlugged = null;\n    // Create new event handlers on the window (returns a channel instance)\n    this.channels = {\n      batterystatus:cordova.addWindowEventHandler(\"batterystatus\"),\n      batterylow:cordova.addWindowEventHandler(\"batterylow\"),\n      batterycritical:cordova.addWindowEventHandler(\"batterycritical\")\n    };\n    for (var key in this.channels) {\n        this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange;\n    }\n};\n/**\n * Event handlers for when callbacks get registered for the battery.\n * Keep track of how many handlers we have so we can start and stop the native battery listener\n * appropriately (and hopefully save on battery life!).\n */\nBattery.onHasSubscribersChange = function() {\n  // If we just registered the first handler, make sure native listener is started.\n  if (this.numHandlers === 1 && handlers() === 1) {\n      exec(battery._status, battery._error, \"Battery\", \"start\", []);\n  } else if (handlers() === 0) {\n      exec(null, null, \"Battery\", \"stop\", []);\n  }\n};\n\n/**\n * Callback for battery status\n *\n * @param {Object} info            keys: level, isPlugged\n */\nBattery.prototype._status = function(info) {\n    if (info) {\n        var me = battery;\n    var level = info.level;\n        if (me._level !== level || me._isPlugged !== info.isPlugged) {\n            // Fire batterystatus event\n            cordova.fireWindowEvent(\"batterystatus\", info);\n\n            // Fire low battery event\n            if (level === 20 || level === 5) {\n                if (level === 20) {\n                    cordova.fireWindowEvent(\"batterylow\", info);\n                }\n                else {\n                    cordova.fireWindowEvent(\"batterycritical\", info);\n                }\n            }\n        }\n        me._level = level;\n        me._isPlugged = info.isPlugged;\n    }\n};\n\n/**\n * Error callback for battery start\n */\nBattery.prototype._error = function(e) {\n    console.log(\"Error initializing Battery: \" + e);\n};\n\nvar battery = new Battery();\n\nmodule.exports = battery;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\battery.js")} catch(e) {console.log("exception: in lib\common\plugin\battery.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/capture\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    MediaFile = require('cordova/plugin/MediaFile');\n\n/**\n * Launches a capture of different types.\n *\n * @param (DOMString} type\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureVideoOptions} options\n */\nfunction _capture(type, successCallback, errorCallback, options) {\n    var win = function(pluginResult) {\n        var mediaFiles = [];\n        var i;\n        for (i = 0; i < pluginResult.length; i++) {\n            var mediaFile = new MediaFile();\n            mediaFile.name = pluginResult[i].name;\n            mediaFile.fullPath = pluginResult[i].fullPath;\n            mediaFile.type = pluginResult[i].type;\n            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;\n            mediaFile.size = pluginResult[i].size;\n            mediaFiles.push(mediaFile);\n        }\n        successCallback(mediaFiles);\n    };\n    exec(win, errorCallback, \"Capture\", type, [options]);\n}\n/**\n * The Capture interface exposes an interface to the camera and microphone of the hosting device.\n */\nfunction Capture() {\n    this.supportedAudioModes = [];\n    this.supportedImageModes = [];\n    this.supportedVideoModes = [];\n}\n\n/**\n * Launch audio recorder application for recording audio clip(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureAudioOptions} options\n */\nCapture.prototype.captureAudio = function(successCallback, errorCallback, options){\n    _capture(\"captureAudio\", successCallback, errorCallback, options);\n};\n\n/**\n * Launch camera application for taking image(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureImageOptions} options\n */\nCapture.prototype.captureImage = function(successCallback, errorCallback, options){\n    _capture(\"captureImage\", successCallback, errorCallback, options);\n};\n\n/**\n * Launch device camera application for recording video(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureVideoOptions} options\n */\nCapture.prototype.captureVideo = function(successCallback, errorCallback, options){\n    _capture(\"captureVideo\", successCallback, errorCallback, options);\n};\n\n\nmodule.exports = new Capture();\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\capture.js")} catch(e) {console.log("exception: in lib\common\plugin\capture.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/compass\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    utils = require('cordova/utils'),\n    CompassHeading = require('cordova/plugin/CompassHeading'),\n    CompassError = require('cordova/plugin/CompassError'),\n    timers = {},\n    compass = {\n        /**\n         * Asynchronously acquires the current heading.\n         * @param {Function} successCallback The function to call when the heading\n         * data is available\n         * @param {Function} errorCallback The function to call when there is an error\n         * getting the heading data.\n         * @param {CompassOptions} options The options for getting the heading data (not used).\n         */\n        getCurrentHeading:function(successCallback, errorCallback, options) {\n            // successCallback required\n            if (typeof successCallback !== \"function\") {\n              console.log(\"Compass Error: successCallback is not a function\");\n              return;\n            }\n\n            // errorCallback optional\n            if (errorCallback && (typeof errorCallback !== \"function\")) {\n              console.log(\"Compass Error: errorCallback is not a function\");\n              return;\n            }\n\n            var win = function(result) {\n                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);\n                successCallback(ch);\n            };\n            var fail = function(code) {\n                var ce = new CompassError(code);\n                errorCallback(ce);\n            };\n\n            // Get heading\n            exec(win, fail, \"Compass\", \"getHeading\", [options]);\n        },\n\n        /**\n         * Asynchronously acquires the heading repeatedly at a given interval.\n         * @param {Function} successCallback The function to call each time the heading\n         * data is available\n         * @param {Function} errorCallback The function to call when there is an error\n         * getting the heading data.\n         * @param {HeadingOptions} options The options for getting the heading data\n         * such as timeout and the frequency of the watch. For iOS, filter parameter\n         * specifies to watch via a distance filter rather than time.\n         */\n        watchHeading:function(successCallback, errorCallback, options) {\n            // Default interval (100 msec)\n            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;\n            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;\n\n            // successCallback required\n            if (typeof successCallback !== \"function\") {\n              console.log(\"Compass Error: successCallback is not a function\");\n              return;\n            }\n\n            // errorCallback optional\n            if (errorCallback && (typeof errorCallback !== \"function\")) {\n              console.log(\"Compass Error: errorCallback is not a function\");\n              return;\n            }\n\n            var id = utils.createUUID();\n            if (filter > 0) {\n                // is an iOS request for watch by filter, no timer needed\n                timers[id] = \"iOS\";\n                compass.getCurrentHeading(successCallback, errorCallback, options);\n            } else {\n                // Start watch timer to get headings\n                timers[id] = window.setInterval(function() {\n                    compass.getCurrentHeading(successCallback, errorCallback);\n                }, frequency);\n            }\n\n            return id;\n        },\n\n        /**\n         * Clears the specified heading watch.\n         * @param {String} watchId The ID of the watch returned from #watchHeading.\n         */\n        clearWatch:function(id) {\n            // Stop javascript timer & remove from timer list\n            if (id && timers[id]) {\n                if (timers[id] != \"iOS\") {\n                      clearInterval(timers[id]);\n                  } else {\n                    // is iOS watch by filter so call into device to stop\n                    exec(null, null, \"Compass\", \"stopHeading\", []);\n                }\n                delete timers[id];\n            }\n        }\n    };\n\nmodule.exports = compass;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\compass.js")} catch(e) {console.log("exception: in lib\common\plugin\compass.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/console-via-logger\", function(require, exports, module) {\n\n//------------------------------------------------------------------------------\n\nvar logger = require(\"cordova/plugin/logger\");\nvar utils  = require(\"cordova/utils\");\n\n//------------------------------------------------------------------------------\n// object that we're exporting\n//------------------------------------------------------------------------------\nvar console = module.exports;\n\n//------------------------------------------------------------------------------\n// copy of the original console object\n//------------------------------------------------------------------------------\nvar WinConsole = window.console;\n\n//------------------------------------------------------------------------------\n// whether to use the logger\n//------------------------------------------------------------------------------\nvar UseLogger = false;\n\n//------------------------------------------------------------------------------\n// Timers\n//------------------------------------------------------------------------------\nvar Timers = {};\n\n//------------------------------------------------------------------------------\n// used for unimplemented methods\n//------------------------------------------------------------------------------\nfunction noop() {}\n\n//------------------------------------------------------------------------------\n// used for unimplemented methods\n//------------------------------------------------------------------------------\nconsole.useLogger = function (value) {\n    if (arguments.length) UseLogger = !!value;\n\n    if (UseLogger) {\n        if (logger.useConsole()) {\n            throw new Error(\"console and logger are too intertwingly\");\n        }\n    }\n\n    return UseLogger;\n};\n\n//------------------------------------------------------------------------------\nconsole.log = function() {\n    if (logger.useConsole()) return;\n    logger.log.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.error = function() {\n    if (logger.useConsole()) return;\n    logger.error.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.warn = function() {\n    if (logger.useConsole()) return;\n    logger.warn.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.info = function() {\n    if (logger.useConsole()) return;\n    logger.info.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.debug = function() {\n    if (logger.useConsole()) return;\n    logger.debug.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.assert = function(expression) {\n    if (expression) return;\n\n    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));\n    console.log(\"ASSERT: \" + message);\n};\n\n//------------------------------------------------------------------------------\nconsole.clear = function() {};\n\n//------------------------------------------------------------------------------\nconsole.dir = function(object) {\n    console.log(\"%o\", object);\n};\n\n//------------------------------------------------------------------------------\nconsole.dirxml = function(node) {\n    console.log(node.innerHTML);\n};\n\n//------------------------------------------------------------------------------\nconsole.trace = noop;\n\n//------------------------------------------------------------------------------\nconsole.group = console.log;\n\n//------------------------------------------------------------------------------\nconsole.groupCollapsed = console.log;\n\n//------------------------------------------------------------------------------\nconsole.groupEnd = noop;\n\n//------------------------------------------------------------------------------\nconsole.time = function(name) {\n    Timers[name] = new Date().valueOf();\n};\n\n//------------------------------------------------------------------------------\nconsole.timeEnd = function(name) {\n    var timeStart = Timers[name];\n    if (!timeStart) {\n        console.warn(\"unknown timer: \" + name);\n        return;\n    }\n\n    var timeElapsed = new Date().valueOf() - timeStart;\n    console.log(name + \": \" + timeElapsed + \"ms\");\n};\n\n//------------------------------------------------------------------------------\nconsole.timeStamp = noop;\n\n//------------------------------------------------------------------------------\nconsole.profile = noop;\n\n//------------------------------------------------------------------------------\nconsole.profileEnd = noop;\n\n//------------------------------------------------------------------------------\nconsole.count = noop;\n\n//------------------------------------------------------------------------------\nconsole.exception = console.log;\n\n//------------------------------------------------------------------------------\nconsole.table = function(data, columns) {\n    console.log(\"%o\", data);\n};\n\n//------------------------------------------------------------------------------\n// return a new function that calls both functions passed as args\n//------------------------------------------------------------------------------\nfunction wrappedOrigCall(orgFunc, newFunc) {\n    return function() {\n        var args = [].slice.call(arguments);\n        try { orgFunc.apply(WinConsole, args); } catch (e) {}\n        try { newFunc.apply(console,    args); } catch (e) {}\n    };\n}\n\n//------------------------------------------------------------------------------\n// For every function that exists in the original console object, that\n// also exists in the new console object, wrap the new console method\n// with one that calls both\n//------------------------------------------------------------------------------\nfor (var key in console) {\n    if (typeof WinConsole[key] == \"function\") {\n        console[key] = wrappedOrigCall(WinConsole[key], console[key]);\n    }\n}\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\console-via-logger.js")} catch(e) {console.log("exception: in lib\common\plugin\console-via-logger.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/contacts\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils'),\n    Contact = require('cordova/plugin/Contact');\n\n/**\n* Represents a group of Contacts.\n* @constructor\n*/\nvar contacts = {\n    /**\n     * Returns an array of Contacts matching the search criteria.\n     * @param fields that should be searched\n     * @param successCB success callback\n     * @param errorCB error callback\n     * @param {ContactFindOptions} options that can be applied to contact searching\n     * @return array of Contacts matching search criteria\n     */\n    find:function(fields, successCB, errorCB, options) {\n        if (!successCB) {\n            throw new TypeError(\"You must specify a success callback for the find command.\");\n        }\n        if (!fields || (utils.isArray(fields) && fields.length === 0)) {\n            if (typeof errorCB === \"function\") {\n                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));\n            }\n        } else {\n            var win = function(result) {\n                var cs = [];\n                for (var i = 0, l = result.length; i < l; i++) {\n                    cs.push(contacts.create(result[i]));\n                }\n                successCB(cs);\n            };\n            exec(win, errorCB, \"Contacts\", \"search\", [fields, options]);\n        }\n    },\n\n    /**\n     * This function creates a new contact, but it does not persist the contact\n     * to device storage. To persist the contact to device storage, invoke\n     * contact.save().\n     * @param properties an object whose properties will be examined to create a new Contact\n     * @returns new Contact object\n     */\n    create:function(properties) {\n        var i;\n        var contact = new Contact();\n        for (i in properties) {\n            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {\n                contact[i] = properties[i];\n            }\n        }\n        return contact;\n    }\n};\n\nmodule.exports = contacts;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\contacts.js")} catch(e) {console.log("exception: in lib\common\plugin\contacts.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/device\", function(require, exports, module) {\n\nvar channel = require('cordova/channel'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\n// Tell cordova channel to wait on the CordovaInfoReady event\nchannel.waitForInitialization('onCordovaInfoReady');\n\n/**\n * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the\n * phone, etc.\n * @constructor\n */\nfunction Device() {\n    this.available = false;\n    this.platform = null;\n    this.version = null;\n    this.name = null;\n    this.uuid = null;\n    this.cordova = null;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribe(function() {\n        me.getInfo(function(info) {\n            me.available = true;\n            me.platform = info.platform;\n            me.version = info.version;\n            me.name = info.name;\n            me.uuid = info.uuid;\n            me.cordova = info.cordova;\n            channel.onCordovaInfoReady.fire();\n        },function(e) {\n            me.available = false;\n            utils.alert(\"[ERROR] Error initializing Cordova: \" + e);\n        });\n    });\n}\n\n/**\n * Get device info\n *\n * @param {Function} successCallback The function to call when the heading data is available\n * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)\n */\nDevice.prototype.getInfo = function(successCallback, errorCallback) {\n\n    // successCallback required\n    if (typeof successCallback !== \"function\") {\n        console.log(\"Device Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback !== \"function\")) {\n        console.log(\"Device Error: errorCallback is not a function\");\n        return;\n    }\n\n    // Get info\n    exec(successCallback, errorCallback, \"Device\", \"getDeviceInfo\", []);\n};\n\nmodule.exports = new Device();\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\device.js")} catch(e) {console.log("exception: in lib\common\plugin\device.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/echo\", function(require, exports, module) {\n\nvar exec = require('cordova/exec');\n\n/**\n * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.\n * @param successCallback  invoked with a FileSystem object\n * @param errorCallback  invoked if error occurs retrieving file system\n * @param message  The string to be echoed.\n * @param forceAsync  Whether to force an async return value (for testing native->js bridge).\n */\nmodule.exports = function(successCallback, errorCallback, message, forceAsync) {\n    var action = forceAsync ? 'echoAsync' : 'echo';\n    exec(successCallback, errorCallback, \"Echo\", action, [message]);\n};\n\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\echo.js")} catch(e) {console.log("exception: in lib\common\plugin\echo.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/geolocation\", function(require, exports, module) {\n\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    PositionError = require('cordova/plugin/PositionError'),\n    Position = require('cordova/plugin/Position');\n\nvar timers = {};   // list of timers in use\n\n// Returns default params, overrides if provided with values\nfunction parseParameters(options) {\n    var opt = {\n        maximumAge: 0,\n        enableHighAccuracy: false,\n        timeout: Infinity\n    };\n\n    if (options) {\n        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {\n            opt.maximumAge = options.maximumAge;\n        }\n        if (options.enableHighAccuracy !== undefined) {\n            opt.enableHighAccuracy = options.enableHighAccuracy;\n        }\n        if (options.timeout !== undefined && !isNaN(options.timeout)) {\n            if (options.timeout < 0) {\n                opt.timeout = 0;\n            } else {\n                opt.timeout = options.timeout;\n            }\n        }\n    }\n\n    return opt;\n}\n\n// Returns a timeout failure, closed over a specified timeout value and error callback.\nfunction createTimeout(errorCallback, timeout) {\n    var t = setTimeout(function() {\n        clearTimeout(t);\n        t = null;\n        errorCallback({\n            code:PositionError.TIMEOUT,\n            message:\"Position retrieval timed out.\"\n        });\n    }, timeout);\n    return t;\n}\n\nvar geolocation = {\n    lastPosition:null, // reference to last known (cached) position returned\n    /**\n   * Asynchronously acquires the current position.\n   *\n   * @param {Function} successCallback    The function to call when the position data is available\n   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)\n   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)\n   */\n    getCurrentPosition:function(successCallback, errorCallback, options) {\n        if (arguments.length === 0) {\n            throw new Error(\"getCurrentPosition must be called with at least one argument.\");\n        }\n        options = parseParameters(options);\n\n        // Timer var that will fire an error callback if no position is retrieved from native\n        // before the \"timeout\" param provided expires\n        var timeoutTimer = {timer:null};\n\n        var win = function(p) {\n            clearTimeout(timeoutTimer.timer);\n            if (!(timeoutTimer.timer)) {\n                // Timeout already happened, or native fired error callback for\n                // this geo request.\n                // Don't continue with success callback.\n                return;\n            }\n            var pos = new Position(\n                {\n                    latitude:p.latitude,\n                    longitude:p.longitude,\n                    altitude:p.altitude,\n                    accuracy:p.accuracy,\n                    heading:p.heading,\n                    velocity:p.velocity,\n                    altitudeAccuracy:p.altitudeAccuracy\n                },\n                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))\n            );\n            geolocation.lastPosition = pos;\n            successCallback(pos);\n        };\n        var fail = function(e) {\n            clearTimeout(timeoutTimer.timer);\n            timeoutTimer.timer = null;\n            var err = new PositionError(e.code, e.message);\n            if (errorCallback) {\n                errorCallback(err);\n            }\n        };\n\n        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just\n        // fire the success callback with the cached position.\n        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {\n            successCallback(geolocation.lastPosition);\n        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.\n        } else if (options.timeout === 0) {\n            fail({\n                code:PositionError.TIMEOUT,\n                message:\"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter.\"\n            });\n        // Otherwise we have to call into native to retrieve a position.\n        } else {\n            if (options.timeout !== Infinity) {\n                // If the timeout value was not set to Infinity (default), then\n                // set up a timeout function that will fire the error callback\n                // if no successful position was retrieved before timeout expired.\n                timeoutTimer.timer = createTimeout(fail, options.timeout);\n            } else {\n                // This is here so the check in the win function doesn't mess stuff up\n                // may seem weird but this guarantees timeoutTimer is\n                // always truthy before we call into native\n                timeoutTimer.timer = true;\n            }\n            exec(win, fail, \"Geolocation\", \"getLocation\", [options.enableHighAccuracy, options.maximumAge]);\n        }\n        return timeoutTimer;\n    },\n    /**\n     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,\n     * the successCallback is called with the new location.\n     *\n     * @param {Function} successCallback    The function to call each time the location data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)\n     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)\n     * @return String                       The watch id that must be passed to #clearWatch to stop watching.\n     */\n    watchPosition:function(successCallback, errorCallback, options) {\n        if (arguments.length === 0) {\n            throw new Error(\"watchPosition must be called with at least one argument.\");\n        }\n        options = parseParameters(options);\n\n        var id = utils.createUUID();\n\n        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition\n        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);\n\n        var fail = function(e) {\n            clearTimeout(timers[id].timer);\n            var err = new PositionError(e.code, e.message);\n            if (errorCallback) {\n                errorCallback(err);\n            }\n        };\n\n        var win = function(p) {\n            clearTimeout(timers[id].timer);\n            if (options.timeout !== Infinity) {\n                timers[id].timer = createTimeout(fail, options.timeout);\n            }\n            var pos = new Position(\n                {\n                    latitude:p.latitude,\n                    longitude:p.longitude,\n                    altitude:p.altitude,\n                    accuracy:p.accuracy,\n                    heading:p.heading,\n                    velocity:p.velocity,\n                    altitudeAccuracy:p.altitudeAccuracy\n                },\n                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))\n            );\n            geolocation.lastPosition = pos;\n            successCallback(pos);\n        };\n\n        exec(win, fail, \"Geolocation\", \"addWatch\", [id, options.enableHighAccuracy]);\n\n        return id;\n    },\n    /**\n     * Clears the specified heading watch.\n     *\n     * @param {String} id       The ID of the watch returned from #watchPosition\n     */\n    clearWatch:function(id) {\n        if (id && timers[id] !== undefined) {\n            clearTimeout(timers[id].timer);\n            timers[id].timer = false;\n            exec(null, null, \"Geolocation\", \"clearWatch\", [id]);\n        }\n    }\n};\n\nmodule.exports = geolocation;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\geolocation.js")} catch(e) {console.log("exception: in lib\common\plugin\geolocation.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/globalization\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    GlobalizationError = require('cordova/plugin/GlobalizationError');\n\nvar globalization = {\n\n/**\n* Returns the string identifier for the client's current language.\n* It returns the language identifier string to the successCB callback with a\n* properties object as a parameter. If there is an error getting the language,\n* then the errorCB callback is invoked.\n*\n* @param {Function} successCB\n* @param {Function} errorCB\n*\n* @return Object.value {String}: The language identifier\n*\n* @error GlobalizationError.UNKNOWN_ERROR\n*\n* Example\n*    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\\n');},\n*                                function () {});\n*/\ngetPreferredLanguage:function(successCB, failureCB) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getPreferredLanguage Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getPreferredLanguage Error: failureCB is not a function\");\n        return;\n    }\n\n    exec(successCB, failureCB, \"Globalization\",\"getPreferredLanguage\", []);\n},\n\n/**\n* Returns the string identifier for the client's current locale setting.\n* It returns the locale identifier string to the successCB callback with a\n* properties object as a parameter. If there is an error getting the locale,\n* then the errorCB callback is invoked.\n*\n* @param {Function} successCB\n* @param {Function} errorCB\n*\n* @return Object.value {String}: The locale identifier\n*\n* @error GlobalizationError.UNKNOWN_ERROR\n*\n* Example\n*    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\\n');},\n*                                function () {});\n*/\ngetLocaleName:function(successCB, failureCB) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getLocaleName Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getLocaleName Error: failureCB is not a function\");\n        return;\n    }\n    exec(successCB, failureCB, \"Globalization\",\"getLocaleName\", []);\n},\n\n\n/**\n* Returns a date formatted as a string according to the client's user preferences and\n* calendar using the time zone of the client. It returns the formatted date string to the\n* successCB callback with a properties object as a parameter. If there is an error\n* formatting the date, then the errorCB callback is invoked.\n*\n* The defaults are: formatLenght=\"short\" and selector=\"date and time\"\n*\n* @param {Date} date\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            formatLength {String}: 'short', 'medium', 'long', or 'full'\n*            selector {String}: 'date', 'time', or 'date and time'\n*\n* @return Object.value {String}: The localized date string\n*\n* @error GlobalizationError.FORMATTING_ERROR\n*\n* Example\n*    globalization.dateToString(new Date(),\n*                function (date) {alert('date:' + date.value + '\\n');},\n*                function (errorCode) {alert(errorCode);},\n*                {formatLength:'short'});\n*/\ndateToString:function(date, successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.dateToString Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.dateToString Error: failureCB is not a function\");\n        return;\n    }\n\n\n    if (date instanceof Date){\n        var dateValue;\n        dateValue = date.valueOf();\n        exec(successCB, failureCB, \"Globalization\", \"dateToString\", [{\"date\": dateValue, \"options\": options}]);\n    }\n    else {\n        console.log(\"Globalization.dateToString Error: date is not a Date object\");\n    }\n},\n\n\n/**\n* Parses a date formatted as a string according to the client's user\n* preferences and calendar using the time zone of the client and returns\n* the corresponding date object. It returns the date to the successCB\n* callback with a properties object as a parameter. If there is an error\n* parsing the date string, then the errorCB callback is invoked.\n*\n* The defaults are: formatLength=\"short\" and selector=\"date and time\"\n*\n* @param {String} dateString\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            formatLength {String}: 'short', 'medium', 'long', or 'full'\n*            selector {String}: 'date', 'time', or 'date and time'\n*\n* @return    Object.year {Number}: The four digit year\n*            Object.month {Number}: The month from (0 - 11)\n*            Object.day {Number}: The day from (1 - 31)\n*            Object.hour {Number}: The hour from (0 - 23)\n*            Object.minute {Number}: The minute from (0 - 59)\n*            Object.second {Number}: The second from (0 - 59)\n*            Object.millisecond {Number}: The milliseconds (from 0 - 999),\n*                                        not available on all platforms\n*\n* @error GlobalizationError.PARSING_ERROR\n*\n* Example\n*    globalization.stringToDate('4/11/2011',\n*                function (date) { alert('Month:' + date.month + '\\n' +\n*                    'Day:' + date.day + '\\n' +\n*                    'Year:' + date.year + '\\n');},\n*                function (errorCode) {alert(errorCode);},\n*                {selector:'date'});\n*/\nstringToDate:function(dateString, successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.stringToDate Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.stringToDate Error: failureCB is not a function\");\n        return;\n    }\n    if (typeof dateString == \"string\"){\n        exec(successCB, failureCB, \"Globalization\", \"stringToDate\", [{\"dateString\": dateString, \"options\": options}]);\n    }\n    else {\n        console.log(\"Globalization.stringToDate Error: dateString is not a string\");\n    }\n},\n\n\n/**\n* Returns a pattern string for formatting and parsing dates according to the client's\n* user preferences. It returns the pattern to the successCB callback with a\n* properties object as a parameter. If there is an error obtaining the pattern,\n* then the errorCB callback is invoked.\n*\n* The defaults are: formatLength=\"short\" and selector=\"date and time\"\n*\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            formatLength {String}: 'short', 'medium', 'long', or 'full'\n*            selector {String}: 'date', 'time', or 'date and time'\n*\n* @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.\n*                                    The patterns follow Unicode Technical Standard #35\n*                                    http://unicode.org/reports/tr35/tr35-4.html\n*            Object.timezone {String}: The abbreviated name of the time zone on the client\n*            Object.utc_offset {Number}: The current difference in seconds between the client's\n*                                        time zone and coordinated universal time.\n*            Object.dst_offset {Number}: The current daylight saving time offset in seconds\n*                                        between the client's non-daylight saving's time zone\n*                                        and the client's daylight saving's time zone.\n*\n* @error GlobalizationError.PATTERN_ERROR\n*\n* Example\n*    globalization.getDatePattern(\n*                function (date) {alert('pattern:' + date.pattern + '\\n');},\n*                function () {},\n*                {formatLength:'short'});\n*/\ngetDatePattern:function(successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getDatePattern Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getDatePattern Error: failureCB is not a function\");\n        return;\n    }\n\n    exec(successCB, failureCB, \"Globalization\", \"getDatePattern\", [{\"options\": options}]);\n},\n\n\n/**\n* Returns an array of either the names of the months or days of the week\n* according to the client's user preferences and calendar. It returns the array of names to the\n* successCB callback with a properties object as a parameter. If there is an error obtaining the\n* names, then the errorCB callback is invoked.\n*\n* The defaults are: type=\"wide\" and item=\"months\"\n*\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            type {String}: 'narrow' or 'wide'\n*            item {String}: 'months', or 'days'\n*\n* @return Object.value {Array{String}}: The array of names starting from either\n*                                        the first month in the year or the\n*                                        first day of the week.\n* @error GlobalizationError.UNKNOWN_ERROR\n*\n* Example\n*    globalization.getDateNames(function (names) {\n*        for(var i = 0; i < names.value.length; i++) {\n*            alert('Month:' + names.value[i] + '\\n');}},\n*        function () {});\n*/\ngetDateNames:function(successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getDateNames Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getDateNames Error: failureCB is not a function\");\n        return;\n    }\n    exec(successCB, failureCB, \"Globalization\", \"getDateNames\", [{\"options\": options}]);\n},\n\n/**\n* Returns whether daylight savings time is in effect for a given date using the client's\n* time zone and calendar. It returns whether or not daylight savings time is in effect\n* to the successCB callback with a properties object as a parameter. If there is an error\n* reading the date, then the errorCB callback is invoked.\n*\n* @param {Date} date\n* @param {Function} successCB\n* @param {Function} errorCB\n*\n* @return Object.dst {Boolean}: The value \"true\" indicates that daylight savings time is\n*                                in effect for the given date and \"false\" indicate that it is not.\n*\n* @error GlobalizationError.UNKNOWN_ERROR\n*\n* Example\n*    globalization.isDayLightSavingsTime(new Date(),\n*                function (date) {alert('dst:' + date.dst + '\\n');}\n*                function () {});\n*/\nisDayLightSavingsTime:function(date, successCB, failureCB) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.isDayLightSavingsTime Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.isDayLightSavingsTime Error: failureCB is not a function\");\n        return;\n    }\n\n\n    if (date instanceof Date){\n        var dateValue;\n        dateValue = date.valueOf();\n        exec(successCB, failureCB, \"Globalization\", \"isDayLightSavingsTime\", [{\"date\": dateValue}]);\n    }\n    else {\n        console.log(\"Globalization.isDayLightSavingsTime Error: date is not a Date object\");\n    }\n\n},\n\n/**\n* Returns the first day of the week according to the client's user preferences and calendar.\n* The days of the week are numbered starting from 1 where 1 is considered to be Sunday.\n* It returns the day to the successCB callback with a properties object as a parameter.\n* If there is an error obtaining the pattern, then the errorCB callback is invoked.\n*\n* @param {Function} successCB\n* @param {Function} errorCB\n*\n* @return Object.value {Number}: The number of the first day of the week.\n*\n* @error GlobalizationError.UNKNOWN_ERROR\n*\n* Example\n*    globalization.getFirstDayOfWeek(function (day)\n*                { alert('Day:' + day.value + '\\n');},\n*                function () {});\n*/\ngetFirstDayOfWeek:function(successCB, failureCB) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getFirstDayOfWeek Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getFirstDayOfWeek Error: failureCB is not a function\");\n        return;\n    }\n\n    exec(successCB, failureCB, \"Globalization\", \"getFirstDayOfWeek\", []);\n},\n\n\n/**\n* Returns a number formatted as a string according to the client's user preferences.\n* It returns the formatted number string to the successCB callback with a properties object as a\n* parameter. If there is an error formatting the number, then the errorCB callback is invoked.\n*\n* The defaults are: type=\"decimal\"\n*\n* @param {Number} number\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            type {String}: 'decimal', \"percent\", or 'currency'\n*\n* @return Object.value {String}: The formatted number string.\n*\n* @error GlobalizationError.FORMATTING_ERROR\n*\n* Example\n*    globalization.numberToString(3.25,\n*                function (number) {alert('number:' + number.value + '\\n');},\n*                function () {},\n*                {type:'decimal'});\n*/\nnumberToString:function(number, successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.numberToString Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.numberToString Error: failureCB is not a function\");\n        return;\n    }\n\n    if(typeof number == \"number\") {\n        exec(successCB, failureCB, \"Globalization\", \"numberToString\", [{\"number\": number, \"options\": options}]);\n    }\n    else {\n        console.log(\"Globalization.numberToString Error: number is not a number\");\n    }\n},\n\n/**\n* Parses a number formatted as a string according to the client's user preferences and\n* returns the corresponding number. It returns the number to the successCB callback with a\n* properties object as a parameter. If there is an error parsing the number string, then\n* the errorCB callback is invoked.\n*\n* The defaults are: type=\"decimal\"\n*\n* @param {String} numberString\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            type {String}: 'decimal', \"percent\", or 'currency'\n*\n* @return Object.value {Number}: The parsed number.\n*\n* @error GlobalizationError.PARSING_ERROR\n*\n* Example\n*    globalization.stringToNumber('1234.56',\n*                function (number) {alert('Number:' + number.value + '\\n');},\n*                function () { alert('Error parsing number');});\n*/\nstringToNumber:function(numberString, successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.stringToNumber Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.stringToNumber Error: failureCB is not a function\");\n        return;\n    }\n\n    if(typeof numberString == \"string\") {\n        exec(successCB, failureCB, \"Globalization\", \"stringToNumber\", [{\"numberString\": numberString, \"options\": options}]);\n    }\n    else {\n        console.log(\"Globalization.stringToNumber Error: numberString is not a string\");\n    }\n},\n\n/**\n* Returns a pattern string for formatting and parsing numbers according to the client's user\n* preferences. It returns the pattern to the successCB callback with a properties object as a\n* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.\n*\n* The defaults are: type=\"decimal\"\n*\n* @param {Function} successCB\n* @param {Function} errorCB\n* @param {Object} options {optional}\n*            type {String}: 'decimal', \"percent\", or 'currency'\n*\n* @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.\n*                                    The patterns follow Unicode Technical Standard #35.\n*                                    http://unicode.org/reports/tr35/tr35-4.html\n*            Object.symbol {String}: The symbol to be used when formatting and parsing\n*                                    e.g., percent or currency symbol.\n*            Object.fraction {Number}: The number of fractional digits to use when parsing and\n*                                    formatting numbers.\n*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.\n*            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.\n*            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.\n*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.\n*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.\n*\n* @error GlobalizationError.PATTERN_ERROR\n*\n* Example\n*    globalization.getNumberPattern(\n*                function (pattern) {alert('Pattern:' + pattern.pattern + '\\n');},\n*                function () {});\n*/\ngetNumberPattern:function(successCB, failureCB, options) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getNumberPattern Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getNumberPattern Error: failureCB is not a function\");\n        return;\n    }\n\n    exec(successCB, failureCB, \"Globalization\", \"getNumberPattern\", [{\"options\": options}]);\n},\n\n/**\n* Returns a pattern string for formatting and parsing currency values according to the client's\n* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a\n* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB\n* callback is invoked.\n*\n* @param {String} currencyCode\n* @param {Function} successCB\n* @param {Function} errorCB\n*\n* @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.\n*                                    The patterns follow Unicode Technical Standard #35\n*                                    http://unicode.org/reports/tr35/tr35-4.html\n*            Object.code {String}: The ISO 4217 currency code for the pattern.\n*            Object.fraction {Number}: The number of fractional digits to use when parsing and\n*                                    formatting currency.\n*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.\n*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.\n*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.\n*\n* @error GlobalizationError.FORMATTING_ERROR\n*\n* Example\n*    globalization.getCurrencyPattern('EUR',\n*                function (currency) {alert('Pattern:' + currency.pattern + '\\n');}\n*                function () {});\n*/\ngetCurrencyPattern:function(currencyCode, successCB, failureCB) {\n    // successCallback required\n    if (typeof successCB != \"function\") {\n        console.log(\"Globalization.getCurrencyPattern Error: successCB is not a function\");\n        return;\n    }\n\n    // errorCallback required\n    if (typeof failureCB != \"function\") {\n        console.log(\"Globalization.getCurrencyPattern Error: failureCB is not a function\");\n        return;\n    }\n\n    if(typeof currencyCode == \"string\") {\n        exec(successCB, failureCB, \"Globalization\", \"getCurrencyPattern\", [{\"currencyCode\": currencyCode}]);\n    }\n    else {\n        console.log(\"Globalization.getCurrencyPattern Error: currencyCode is not a currency code\");\n    }\n}\n\n};\n\nmodule.exports = globalization;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\globalization.js")} catch(e) {console.log("exception: in lib\common\plugin\globalization.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/logger\", function(require, exports, module) {\n\n//------------------------------------------------------------------------------\n// The logger module exports the following properties/functions:\n//\n// LOG                          - constant for the level LOG\n// ERROR                        - constant for the level ERROR\n// WARN                         - constant for the level WARN\n// INFO                         - constant for the level INFO\n// DEBUG                        - constant for the level DEBUG\n// logLevel()                   - returns current log level\n// logLevel(value)              - sets and returns a new log level\n// useConsole()                 - returns whether logger is using console\n// useConsole(value)            - sets and returns whether logger is using console\n// log(message,...)             - logs a message at level LOG\n// error(message,...)           - logs a message at level ERROR\n// warn(message,...)            - logs a message at level WARN\n// info(message,...)            - logs a message at level INFO\n// debug(message,...)           - logs a message at level DEBUG\n// logLevel(level,message,...)  - logs a message specified level\n//\n//------------------------------------------------------------------------------\n\nvar logger = exports;\n\nvar exec    = require('cordova/exec');\nvar utils   = require('cordova/utils');\n\nvar UseConsole   = true;\nvar Queued       = [];\nvar DeviceReady  = false;\nvar CurrentLevel;\n\n/**\n * Logging levels\n */\n\nvar Levels = [\n    \"LOG\",\n    \"ERROR\",\n    \"WARN\",\n    \"INFO\",\n    \"DEBUG\"\n];\n\n/*\n * add the logging levels to the logger object and\n * to a separate levelsMap object for testing\n */\n\nvar LevelsMap = {};\nfor (var i=0; i<Levels.length; i++) {\n    var level = Levels[i];\n    LevelsMap[level] = i;\n    logger[level]    = level;\n}\n\nCurrentLevel = LevelsMap.WARN;\n\n/**\n * Getter/Setter for the logging level\n *\n * Returns the current logging level.\n *\n * When a value is passed, sets the logging level to that value.\n * The values should be one of the following constants:\n *    logger.LOG\n *    logger.ERROR\n *    logger.WARN\n *    logger.INFO\n *    logger.DEBUG\n *\n * The value used determines which messages get printed.  The logging\n * values above are in order, and only messages logged at the logging\n * level or above will actually be displayed to the user.  E.g., the\n * default level is WARN, so only messages logged with LOG, ERROR, or\n * WARN will be displayed; INFO and DEBUG messages will be ignored.\n */\nlogger.level = function (value) {\n    if (arguments.length) {\n        if (LevelsMap[value] === null) {\n            throw new Error(\"invalid logging level: \" + value);\n        }\n        CurrentLevel = LevelsMap[value];\n    }\n\n    return Levels[CurrentLevel];\n};\n\n/**\n * Getter/Setter for the useConsole functionality\n *\n * When useConsole is true, the logger will log via the\n * browser 'console' object.  Otherwise, it will use the\n * native Logger plugin.\n */\nlogger.useConsole = function (value) {\n    if (arguments.length) UseConsole = !!value;\n\n    if (UseConsole) {\n        if (typeof console == \"undefined\") {\n            throw new Error(\"global console object is not defined\");\n        }\n\n        if (typeof console.log != \"function\") {\n            throw new Error(\"global console object does not have a log function\");\n        }\n\n        if (typeof console.useLogger == \"function\") {\n            if (console.useLogger()) {\n                throw new Error(\"console and logger are too intertwingly\");\n            }\n        }\n    }\n\n    return UseConsole;\n};\n\n/**\n * Logs a message at the LOG level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.log   = function(message) { logWithArgs(\"LOG\",   arguments); };\n\n/**\n * Logs a message at the ERROR level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.error = function(message) { logWithArgs(\"ERROR\", arguments); };\n\n/**\n * Logs a message at the WARN level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.warn  = function(message) { logWithArgs(\"WARN\",  arguments); };\n\n/**\n * Logs a message at the INFO level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.info  = function(message) { logWithArgs(\"INFO\",  arguments); };\n\n/**\n * Logs a message at the DEBUG level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.debug = function(message) { logWithArgs(\"DEBUG\", arguments); };\n\n// log at the specified level with args\nfunction logWithArgs(level, args) {\n    args = [level].concat([].slice.call(args));\n    logger.logLevel.apply(logger, args);\n}\n\n/**\n * Logs a message at the specified level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.logLevel = function(level, message /* , ... */) {\n    // format the message with the parameters\n    var formatArgs = [].slice.call(arguments, 2);\n    message    = utils.vformat(message, formatArgs);\n\n    if (LevelsMap[level] === null) {\n        throw new Error(\"invalid logging level: \" + level);\n    }\n\n    if (LevelsMap[level] > CurrentLevel) return;\n\n    // queue the message if not yet at deviceready\n    if (!DeviceReady && !UseConsole) {\n        Queued.push([level, message]);\n        return;\n    }\n\n    // if not using the console, use the native logger\n    if (!UseConsole) {\n        exec(null, null, \"Logger\", \"logLevel\", [level, message]);\n        return;\n    }\n\n    // make sure console is not using logger\n    if (console.__usingCordovaLogger) {\n        throw new Error(\"console and logger are too intertwingly\");\n    }\n\n    // log to the console\n    switch (level) {\n        case logger.LOG:   console.log(message); break;\n        case logger.ERROR: console.log(\"ERROR: \" + message); break;\n        case logger.WARN:  console.log(\"WARN: \"  + message); break;\n        case logger.INFO:  console.log(\"INFO: \"  + message); break;\n        case logger.DEBUG: console.log(\"DEBUG: \" + message); break;\n    }\n};\n\n// when deviceready fires, log queued messages\nlogger.__onDeviceReady = function() {\n    if (DeviceReady) return;\n\n    DeviceReady = true;\n\n    for (var i=0; i<Queued.length; i++) {\n        var messageArgs = Queued[i];\n        logger.logLevel(messageArgs[0], messageArgs[1]);\n    }\n\n    Queued = null;\n};\n\n// add a deviceready event to log queued messages\ndocument.addEventListener(\"deviceready\", logger.__onDeviceReady, false);\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\logger.js")} catch(e) {console.log("exception: in lib\common\plugin\logger.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/network\", function(require, exports, module) {\n\nvar exec = require('cordova/exec'),\n    cordova = require('cordova'),\n    channel = require('cordova/channel'),\n    utils = require('cordova/utils');\n\n// Link the onLine property with the Cordova-supplied network info.\n// This works because we clobber the naviagtor object with our own\n// object in bootstrap.js.\nif (typeof navigator != 'undefined') {\n    utils.defineGetter(navigator, 'onLine', function() {\n        return this.connection.type != 'none';\n    });\n}\n\nvar NetworkConnection = function () {\n    this.type = null;\n    this._firstRun = true;\n    this._timer = null;\n    this.timeout = 500;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribe(function() {\n        me.getInfo(function (info) {\n            me.type = info;\n            if (info === \"none\") {\n                // set a timer if still offline at the end of timer send the offline event\n                me._timer = setTimeout(function(){\n                    cordova.fireDocumentEvent(\"offline\");\n                    me._timer = null;\n                    }, me.timeout);\n            } else {\n                // If there is a current offline event pending clear it\n                if (me._timer !== null) {\n                    clearTimeout(me._timer);\n                    me._timer = null;\n                }\n                cordova.fireDocumentEvent(\"online\");\n            }\n\n            // should only fire this once\n            if (me._firstRun) {\n                me._firstRun = false;\n                channel.onCordovaConnectionReady.fire();\n            }\n        },\n        function (e) {\n            // If we can't get the network info we should still tell Cordova\n            // to fire the deviceready event.\n            if (me._firstRun) {\n                me._firstRun = false;\n                channel.onCordovaConnectionReady.fire();\n            }\n            console.log(\"Error initializing Network Connection: \" + e);\n        });\n    });\n};\n\n/**\n * Get connection info\n *\n * @param {Function} successCallback The function to call when the Connection data is available\n * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)\n */\nNetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {\n    // Get info\n    exec(successCallback, errorCallback, \"NetworkStatus\", \"getConnectionInfo\", []);\n};\n\nmodule.exports = new NetworkConnection();\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\network.js")} catch(e) {console.log("exception: in lib\common\plugin\network.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/notification\", function(require, exports, module) {\n\nvar exec = require('cordova/exec');\n\n/**\n * Provides access to notifications on the device.\n */\n\nmodule.exports = {\n\n    /**\n     * Open a native alert dialog, with a customizable title and button text.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} completeCallback   The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Alert)\n     * @param {String} buttonLabel          Label of the close button (default: OK)\n     */\n    alert: function(message, completeCallback, title, buttonLabel) {\n        var _title = (title || \"Alert\");\n        var _buttonLabel = (buttonLabel || \"OK\");\n        exec(completeCallback, null, \"Notification\", \"alert\", [message, _title, _buttonLabel]);\n    },\n\n    /**\n     * Open a native confirm dialog, with a customizable title and button text.\n     * The result that the user selects is returned to the result callback.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} resultCallback     The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Confirm)\n     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')\n     */\n    confirm: function(message, resultCallback, title, buttonLabels) {\n        var _title = (title || \"Confirm\");\n        var _buttonLabels = (buttonLabels || \"OK,Cancel\");\n        exec(resultCallback, null, \"Notification\", \"confirm\", [message, _title, _buttonLabels]);\n    },\n\n    /**\n     * Causes the device to vibrate.\n     *\n     * @param {Integer} mills       The number of milliseconds to vibrate for.\n     */\n    vibrate: function(mills) {\n        exec(null, null, \"Notification\", \"vibrate\", [mills]);\n    },\n\n    /**\n     * Causes the device to beep.\n     * On Android, the default notification ringtone is played \"count\" times.\n     *\n     * @param {Integer} count       The number of beeps.\n     */\n    beep: function(count) {\n        exec(null, null, \"Notification\", \"beep\", [count]);\n    }\n};\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\notification.js")} catch(e) {console.log("exception: in lib\common\plugin\notification.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/requestFileSystem\", function(require, exports, module) {\n\nvar FileError = require('cordova/plugin/FileError'),\n    FileSystem = require('cordova/plugin/FileSystem'),\n    exec = require('cordova/exec');\n\n/**\n * Request a file system in which to store application data.\n * @param type  local file system type\n * @param size  indicates how much storage space, in bytes, the application expects to need\n * @param successCallback  invoked with a FileSystem object\n * @param errorCallback  invoked if error occurs retrieving file system\n */\nvar requestFileSystem = function(type, size, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n\n    if (type < 0 || type > 3) {\n        fail(FileError.SYNTAX_ERR);\n    } else {\n        // if successful, return a FileSystem object\n        var success = function(file_system) {\n            if (file_system) {\n                if (typeof successCallback === 'function') {\n                    // grab the name and root from the file system object\n                    var result = new FileSystem(file_system.name, file_system.root);\n                    successCallback(result);\n                }\n            }\n            else {\n                // no FileSystem object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n        exec(success, fail, \"File\", \"requestFileSystem\", [type, size]);\n    }\n};\n\nmodule.exports = requestFileSystem;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\requestFileSystem.js")} catch(e) {console.log("exception: in lib\common\plugin\requestFileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/resolveLocalFileSystemURI\", function(require, exports, module) {\n\nvar DirectoryEntry = require('cordova/plugin/DirectoryEntry'),\n    FileEntry = require('cordova/plugin/FileEntry'),\n    FileError = require('cordova/plugin/FileError'),\n    exec = require('cordova/exec');\n\n/**\n * Look up file system Entry referred to by local URI.\n * @param {DOMString} uri  URI referring to a local file or directory\n * @param successCallback  invoked with Entry object corresponding to URI\n * @param errorCallback    invoked if error occurs retrieving file system entry\n */\nmodule.exports = function(uri, successCallback, errorCallback) {\n    // error callback\n    var fail = function(error) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(error));\n        }\n    };\n    // sanity check for 'not:valid:filename'\n    if(!uri || uri.split(\":\").length > 2) {\n        setTimeout( function() {\n            fail(FileError.ENCODING_ERR);\n        },0);\n        return;\n    }\n    // if successful, return either a file or directory entry\n    var success = function(entry) {\n        var result;\n        if (entry) {\n            if (typeof successCallback === 'function') {\n                // create appropriate Entry object\n                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);\n                try {\n                    successCallback(result);\n                }\n                catch (e) {\n                    console.log('Error invoking callback: ' + e);\n                }\n            }\n        }\n        else {\n            // no Entry object returned\n            fail(FileError.NOT_FOUND_ERR);\n        }\n    };\n\n    exec(success, fail, \"File\", \"resolveLocalFileSystemURI\", [uri]);\n};\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\resolveLocalFileSystemURI.js")} catch(e) {console.log("exception: in lib\common\plugin\resolveLocalFileSystemURI.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/splashscreen\", function(require, exports, module) {\n\nvar exec = require('cordova/exec');\n\nvar splashscreen = {\n    show:function() {\n        exec(null, null, \"SplashScreen\", \"show\", []);\n    },\n    hide:function() {\n        exec(null, null, \"SplashScreen\", \"hide\", []);\n    }\n};\n\nmodule.exports = splashscreen;\n\n});\n\n//@ sourceURL=lib\\common\\plugin\\splashscreen.js")} catch(e) {console.log("exception: in lib\common\plugin\splashscreen.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/accelerometer\", function(require, exports, module) {\n\nvar callback;\nmodule.exports = {\n    /*\n     * Tells WebOS to put higher priority on accelerometer resolution. Also relaxes the internal garbage collection events.\n     * @param {Boolean} state\n     * Dependencies: Mojo.windowProperties\n     * Example:\n     *         navigator.accelerometer.setFastAccelerometer(true)\n     */\n    setFastAccelerometer: function(state) {\n        navigator.windowProperties.fastAccelerometer = state;\n        navigator.window.setWindowProperties();\n    },\n\n    /*\n     * Starts the native acceleration listener.\n     */\n    start: function(win,fail,args) {\n        console.error(\"webos plugin accelerometer start\");\n        window.removeEventListener(\"acceleration\", callback);\n        callback = function(event) {\n            var accel = new Acceleration(event.accelX*-9.81, event.accelY*-9.81, event.accelZ*-9.81);\n            win(accel);\n        };\n        document.addEventListener(\"acceleration\", callback);\n    },\n    stop: function (win,fail,args) {\n        console.error(\"webos plugin accelerometer stop\");\n        window.removeEventListener(\"acceleration\", callback);\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\accelerometer.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\accelerometer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/application\", function(require, exports, module) {\n\nmodule.exports = {\n    isActivated: function(inWindow) {\n        inWindow = inWindow || window;\n        if(inWindow.PalmSystem) {\n            return inWindow.PalmSystem.isActivated;\n        }\n        return false;\n    },\n\n    /*\n     * Tell webOS to activate the current page of your app, bringing it into focus.\n     * Example:\n     *         navigator.application.activate();\n     */\n    activate: function(inWindow) {\n        inWindow = inWindow || window;\n        if(inWindow.PalmSystem) {\n            inWindow.PalmSystem.activate();\n        }\n    },\n\n    /*\n     * Tell webOS to deactivate your app.\n     * Example:\n     *        navigator.application.deactivate();\n     */\n    deactivate: function(inWindow) {\n        inWindow = inWindow || window;\n        if(inWindow.PalmSystem) {\n            inWindow.PalmSystem.deactivate();\n        }\n    },\n\n    /*\n     * Returns the identifier of the current running application (e.g. com.yourdomain.yourapp).\n     * Example:\n     *        navigator.application.getIdentifier();\n     */\n    getIdentifier: function() {\n        return PalmSystem.identifier;\n    },\n\n    fetchAppId: function() {\n        if (window.PalmSystem) {\n            // PalmSystem.identifier: <appid> <processid>\n            return PalmSystem.identifier.split(\" \")[0];\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\application.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\application.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/camera\", function(require, exports, module) {\n\nvar service = require('cordova/plugin/webos/service');\n\nmodule.exports = {\n    takePicture: function(successCallback, errorCallback, options) {\n        var filename = (options || {}).filename | \"\";\n\n        service.Request('palm://com.palm.applicationManager', {\n            method: 'launch',\n            parameters: {\n            id: 'com.palm.app.camera',\n            params: {\n                    appId: 'com.palm.app.camera',\n                    name: 'capture',\n                    sublaunch: true,\n                    filename: filename\n                }\n            },\n            onSuccess: successCallback,\n            onFailure: errorCallback\n        });\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\camera.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\camera.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/compass\", function(require, exports, module) {\n\nvar CompassHeading = require('cordova/plugin/CompassHeading'),\n    CompassError = require('cordova/plugin/CompassError');\n\nmodule.exports = {\n    getHeading: function (win, lose) {\n        // only TouchPad and Pre3 have a Compass/Gyro\n        if (window.device.name !== \"TouchPad\" && window.device.name !== \"Prē3\") {\n            lose({code: CompassError.COMPASS_NOT_SUPPORTED});\n        } else {\n            console.error(\"webos plugin compass getheading\");\n            var onReadingChanged = function (e) {\n                var heading = new CompassHeading(e.magHeading, e.trueHeading);\n                document.removeEventListener(\"compass\", onReadingChanged);\n                //win(CompassHeading(e.magHeading, e.trueHeading));\n                win(heading);\n            };\n            document.addEventListener(\"compass\", onReadingChanged);\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\compass.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\compass.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/device\", function(require, exports, module) {\n\nvar service = require('cordova/plugin/webos/service');\n\nmodule.exports = {\n    getDeviceInfo: function(success, fail, args) {\n        console.log(\"webOS Plugin: Device - getDeviceInfo\");\n\n        service.Request('palm://com.palm.preferences/systemProperties', {\n            method:\"Get\",\n            parameters:{\"key\": \"com.palm.properties.nduid\" },\n            onSuccess: function (result) {\n                var parsedData = JSON.parse(PalmSystem.deviceInfo);\n\n                success({\n                    cordova: \"2.2.0\",\n                    platform: \"HP webOS\",\n                    name: parsedData.modelName,\n                    version: parsedData.platformVersion,\n                    uuid: result[\"com.palm.properties.nduid\"]\n                });\n            }\n        });\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\device.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\device.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/file\", function(require, exports, module) {\n\n/**\n * Constructor.\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\n\nvar File = function(name, fullPath, type, lastModifiedDate, size){\n    this.name = name || '';\n    this.fullPath = fullPath || null;\n    this.type = type || null;\n    this.lastModifiedDate = lastModifiedDate || null;\n    this.size = size || 0;\n};\n\nmodule.exports = File;\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\file.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\file.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/filereader\", function(require, exports, module) {\n\nvar FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\nvar FileReader = function() {\n    this.fileName = \"\";\n\n    this.readyState = 0; // FileReader.EMPTY\n\n    // File data\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onloadstart = null;    // When the read starts.\n    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)\n    this.onload = null;         // When the read has successfully completed.\n    this.onerror = null;        // When the read has failed (see errors).\n    this.onloadend = null;      // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.\n};\n\nFileReader.prototype.readAsText = function(file, encoding) {\n    console.error(\"webos plugin filereader readastext:\" + file);\n    //Mojo has no file i/o yet, so we use an xhr. very limited\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    // Default encoding is UTF-8\n    var enc = encoding ? encoding : \"UTF-8\";\n\n    var me = this;\n\n    var xhr = new XMLHttpRequest();\n    xhr.onreadystatechange = function() {\n        console.error(\"onreadystatechange:\"+xhr.readyState+\" \"+xhr.status);\n        if (xhr.readyState == 4) {\n            if (xhr.status == 200 && xhr.responseText) {\n                console.error(\"file read completed\");\n                // Save result\n                me.result = xhr.responseText;\n\n                // If onload callback\n                if (typeof me.onload === \"function\") {\n                    me.onload(new ProgressEvent(\"load\", {target:me}));\n                }\n\n                // DONE state\n                me.readyState = FileReader.DONE;\n\n                // If onloadend callback\n                if (typeof me.onloadend === \"function\") {\n                    me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n                }\n\n            } else {\n                // If DONE (cancelled), then don't do anything\n                if (me.readyState === FileReader.DONE) {\n                    return;\n                }\n\n                // DONE state\n                me.readyState = FileReader.DONE;\n\n                me.result = null;\n\n                // Save error\n                me.error = new FileError(FileError.NOT_FOUND_ERR);\n\n                // If onerror callback\n                if (typeof me.onerror === \"function\") {\n                    me.onerror(new ProgressEvent(\"error\", {target:me}));\n                }\n\n                // If onloadend callback\n                if (typeof me.onloadend === \"function\") {\n                    me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n                }\n            }\n        }\n    };\n    xhr.open(\"GET\", file, true);\n    xhr.send();\n};\n\nmodule.exports = FileReader;\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\filereader.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\filereader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/geolocation\", function(require, exports, module) {\n\nvar service = require('cordova/plugin/webos/service');\n\nmodule.exports = {\n    getLocation: function(successCallback, errorCallback, options) {\n        console.error(\"webos plugin geolocation getlocation\");\n        var request = service.Request('palm://com.palm.location', {\n            method: \"getCurrentPosition\",\n            onSuccess: function(event) {\n                var alias={};\n                alias.lastPosition = {\n                    coords: {\n                        latitude: event.latitude,\n                        longitude: event.longitude,\n                        altitude: (event.altitude >= 0 ? event.altitude: null),\n                        speed: (event.velocity >= 0 ? event.velocity: null),\n                        heading: (event.heading >= 0 ? event.heading: null),\n                        accuracy: (event.horizAccuracy >= 0 ? event.horizAccuracy: null),\n                        altitudeAccuracy: (event.vertAccuracy >= 0 ? event.vertAccuracy: null)\n                    },\n                    timestamp: new Date().getTime()\n                };\n\n                successCallback(alias.lastPosition);\n            },\n            onFailure: function() {\n                errorCallback();\n            }\n        });\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\geolocation.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\geolocation.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/keyboard\", function(require, exports, module) {\n\nvar _isShowing = null,\n    _manual = null;\n\nmodule.exports = {\n    types: {\n        text: 0,\n        password: 1,\n        search: 2,\n        range: 3,\n        email: 4,\n        number: 5,\n        phone: 6,\n        url: 7,\n        color: 8\n    },\n    isShowing: function() {\n        return !!_isShowing;\n    },\n    show: function(type){\n        if(this.isManualMode()) {\n            PalmSystem.keyboardShow(type || 0);\n        }\n    },\n    hide: function(){\n        if(this.isManualMode()) {\n            PalmSystem.keyboardHide();\n        }\n    },\n    setManualMode: function(mode){\n        _manual = mode;\n        PalmSystem.setManualKeyboardEnabled(mode);\n    },\n    isManualMode: function(){\n        return _manual || false;\n    },\n    forceShow: function(inType){\n        this.setManualMode(true);\n        PalmSystem.keyboardShow(inType || 0);\n    },\n    forceHide: function(){\n        this.setManualMode(true);\n        PalmSystem.keyboardHide();\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\keyboard.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\keyboard.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/network\", function(require, exports, module) {\n\nvar service=require('cordova/plugin/webos/service');\n\nmodule.exports = {\n    /**\n     * Get connection info\n     *\n     * @param {Function} successCallback The function to call when the Connection data is available\n     * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)\n     */\n    getConnectionInfo: function (successCallback, errorCallback) {\n        // Get info\n        console.log(\"webos Plugin: NetworkStatus - getConnectionInfo\");\n\n        service.Request('palm://com.palm.connectionmanager', {\n            method: 'getstatus',\n            parameters: {},\n            onSuccess: function (result) {\n                console.log(\"result:\"+JSON.stringify(result));\n\n                var info={};\n                if (!result.isInternetConnectionAvailable) { info.type=\"Connection.NONE\"; }\n                if (result.wifi.onInternet) { info.type=\"Connection.WIFI\"; }\n                if (result.wan.state===\"connected\") { info.type=\"Connection.CELL_2G\"; }\n\n                successCallback(info.type);\n            },\n            onFailure: errorCallback\n        });\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\network.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\network.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/notification\", function(require, exports, module) {\n\nmodule.exports = {\n    /*\n     * adds a dashboard to the WebOS app\n     * @param {String} url\n     * @param {String} html\n     * Example:\n     *        navigator.notification.newDashboard(\"dashboard.html\");\n     */\n    newDashboard: function(url, html) {\n        var win = window.open(url, \"_blank\", \"attributes={\\\"window\\\":\\\"dashboard\\\"}\");\n        html && win.document.write(html);\n        win.PalmSystem.stageReady();\n    },\n\n    /*\n     * Displays a banner notification. If specified, will send your 'response' object as data via the 'palmsystem' DOM event.\n     * If no 'icon' filename is specified, will use a small version of your application icon.\n     * @param {String} message\n     * @param {Object} response\n     * @param {String} icon\n     * @param {String} soundClass class of the sound; supported classes are: \"ringtones\", \"alerts\", \"alarm\", \"calendar\", \"notification\"\n     * @param {String} soundFile partial or full path to the sound file\n     * @param {String} soundDurationMs of sound in ms\n     * Example:\n     *        navigator.notification.showBanner('test message');\n     */\n    showBanner: function(message, response, icon, soundClass, soundFile, soundDurationMs) {\n        response = response || {\n            banner: true\n        };\n        PalmSystem.addBannerMessage(message, JSON.stringify(response), icon, soundClass, soundFile, soundDurationMs);\n    },\n\n    /**\n     * Remove a banner from the banner area. The category parameter defaults to 'banner'. Will not remove\n     * messages that are already displayed.\n     * @param {String} category\n            Value defined by the application and usually same one used in {@link showBanner}.\n            It is used if you have more than one kind of banner message.\n     */\n    removeBannerMessage: function(category) {\n        var bannerKey = category || 'banner';\n        var bannerId = this.banners.get(bannerKey);\n        if (bannerId) {\n            try {\n                PalmSystem.removeBannerMessage(bannerId);\n            } catch(removeBannerException) {\n                window.debug.error(removeBannerException.toString());\n            }\n        }\n    },\n\n    /*\n     * Remove all pending banner messages from the banner area. Will not remove messages that are already displayed.\n     */\n    clearBannerMessage: function() {\n        PalmSystem.clearBannerMessage();\n    },\n\n    /*\n     * This function vibrates the device\n     * @param {number} duration The duration in ms to vibrate for.\n     * @param {number} intensity The intensity of the vibration\n     */\n    vibrate_private: function(duration, intensity) {\n        //the intensity for palm is inverted; 0=high intensity, 100=low intensity\n        //this is opposite from our api, so we invert\n        if (isNaN(intensity) || intensity > 100 || intensity <= 0)\n        intensity = 0;\n        else\n        intensity = 100 - intensity;\n\n        // if the app id does not have the namespace \"com.palm.\", an error will be thrown here\n        //this.vibhandle = new Mojo.Service.Request(\"palm://com.palm.vibrate\", {\n        this.vibhandle = navigator.service.Request(\"palm://com.palm.vibrate\", {\n            method: 'vibrate',\n            parameters: {\n                'period': intensity,\n                'duration': duration\n            }\n        },\n        false);\n    },\n\n    vibrate: function(param) {\n        PalmSystem.playSoundNotification('vibrate');\n    },\n    /*\n     * Plays the specified sound\n     * @param {String} soundClass class of the sound; supported classes are: \"ringtones\", \"alerts\", \"alarm\", \"calendar\", \"notification\"\n     * @param {String} soundFile partial or full path to the sound file\n     * @param {String} soundDurationMs of sound in ms\n     */\n    beep: function(param) {\n        PalmSystem.playSoundNotification('alerts');\n    },\n\n    getRootWindow: function() {\n        var w = window.opener || window.rootWindow || window.top || window;\n        if(!w.setTimeout) { // use this window as the root if we don't have access to the real root.\n            w = window;\n        }\n        return w;\n    },\n\n    open: function(inOpener, inUrl, inName, inAttributes, inWindowInfo) {\n        var url = inUrl;\n        var a = inAttributes && JSON.stringify(inAttributes);\n        a = \"attributes=\" + a;\n        var i = inWindowInfo ? inWindowInfo + \", \" : \"\";\n        return inOpener.open(url, inName, i + a);\n    },\n\n    openWindow: function(inUrl, inName, inParams, inAttributes, inWindowInfo) {\n        //var attributes = inAttributes || {};\n        //attributes.window = attributes.window || \"card\";\n        // NOTE: make the root window open all windows.\n        return this.open(this.getRootWindow(), inUrl, inName || \"\", inAttributes, inWindowInfo);\n    },\n\n    alert: function(message,callback,title,buttonName) {\n        var inAttributes = {};\n        //inAttributes.window = \"card\"; // create card\n        inAttributes.window = \"popupalert\"; // create popup\n        //inAttributes.window=\"dashboard\"; // create dashboard\n        var html='<html><head><script>setTimeout(function(f){var el=window.document.getElementById(\"b1\");console.error(el);el.addEventListener(\"click\",function(f){window.close();},false);},500);</script></head><body>'+message+'<br/><button id=\"b1\">'+buttonName+'</button></body></html>';\n        var inName=\"PopupAlert\";\n        var inUrl=\"\";\n        var inParams={};\n        var inHeight=120;\n        var w = this.openWindow(inUrl, inName, inParams, inAttributes, \"height=\" + (inHeight || 200));\n        w.document.write(html);\n        w.PalmSystem.stageReady();\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\notification.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\notification.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/orientation\", function(require, exports, module) {\n\nmodule.exports = {\n    setOrientation: function(orientation) {\n        PalmSystem.setWindowOrientation(orientation);\n    },\n\n    /*\n     * Returns the current window orientation\n     * orientation is one of 'up', 'down', 'left', 'right', or 'free'\n     */\n    getCurrentOrientation: function() {\n          return PalmSystem.windowOrientation;\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\orientation.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\orientation.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/requestfilesystem\", function(require, exports, module) {\n\nmodule.exports = function(type,size,successCallback,errorCallback) {\n    console.error(\"requestFileSystem\");\n\n    var theFileSystem={};\n    theFileSystem.name=\"webOS\";\n    theFileSystem.root={};\n    theFileSystem.root.name=\"Root\";\n\n    theFileSystem.root.getFile=function(filename,options,successCallback,errorCallback) {\n        console.error(\"getFile\");\n        if (options.create) { errorCallback(); }\n        var theFile=filename;\n        successCallback(theFile);\n    };\n\n    successCallback(theFileSystem);\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\requestfilesystem.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\requestfilesystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/service\", function(require, exports, module) {\n\nfunction Service() { }\n\nService.prototype.Request = function (uri, params) {\n    var req = new PalmServiceBridge();\n    var url = uri + \"/\" + (params.method || \"\");\n    req.url = url;\n\n    this.req = req;\n    this.url = url;\n    this.params = params || {};\n\n    this.call(params);\n\n    return this;\n};\n\nService.prototype.call = function(params) {\n    var onsuccess = null;\n    var onfailure = null;\n    var oncomplete = null;\n\n    if (typeof params.onSuccess === 'function')\n        onsuccess = params.onSuccess;\n\n    if (typeof params.onFailure === 'function')\n        onerror = params.onFailure;\n\n    if (typeof params.onComplete === 'function')\n        oncomplete = params.onComplete;\n\n    this.req.onservicecallback = callback;\n\n    function callback(msg) {\n        var response = JSON.parse(msg);\n\n        if ((response.errorCode) && onfailure)\n            onfailure(response);\n        else if (onsuccess)\n            onsuccess(response);\n\n        if (oncomplete)\n            oncomplete(response);\n    }\n\n    this.data = (typeof params.parameters === 'object') ? JSON.stringify(params.parameters) : '{}';\n\n    this.req.call(this.url, this.data);\n};\n\nmodule.exports = new Service();\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\service.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\service.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/webos/window\", function(require, exports, module) {\n\nmodule.exports={\n    launchParams: function() {\n        return JSON.parse(PalmSystem.launchParams) || {};\n    },\n    /*\n     * This is a thin wrapper for 'window.open()' which optionally sets document contents to 'html', and calls 'PalmSystem.stageReady()'\n     * on your new card. Note that this new card will not come with your framework (if any) or anything for that matter.\n     * @param {String} url\n     * @param {String} html\n     * Example:\n     *        navigator.window.newCard('about:blank', '<html><body>Hello again!</body></html>');\n     */\n    newCard: function(url, html) {\n        var win = window.open(url || \"\");\n        if (html)\n            win.document.write(html);\n        win.PalmSystem.stageReady();\n    },\n\n    /*\n     * Enable or disable full screen display (full screen removes the app menu bar and the rounded corners of the screen).\n     * @param {Boolean} state\n     * Example:\n     *        navigator.window.setFullScreen(true);\n     */\n    setFullScreen: function(state) {\n        // valid state values are: true or false\n        PalmSystem.enableFullScreenMode(state);\n    },\n\n    /*\n     * used to set the window properties of the WebOS app\n     * @param {Object} props\n     * Example:\n     *         private method used by other member functions - ideally we shouldn't call this method\n     */\n    setWindowProperties: function(inWindow, inProps) {\n        if(arguments.length==1) {\n            inProps = inWindow;\n            inWindow = window;\n        }\n        if(inWindow.PalmSystem) {\n            inWindow.PalmSystem.setWindowProperties(inProps);\n        }\n    },\n\n    /*\n     * Enable or disable screen timeout. When enabled, the device screen will not dim. This is useful for navigation, clocks or other \"dock\" apps.\n     * @param {Boolean} state\n     * Example:\n     *        navigator.window.blockScreenTimeout(true);\n     */\n    blockScreenTimeout: function(state) {\n        navigator.windowProperties.blockScreenTimeout = state;\n        this.setWindowProperties();\n    },\n\n    /*\n     * Sets the lightbar to be a little dimmer for screen locked notifications.\n     * @param {Boolean} state\n     * Example:\n     *        navigator.window.setSubtleLightbar(true);\n     */\n    setSubtleLightbar: function(state) {\n        navigator.windowProperties.setSubtleLightbar = state;\n        this.setWindowProperties();\n    }\n};\n\n});\n\n//@ sourceURL=lib\\webos\\plugin\\webos\\window.js")} catch(e) {console.log("exception: in lib\webos\plugin\webos\window.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/utils\", function(require, exports, module) {\n\nvar utils = exports;\n\n/**\n * Defines a property getter for obj[key].\n */\nutils.defineGetter = function(obj, key, func) {\n    if (Object.defineProperty) {\n        Object.defineProperty(obj, key, { get: func });\n    } else {\n        obj.__defineGetter__(key, func);\n    }\n};\n\n/**\n * Returns an indication of whether the argument is an array or not\n */\nutils.isArray = function(a) {\n    return Object.prototype.toString.call(a) == '[object Array]';\n};\n\n/**\n * Returns an indication of whether the argument is a Date or not\n */\nutils.isDate = function(d) {\n    return Object.prototype.toString.call(d) == '[object Date]';\n};\n\n/**\n * Does a deep clone of the object.\n */\nutils.clone = function(obj) {\n    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {\n        return obj;\n    }\n\n    var retVal, i;\n\n    if(utils.isArray(obj)){\n        retVal = [];\n        for(i = 0; i < obj.length; ++i){\n            retVal.push(utils.clone(obj[i]));\n        }\n        return retVal;\n    }\n\n    retVal = {};\n    for(i in obj){\n        if(!(i in retVal) || retVal[i] != obj[i]) {\n            retVal[i] = utils.clone(obj[i]);\n        }\n    }\n    return retVal;\n};\n\n/**\n * Returns a wrapped version of the function\n */\nutils.close = function(context, func, params) {\n    if (typeof params == 'undefined') {\n        return function() {\n            return func.apply(context, arguments);\n        };\n    } else {\n        return function() {\n            return func.apply(context, params);\n        };\n    }\n};\n\n/**\n * Create a UUID\n */\nutils.createUUID = function() {\n    return UUIDcreatePart(4) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(6);\n};\n\n/**\n * Extends a child object from a parent object using classical inheritance\n * pattern.\n */\nutils.extend = (function() {\n    // proxy used to establish prototype chain\n    var F = function() {};\n    // extend Child from Parent\n    return function(Child, Parent) {\n        F.prototype = Parent.prototype;\n        Child.prototype = new F();\n        Child.__super__ = Parent.prototype;\n        Child.prototype.constructor = Child;\n    };\n}());\n\n/**\n * Alerts a message in any available way: alert or console.log.\n */\nutils.alert = function(msg) {\n    if (window.alert) {\n        window.alert(msg);\n    } else if (console && console.log) {\n        console.log(msg);\n    }\n};\n\n/**\n * Formats a string and arguments following it ala sprintf()\n *\n * see utils.vformat() for more information\n */\nutils.format = function(formatString /* ,... */) {\n    var args = [].slice.call(arguments, 1);\n    return utils.vformat(formatString, args);\n};\n\n/**\n * Formats a string and arguments following it ala vsprintf()\n *\n * format chars:\n *   %j - format arg as JSON\n *   %o - format arg as JSON\n *   %c - format arg as ''\n *   %% - replace with '%'\n * any other char following % will format it's\n * arg via toString().\n *\n * for rationale, see FireBug's Console API:\n *    http://getfirebug.com/wiki/index.php/Console_API\n */\nutils.vformat = function(formatString, args) {\n    if (formatString === null || formatString === undefined) return \"\";\n    if (arguments.length == 1) return formatString.toString();\n    if (typeof formatString != \"string\") return formatString.toString();\n\n    var pattern = /(.*?)%(.)(.*)/;\n    var rest    = formatString;\n    var result  = [];\n\n    while (args.length) {\n        var arg   = args.shift();\n        var match = pattern.exec(rest);\n\n        if (!match) break;\n\n        rest = match[3];\n\n        result.push(match[1]);\n\n        if (match[2] == '%') {\n            result.push('%');\n            args.unshift(arg);\n            continue;\n        }\n\n        result.push(formatted(arg, match[2]));\n    }\n\n    result.push(rest);\n\n    return result.join('');\n};\n\n//------------------------------------------------------------------------------\nfunction UUIDcreatePart(length) {\n    var uuidpart = \"\";\n    for (var i=0; i<length; i++) {\n        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);\n        if (uuidchar.length == 1) {\n            uuidchar = \"0\" + uuidchar;\n        }\n        uuidpart += uuidchar;\n    }\n    return uuidpart;\n}\n\n//------------------------------------------------------------------------------\nfunction formatted(object, formatChar) {\n\n    try {\n        switch(formatChar) {\n            case 'j':\n            case 'o': return JSON.stringify(object);\n            case 'c': return '';\n        }\n    }\n    catch (e) {\n        return \"error JSON.stringify()ing argument: \" + e;\n    }\n\n    if ((object === null) || (object === undefined)) {\n        return Object.prototype.toString.call(object);\n    }\n\n    return object.toString();\n}\n\n});\n\n//@ sourceURL=lib\\common\\utils.js")} catch(e) {console.log("exception: in lib\common\utils.js: " + e);console.log(e.stack);}
+
+window.cordova = require('cordova');
+
+try {eval("\n(function (context) {\n    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.\n    // We replace it so that properties that can't be clobbered can instead be overridden.\n    if (typeof navigator != 'undefined') {\n        var CordovaNavigator = function () {};\n        CordovaNavigator.prototype = navigator;\n        navigator = new CordovaNavigator();\n    }\n\n    var channel = require(\"cordova/channel\"),\n        _self = {\n            boot: function () {\n                /**\n                 * Create all cordova objects once page has fully loaded and native side is ready.\n                 */\n                channel.join(function() {\n                    var builder = require('cordova/builder'),\n                        base = require('cordova/common'),\n                        platform = require('cordova/platform');\n\n                    // Drop the common globals into the window object, but be nice and don't overwrite anything.\n                    builder.build(base.objects).intoButDoNotClobber(window);\n\n                    // Drop the platform-specific globals into the window object\n                    // and clobber any existing object.\n                    builder.build(platform.objects).intoAndClobber(window);\n\n                    // Merge the platform-specific overrides/enhancements into\n                    // the window object.\n                    if (typeof platform.merges !== 'undefined') {\n                        builder.build(platform.merges).intoAndMerge(window);\n                    }\n\n                    // Call the platform-specific initialization\n                    platform.initialize();\n\n                    // Fire event to notify that all objects are created\n                    channel.onCordovaReady.fire();\n\n                    // Fire onDeviceReady event once all constructors have run and\n                    // cordova info has been received from native side.\n                    channel.join(function() {\n                        require('cordova').fireDocumentEvent('deviceready');\n                    }, channel.deviceReadyChannelsArray);\n\n                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);\n            }\n        };\n\n    // boot up once native side is ready\n    channel.onNativeReady.subscribe(_self.boot);\n\n    // _nativeReady is global variable that the native side can set\n    // to signify that the native code is ready. It is a global since\n    // it may be called before any cordova JS is ready.\n    if (window._nativeReady) {\n        channel.onNativeReady.fire();\n    }\n\n}(window));\n\n//@ sourceURL=lib\\scripts\\bootstrap.js")} catch(e) {console.log("exception: in lib\scripts\bootstrap.js: " + e);console.log(e.stack);}
+try {eval("\nrequire('cordova/channel').onNativeReady.fire();\n\n//@ sourceURL=lib\\scripts\\bootstrap-webos.js")} catch(e) {console.log("exception: in lib\scripts\bootstrap-webos.js: " + e);console.log(e.stack);}
+
+})();
diff --git a/lib/cordova.webos.js b/lib/cordova.webos.js
new file mode 100644
index 0000000..d425678
--- /dev/null
+++ b/lib/cordova.webos.js
@@ -0,0 +1,6427 @@
+// 
+
+// File generated at :: Tue Oct 30 2012 10:12:55 GMT+0100 (W. Europe Standard Time)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+// file: lib\scripts\require.js
+
+var require,
+    define;
+
+(function () {
+    var modules = {};
+    // Stack of moduleIds currently being built.
+    var requireStack = [];
+    // Map of module ID -> index into requireStack of modules currently being built.
+    var inProgressModules = {};
+
+    function build(module) {
+        var factory = module.factory;
+        module.exports = {};
+        delete module.factory;
+        factory(require, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        } else if (id in inProgressModules) {
+            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+            throw "Cycle in require graph: " + cycle;
+        }
+        if (modules[id].factory) {
+            try {
+                inProgressModules[id] = requireStack.length;
+                requireStack.push(id);
+                return build(modules[id]);
+            } finally {
+                delete inProgressModules[id];
+                requireStack.pop();
+            }
+        }
+        return modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+
+
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+    channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        documentEventHandlers[e].subscribe(handler);
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+if(typeof window.console === "undefined") {
+    window.console = {
+        log:function(){}
+    };
+}
+
+var cordova = {
+    define:define,
+    require:require,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event) {
+        return (windowEventHandlers[event] = channel.create(event));
+    },
+    addStickyDocumentEventHandler:function(event) {
+        return (documentEventHandlers[event] = channel.createSticky(event));
+    },
+    addDocumentEventHandler:function(event) {
+        return (documentEventHandlers[event] = channel.create(event));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retrieve original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     * bNoDetach is required for events which cause an exception which needs to be caught in native code
+     */
+    fireDocumentEvent: function(type, data, bNoDetach) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            if( bNoDetach ) {
+              documentEventHandlers[type].fire(evt);
+            }
+            else {
+              setTimeout(function() {
+                  documentEventHandlers[type].fire(evt);
+              }, 0);
+            }
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+
+    /**
+     * Plugin callback mechanism.
+     */
+    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+    callbackId: Math.floor(Math.random() * 2000000000),
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     */
+    callbackSuccess: function(callbackId, args) {
+        try {
+            cordova.callbackFromNative(callbackId, true, args.status, args.message, args.keepCallback);
+        } catch (e) {
+            console.log("Error in error callback: " + callbackId + " = "+e);
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     */
+    callbackError: function(callbackId, args) {
+        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+        // Derive success from status.
+        try {
+            cordova.callbackFromNative(callbackId, false, args.status, args.message, args.keepCallback);
+        } catch (e) {
+            console.log("Error in error callback: " + callbackId + " = "+e);
+        }
+    },
+
+    /**
+     * Called by native code when returning the result from an action.
+     */
+    callbackFromNative: function(callbackId, success, status, message, keepCallback) {
+        var callback = cordova.callbacks[callbackId];
+        if (callback) {
+            if (success && status == cordova.callbackStatus.OK) {
+                callback.success && callback.success(message);
+            } else if (!success) {
+                callback.fail && callback.fail(message);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribe(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib\common\builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+    if (message) {
+        utils.defineGetter(obj, key, function() {
+            window.console && console.log(message);
+            return value;
+        });
+    } else {
+        obj[key] = value;
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+          var result = obj.path ? require(obj.path) : {};
+
+          if (clobber) {
+              // Clobber if it doesn't exist.
+              if (typeof parent[key] === 'undefined') {
+                  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+              } else if (typeof obj.path !== 'undefined') {
+                  // If merging, merge properties onto parent, otherwise, clobber.
+                  if (merge) {
+                      recursiveMerge(parent[key], result);
+                  } else {
+                      assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                  }
+              }
+              result = parent[key];
+          } else {
+            // Overwrite if not currently defined.
+            if (typeof parent[key] == 'undefined') {
+              assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+            } else if (merge && typeof obj.path !== 'undefined') {
+              // If merging, merge parent onto result
+              recursiveMerge(result, parent[key]);
+              parent[key] = result;
+            } else {
+              // Set result to what already exists, so we can build children into it if they exist.
+              result = parent[key];
+            }
+          }
+
+          if (obj.children) {
+            include(result, obj.children, clobber, merge);
+          }
+        } catch(e) {
+          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                target.prototype[prop] = src[prop];
+            } else {
+                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(
+                        target[prop], src[prop]) : src[prop];
+            }
+        }
+    }
+    return target;
+}
+
+module.exports = {
+    build: function (objects) {
+        return {
+            intoButDoNotClobber: function (target) {
+                include(target, objects, false, false);
+            },
+            intoAndClobber: function(target) {
+                include(target, objects, true, false);
+            },
+            intoAndMerge: function(target) {
+                include(target, objects, true, true);
+            }
+        };
+    }
+};
+
+});
+
+// file: lib\common\channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady*              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady*         Internal event fired when device properties are available.
+ * onCordovaConnectionReady*   Internal event fired when the connection property has been set.
+ * onDeviceReady*              User event fired to indicate that Cordova is ready
+ * onResume                    User event fired to indicate a start/resume lifecycle event
+ * onPause                     User event fired to indicate a pause lifecycle event
+ * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ */
+var Channel = function(type, sticky) {
+    this.type = type;
+    // Map of guid -> function.
+    this.handlers = {};
+    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+    this.state = sticky ? 1 : 0;
+    // Used in sticky mode to remember args passed to fire().
+    this.fireArgs = null;
+    // Used by onHasSubscribersChange to know if there are any listeners.
+    this.numHandlers = 0;
+    // Function that is called when the first listener is subscribed, or when
+    // the last listener is unsubscribed.
+    this.onHasSubscribersChange = null;
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired. All channels must be sticky channels.
+         */
+        join: function(h, c) {
+            var len = c.length,
+                i = len,
+                f = function() {
+                    if (!(--i)) h();
+                };
+            for (var j=0; j<len; j++) {
+                if (c[j].state === 0) {
+                    throw Error('Can only use join with sticky channels.');
+                }
+                c[j].subscribe(f);
+            }
+            if (!len) h();
+        },
+        create: function(type) {
+            return channel[type] = new Channel(type, false);
+        },
+        createSticky: function(type) {
+            return channel[type] = new Channel(type, true);
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = channel[feature] || this.createSticky(feature);
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+    if (this.state == 2) {
+        f.apply(c || this, this.fireArgs);
+        return;
+    }
+
+    var func = f,
+        guid = f.observer_guid;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    if (!guid) {
+        // first time any channel has seen this subscriber
+        guid = '' + nextGuid++;
+    }
+    func.observer_guid = guid;
+    f.observer_guid = guid;
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[guid]) {
+        this.handlers[guid] = func;
+        this.numHandlers++;
+        if (this.numHandlers == 1) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+    // need a function to unsubscribe
+    forceFunction(f);
+
+    var guid = f.observer_guid,
+        handler = this.handlers[guid];
+    if (handler) {
+        delete this.handlers[guid];
+        this.numHandlers--;
+        if (this.numHandlers === 0) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    var fail = false,
+        fireArgs = Array.prototype.slice.call(arguments);
+    // Apply stickiness.
+    if (this.state == 1) {
+        this.state = 2;
+        this.fireArgs = fireArgs;
+    }
+    if (this.numHandlers) {
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
+        for (var item in this.handlers) {
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            toCall[i].apply(this, fireArgs);
+        }
+        if (this.state == 2 && this.numHandlers) {
+            this.numHandlers = 0;
+            this.handlers = {};
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.createSticky('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.createSticky('onCordovaConnectionReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+
+module.exports = channel;
+
+});
+
+// file: lib\common\commandProxy.js
+define("cordova/commandProxy", function(require, exports, module) {
+
+
+// internal map of proxy function
+var CommandProxyMap = {};
+
+module.exports = {
+
+    // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
+    add:function(id,proxyObj) {
+        console.log("adding proxy for " + id);
+        CommandProxyMap[id] = proxyObj;
+        return proxyObj;
+    },
+
+    // cordova.commandProxy.remove("Accelerometer");
+    remove:function(id) {
+        var proxy = CommandProxyMap[id];
+        delete CommandProxyMap[id];
+        CommandProxyMap[id] = null;
+        return proxy;
+    },
+
+    get:function(service,action) {
+        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
+    }
+};
+});
+
+// file: lib\common\common.js
+define("cordova/common", function(require, exports, module) {
+
+module.exports = {
+    objects: {
+        cordova: {
+            path: 'cordova',
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                },
+                logger: {
+                    path: 'cordova/plugin/logger'
+                }
+            }
+        },
+        Cordova: {
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        navigator: {
+            children: {
+                notification: {
+                    path: 'cordova/plugin/notification'
+                },
+                accelerometer: {
+                    path: 'cordova/plugin/accelerometer'
+                },
+                battery: {
+                    path: 'cordova/plugin/battery'
+                },
+                camera:{
+                    path: 'cordova/plugin/Camera'
+                },
+                compass:{
+                    path: 'cordova/plugin/compass'
+                },
+                connection: {
+                    path: 'cordova/plugin/network'
+                },
+                contacts: {
+                    path: 'cordova/plugin/contacts'
+                },
+                device:{
+                    children:{
+                        capture: {
+                            path: 'cordova/plugin/capture'
+                        }
+                    }
+                },
+                geolocation: {
+                    path: 'cordova/plugin/geolocation'
+                },
+                globalization: {
+                    path: 'cordova/plugin/globalization'
+                },
+                network: {
+                    children: {
+                        connection: {
+                            path: 'cordova/plugin/network',
+                            deprecated: 'navigator.network.connection is deprecated. Use navigator.connection instead.'
+                        }
+                    }
+                },
+                splashscreen: {
+                    path: 'cordova/plugin/splashscreen'
+                }
+            }
+        },
+        Acceleration: {
+            path: 'cordova/plugin/Acceleration'
+        },
+        Camera:{
+            path: 'cordova/plugin/CameraConstants'
+        },
+        CameraPopoverOptions: {
+            path: 'cordova/plugin/CameraPopoverOptions'
+        },
+        CaptureError: {
+            path: 'cordova/plugin/CaptureError'
+        },
+        CaptureAudioOptions:{
+            path: 'cordova/plugin/CaptureAudioOptions'
+        },
+        CaptureImageOptions: {
+            path: 'cordova/plugin/CaptureImageOptions'
+        },
+        CaptureVideoOptions: {
+            path: 'cordova/plugin/CaptureVideoOptions'
+        },
+        CompassHeading:{
+            path: 'cordova/plugin/CompassHeading'
+        },
+        CompassError:{
+            path: 'cordova/plugin/CompassError'
+        },
+        ConfigurationData: {
+            path: 'cordova/plugin/ConfigurationData'
+        },
+        Connection: {
+            path: 'cordova/plugin/Connection'
+        },
+        Contact: {
+            path: 'cordova/plugin/Contact'
+        },
+        ContactAddress: {
+            path: 'cordova/plugin/ContactAddress'
+        },
+        ContactError: {
+            path: 'cordova/plugin/ContactError'
+        },
+        ContactField: {
+            path: 'cordova/plugin/ContactField'
+        },
+        ContactFindOptions: {
+            path: 'cordova/plugin/ContactFindOptions'
+        },
+        ContactName: {
+            path: 'cordova/plugin/ContactName'
+        },
+        ContactOrganization: {
+            path: 'cordova/plugin/ContactOrganization'
+        },
+        Coordinates: {
+            path: 'cordova/plugin/Coordinates'
+        },
+        device: {
+            path: 'cordova/plugin/device'
+        },
+        DirectoryEntry: {
+            path: 'cordova/plugin/DirectoryEntry'
+        },
+        DirectoryReader: {
+            path: 'cordova/plugin/DirectoryReader'
+        },
+        Entry: {
+            path: 'cordova/plugin/Entry'
+        },
+        File: {
+            path: 'cordova/plugin/File'
+        },
+        FileEntry: {
+            path: 'cordova/plugin/FileEntry'
+        },
+        FileError: {
+            path: 'cordova/plugin/FileError'
+        },
+        FileReader: {
+            path: 'cordova/plugin/FileReader'
+        },
+        FileSystem: {
+            path: 'cordova/plugin/FileSystem'
+        },
+        FileTransfer: {
+            path: 'cordova/plugin/FileTransfer'
+        },
+        FileTransferError: {
+            path: 'cordova/plugin/FileTransferError'
+        },
+        FileUploadOptions: {
+            path: 'cordova/plugin/FileUploadOptions'
+        },
+        FileUploadResult: {
+            path: 'cordova/plugin/FileUploadResult'
+        },
+        FileWriter: {
+            path: 'cordova/plugin/FileWriter'
+        },
+        Flags: {
+            path: 'cordova/plugin/Flags'
+        },
+        GlobalizationError: {
+            path: 'cordova/plugin/GlobalizationError'
+        },
+        LocalFileSystem: {
+            path: 'cordova/plugin/LocalFileSystem'
+        },
+        Media: {
+            path: 'cordova/plugin/Media'
+        },
+        MediaError: {
+            path: 'cordova/plugin/MediaError'
+        },
+        MediaFile: {
+            path: 'cordova/plugin/MediaFile'
+        },
+        MediaFileData:{
+            path: 'cordova/plugin/MediaFileData'
+        },
+        Metadata:{
+            path: 'cordova/plugin/Metadata'
+        },
+        Position: {
+            path: 'cordova/plugin/Position'
+        },
+        PositionError: {
+            path: 'cordova/plugin/PositionError'
+        },
+        ProgressEvent: {
+            path: 'cordova/plugin/ProgressEvent'
+        },
+        requestFileSystem:{
+            path: 'cordova/plugin/requestFileSystem'
+        },
+        resolveLocalFileSystemURI:{
+            path: 'cordova/plugin/resolveLocalFileSystemURI'
+        }
+    }
+};
+
+});
+
+// file: lib\webos\exec.js
+define("cordova/exec", function(require, exports, module) {
+
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchrounous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success    The success callback
+ * @param {Function} fail       The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+
+var plugins = {
+    "Device": require('cordova/plugin/webos/device'),
+    "NetworkStatus": require('cordova/plugin/webos/network'),
+    "Compass": require('cordova/plugin/webos/compass'),
+    "Camera": require('cordova/plugin/webos/camera'),
+    "Accelerometer" : require('cordova/plugin/webos/accelerometer'),
+    "Notification" : require('cordova/plugin/webos/notification'),
+    "Geolocation": require('cordova/plugin/webos/geolocation')
+};
+
+module.exports = function(success, fail, service, action, args) {
+    try {
+        console.error("exec:call plugin:"+service+":"+action);
+        plugins[service][action](success, fail, args);
+    }
+    catch(e) {
+        console.error("missing exec: " + service + "." + action);
+        console.error(args);
+        console.error(e);
+        console.error(e.stack);
+    }
+};
+
+});
+
+// file: lib\webos\platform.js
+define("cordova/platform", function(require, exports, module) {
+
+module.exports = {
+    id: "webos",
+    initialize: function() {
+        if (window.PalmSystem) {
+            window.PalmSystem.stageReady();
+        }
+        window.Mojo = window.Mojo || {};
+        window.Mojo.stageActivated = function() {
+            console.error("stageActivated");
+        };
+    },
+    objects: {
+        requestFileSystem:{
+            path: 'cordova/plugin/webos/requestfilesystem'
+        },
+        FileReader: {
+            path: "cordova/plugin/webos/filereader"
+        }
+    },
+    merges: {
+        navigator: {
+            children: {
+                service: {
+                    path: "cordova/plugin/webos/service"
+                },
+                application: {
+                    path: "cordova/plugin/webos/application"
+                },
+                window: {
+                    path: "cordova/plugin/webos/window"
+                },
+                notification: {
+                    path: "cordova/plugin/webos/notification"
+                },
+                orientation: {
+                    path: "cordova/plugin/webos/orientation"
+                },
+                keyboard: {
+                    path: "cordova/plugin/webos/keyboard"
+                }
+            }
+        }
+    }
+};
+
+});
+
+// file: lib\common\plugin\Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+
+var Acceleration = function(x, y, z, timestamp) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+    this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib\common\plugin\Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    Camera = require('cordova/plugin/CameraConstants');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+    cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+    options = options || {};
+    // successCallback required
+    if (typeof successCallback != "function") {
+        console.log("Camera Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback != "function")) {
+        console.log("Camera Error: errorCallback is not a function");
+        return;
+    }
+
+    var quality = 50;
+    if (typeof options.quality == "number") {
+        quality = options.quality;
+    } else if (typeof options.quality == "string") {
+        var qlity = parseInt(options.quality, 10);
+        if (isNaN(qlity) === false) {
+            quality = qlity.valueOf();
+        }
+    }
+
+    var destinationType = Camera.DestinationType.FILE_URI;
+    if (typeof options.destinationType == "number") {
+        destinationType = options.destinationType;
+    }
+
+    var sourceType = Camera.PictureSourceType.CAMERA;
+    if (typeof options.sourceType == "number") {
+        sourceType = options.sourceType;
+    }
+
+    var targetWidth = -1;
+    if (typeof options.targetWidth == "number") {
+        targetWidth = options.targetWidth;
+    } else if (typeof options.targetWidth == "string") {
+        var width = parseInt(options.targetWidth, 10);
+        if (isNaN(width) === false) {
+            targetWidth = width.valueOf();
+        }
+    }
+
+    var targetHeight = -1;
+    if (typeof options.targetHeight == "number") {
+        targetHeight = options.targetHeight;
+    } else if (typeof options.targetHeight == "string") {
+        var height = parseInt(options.targetHeight, 10);
+        if (isNaN(height) === false) {
+            targetHeight = height.valueOf();
+        }
+    }
+
+    var encodingType = Camera.EncodingType.JPEG;
+    if (typeof options.encodingType == "number") {
+        encodingType = options.encodingType;
+    }
+
+    var mediaType = Camera.MediaType.PICTURE;
+    if (typeof options.mediaType == "number") {
+        mediaType = options.mediaType;
+    }
+    var allowEdit = false;
+    if (typeof options.allowEdit == "boolean") {
+        allowEdit = options.allowEdit;
+    } else if (typeof options.allowEdit == "number") {
+        allowEdit = options.allowEdit <= 0 ? false : true;
+    }
+    var correctOrientation = false;
+    if (typeof options.correctOrientation == "boolean") {
+        correctOrientation = options.correctOrientation;
+    } else if (typeof options.correctOrientation == "number") {
+        correctOrientation = options.correctOrientation <=0 ? false : true;
+    }
+    var saveToPhotoAlbum = false;
+    if (typeof options.saveToPhotoAlbum == "boolean") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum;
+    } else if (typeof options.saveToPhotoAlbum == "number") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;
+    }
+    var popoverOptions = null;
+    if (typeof options.popoverOptions == "object") {
+        popoverOptions = options.popoverOptions;
+    }
+
+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+
+    exec(successCallback, errorCallback, "Camera", "takePicture", args);
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+    exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+
+});
+
+// file: lib\common\plugin\CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+
+module.exports = {
+  DestinationType:{
+    DATA_URL: 0,         // Return base64 encoded string
+    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)
+  },
+  EncodingType:{
+    JPEG: 0,             // Return JPEG encoded image
+    PNG: 1               // Return PNG encoded image
+  },
+  MediaType:{
+    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL
+    ALLMEDIA : 2         // allow selection from all media types
+  },
+  PictureSourceType:{
+    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+    CAMERA : 1,          // Take picture from camera
+    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
+  },
+  PopoverArrowDirection:{
+      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+      ARROW_DOWN : 2,
+      ARROW_LEFT : 4,
+      ARROW_RIGHT : 8,
+      ARROW_ANY : 15
+  }
+};
+
+});
+
+// file: lib\common\plugin\CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+    // information of rectangle that popover should be anchored to
+    this.x = x || 0;
+    this.y = y || 32;
+    this.width = width || 320;
+    this.height = height || 480;
+    // The direction of the popover arrow
+    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+
+});
+
+// file: lib\common\plugin\CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single sound clip in seconds.
+    this.duration = 0;
+    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureAudioOptions;
+
+});
+
+// file: lib\common\plugin\CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+   this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+
+});
+
+// file: lib\common\plugin\CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+    // Upper limit of images user can take. Value must be equal or greater than 1.
+    this.limit = 1;
+    // The selected image mode. Must match with one of the elements in supportedImageModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureImageOptions;
+
+});
+
+// file: lib\common\plugin\CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+    // Upper limit of videos user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single video clip in seconds.
+    this.duration = 0;
+    // The selected video mode. Must match with one of the elements in supportedVideoModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureVideoOptions;
+
+});
+
+// file: lib\common\plugin\CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+
+/**
+ *  CompassError.
+ *  An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var CompassError = function(err) {
+    this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+
+});
+
+// file: lib\common\plugin\CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);
+  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);
+  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);
+  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());
+};
+
+module.exports = CompassHeading;
+
+});
+
+// file: lib\common\plugin\ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+    // The ASCII-encoded string in lower case representing the media type.
+    this.type = null;
+    // The height attribute represents height of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0.
+    this.height = 0;
+    // The width attribute represents width of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0
+    this.width = 0;
+}
+
+module.exports = ConfigurationData;
+
+});
+
+// file: lib\common\plugin\Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+
+/**
+ * Network status
+ */
+module.exports = {
+        UNKNOWN: "unknown",
+        ETHERNET: "ethernet",
+        WIFI: "wifi",
+        CELL_2G: "2g",
+        CELL_3G: "3g",
+        CELL_4G: "4g",
+        NONE: "none"
+};
+
+});
+
+// file: lib\common\plugin\Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+    var value = contact.birthday;
+    try {
+      contact.birthday = new Date(parseFloat(value));
+    } catch (exception){
+      console.log("Cordova Contact convertIn error: exception creating date.");
+    }
+    return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+    var value = contact.birthday;
+    if (value !== null) {
+        // try to make it a Date object if it is not already
+        if (!utils.isDate(value)){
+            try {
+                value = new Date(value);
+            } catch(exception){
+                value = null;
+            }
+        }
+        if (utils.isDate(value)){
+            value = value.valueOf(); // convert to milliseconds
+        }
+        contact.birthday = value;
+    }
+    return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+    ims, organizations, birthday, note, photos, categories, urls) {
+    this.id = id || null;
+    this.rawId = null;
+    this.displayName = displayName || null;
+    this.name = name || null; // ContactName
+    this.nickname = nickname || null;
+    this.phoneNumbers = phoneNumbers || null; // ContactField[]
+    this.emails = emails || null; // ContactField[]
+    this.addresses = addresses || null; // ContactAddress[]
+    this.ims = ims || null; // ContactField[]
+    this.organizations = organizations || null; // ContactOrganization[]
+    this.birthday = birthday || null;
+    this.note = note || null;
+    this.photos = photos || null; // ContactField[]
+    this.categories = categories || null; // ContactField[]
+    this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+    var fail = function(code) {
+        errorCB(new ContactError(code));
+    };
+    if (this.id === null) {
+        fail(ContactError.UNKNOWN_ERROR);
+    }
+    else {
+        exec(successCB, fail, "Contacts", "remove", [this.id]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = utils.clone(this);
+    var i;
+    clonedContact.id = null;
+    clonedContact.rawId = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {
+            clonedContact.phoneNumbers[i].id = null;
+        }
+    }
+    if (clonedContact.emails) {
+        for (i = 0; i < clonedContact.emails.length; i++) {
+            clonedContact.emails[i].id = null;
+        }
+    }
+    if (clonedContact.addresses) {
+        for (i = 0; i < clonedContact.addresses.length; i++) {
+            clonedContact.addresses[i].id = null;
+        }
+    }
+    if (clonedContact.ims) {
+        for (i = 0; i < clonedContact.ims.length; i++) {
+            clonedContact.ims[i].id = null;
+        }
+    }
+    if (clonedContact.organizations) {
+        for (i = 0; i < clonedContact.organizations.length; i++) {
+            clonedContact.organizations[i].id = null;
+        }
+    }
+    if (clonedContact.categories) {
+        for (i = 0; i < clonedContact.categories.length; i++) {
+            clonedContact.categories[i].id = null;
+        }
+    }
+    if (clonedContact.photos) {
+        for (i = 0; i < clonedContact.photos.length; i++) {
+            clonedContact.photos[i].id = null;
+        }
+    }
+    if (clonedContact.urls) {
+        for (i = 0; i < clonedContact.urls.length; i++) {
+            clonedContact.urls[i].id = null;
+        }
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+  var fail = function(code) {
+      errorCB(new ContactError(code));
+  };
+    var success = function(result) {
+      if (result) {
+          if (typeof successCB === 'function') {
+              var fullContact = require('cordova/plugin/contacts').create(result);
+              successCB(convertIn(fullContact));
+          }
+      }
+      else {
+          // no Entry object returned
+          fail(ContactError.UNKNOWN_ERROR);
+      }
+  };
+    var dupContact = convertOut(utils.clone(this));
+    exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib\common\plugin\ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.formatted = formatted || null;
+    this.streetAddress = streetAddress || null;
+    this.locality = locality || null;
+    this.region = region || null;
+    this.postalCode = postalCode || null;
+    this.country = country || null;
+};
+
+module.exports = ContactAddress;
+
+});
+
+// file: lib\common\plugin\ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occurred
+ * @constructor
+ */
+var ContactError = function(err) {
+    this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+
+});
+
+// file: lib\common\plugin\ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+    this.id = null;
+    this.type = (type && type.toString()) || null;
+    this.value = (value && value.toString()) || null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+
+});
+
+// file: lib\common\plugin\ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+    this.filter = filter || '';
+    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+
+});
+
+// file: lib\common\plugin\ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+    this.formatted = formatted || null;
+    this.familyName = familyName || null;
+    this.givenName = givenName || null;
+    this.middleName = middle || null;
+    this.honorificPrefix = prefix || null;
+    this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+
+});
+
+// file: lib\common\plugin\ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.name = name || null;
+    this.department = dept || null;
+    this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+
+});
+
+// file: lib\common\plugin\Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+    /**
+     * The latitude of the position.
+     */
+    this.latitude = lat;
+    /**
+     * The longitude of the position,
+     */
+    this.longitude = lng;
+    /**
+     * The accuracy of the position.
+     */
+    this.accuracy = acc;
+    /**
+     * The altitude of the position.
+     */
+    this.altitude = (alt !== undefined ? alt : null);
+    /**
+     * The direction the device is moving at the position.
+     */
+    this.heading = (head !== undefined ? head : null);
+    /**
+     * The velocity with which the device is moving at the position.
+     */
+    this.speed = (vel !== undefined ? vel : null);
+
+    if (this.speed === 0 || this.speed === null) {
+        this.heading = NaN;
+    }
+
+    /**
+     * The altitude accuracy of the position.
+     */
+    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib\common\plugin\DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileError = require('cordova/plugin/FileError'),
+    DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+    return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or exclusively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or exclusively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var FileEntry = require('cordova/plugin/FileEntry');
+        var entry = new FileEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib\common\plugin\DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+    this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var retVal = [];
+        for (var i=0; i<result.length; i++) {
+            var entry = null;
+            if (result[i].isDirectory) {
+                entry = new (require('cordova/plugin/DirectoryEntry'))();
+            }
+            else if (result[i].isFile) {
+                entry = new (require('cordova/plugin/FileEntry'))();
+            }
+            entry.isDirectory = result[i].isDirectory;
+            entry.isFile = result[i].isFile;
+            entry.name = result[i].name;
+            entry.fullPath = result[i].fullPath;
+            retVal.push(entry);
+        }
+        successCallback(retVal);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib\common\plugin\Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ *            {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ *            {boolean} true if Entry is a directory (readonly)
+ * @param name
+ *            {DOMString} name of the file or directory, excluding the path
+ *            leading to it (readonly)
+ * @param fullPath
+ *            {DOMString} the absolute full path to the file or directory
+ *            (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+    this.isFile = (typeof isFile != 'undefined'?isFile:false);
+    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);
+    this.name = name || '';
+    this.fullPath = fullPath || '';
+    this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+  var success = typeof successCallback !== 'function' ? null : function(lastModified) {
+      var metadata = new Metadata(lastModified);
+      successCallback(metadata);
+  };
+  var fail = typeof errorCallback !== 'function' ? null : function(code) {
+      errorCallback(new FileError(code));
+  };
+
+  exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ * @param metadataObject
+ *            {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+
+  exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+    // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new Entry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+
+        // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        // success callback
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+    // fullPath attribute contains the full URL
+    return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+    console.log("DEPRECATED: Update your code to use 'toURL'");
+    // fullPath attribute contains the full URI
+    return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+
+});
+
+// file: lib\common\plugin\File.js
+define("cordova/plugin/File", function(require, exports, module) {
+
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+    this.name = name || '';
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+};
+
+module.exports = File;
+
+});
+
+// file: lib\common\plugin\FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileWriter = require('cordova/plugin/FileWriter'),
+    File = require('cordova/plugin/File'),
+    FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+    this.file(function(filePointer) {
+        var writer = new FileWriter(filePointer);
+
+        if (writer.fileName === null || writer.fileName === "") {
+            if (typeof errorCallback === "function") {
+                errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+            }
+        } else {
+            if (typeof successCallback === "function") {
+                successCallback(writer);
+            }
+        }
+    }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(f) {
+        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+        successCallback(file);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+
+});
+
+// file: lib\common\plugin\FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+
+/**
+ * FileError
+ */
+function FileError(error) {
+  this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+
+});
+
+// file: lib\common\plugin\FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+    this.fileName = "";
+
+    this.readyState = 0; // FileReader.EMPTY
+
+    // File data
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onloadstart = null;    // When the read starts.
+    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
+    this.onload = null;         // When the read has successfully completed.
+    this.onerror = null;        // When the read has failed (see errors).
+    this.onloadend = null;      // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+    this.result = null;
+
+    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {
+      return;
+    }
+
+    this.readyState = FileReader.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === 'function') {
+        this.onabort(new ProgressEvent('abort', {target:this}));
+    }
+    // If load end callback
+    if (typeof this.onloadend === 'function') {
+        this.onloadend(new ProgressEvent('loadend', {target:this}));
+    }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file          {File} File object containing file properties
+ * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+    // Figure out pathing
+    this.fileName = '';
+    if (typeof file.fullPath === 'undefined') {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    // Default encoding is UTF-8
+    var enc = encoding ? encoding : "UTF-8";
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // null result
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsText", [this.fileName, enc]);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ *      data:[<mediatype>][;base64],<data>
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+    this.fileName = "";
+    if (typeof file.fullPath === "undefined") {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsDataURL", [this.fileName]);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('method "readAsBinaryString" is not supported at this time.');
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('This method is not supported at this time.');
+};
+
+module.exports = FileReader;
+
+});
+
+// file: lib\common\plugin\FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+    this.name = name || null;
+    if (root) {
+        this.root = new DirectoryEntry(root.name, root.fullPath);
+    }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib\common\plugin\FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    FileTransferError = require('cordova/plugin/FileTransferError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+function newProgressEvent(result) {
+    var pe = new ProgressEvent();
+    pe.lengthComputable = result.lengthComputable;
+    pe.loaded = result.loaded;
+    pe.total = result.total;
+    return pe;
+}
+
+var idCounter = 0;
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {
+    this._id = ++idCounter;
+    this.onprogress = null; // optional callback
+};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String}           Full path of the file on the device
+* @param server {String}             URL of the server to receive the file
+* @param successCallback (Function}  Callback to be invoked when upload has completed
+* @param errorCallback {Function}    Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+    // sanity parameter checking
+    if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
+    // check for options
+    var fileKey = null;
+    var fileName = null;
+    var mimeType = null;
+    var params = null;
+    var chunkedMode = true;
+    var headers = null;
+    if (options) {
+        fileKey = options.fileKey;
+        fileName = options.fileName;
+        mimeType = options.mimeType;
+        headers = options.headers;
+        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+            chunkedMode = options.chunkedMode;
+        }
+        if (options.params) {
+            params = options.params;
+        }
+        else {
+            params = {};
+        }
+    }
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    var self = this;
+    var win = function(result) {
+        if (typeof result.lengthComputable != "undefined") {
+            if (self.onprogress) {
+                return self.onprogress(newProgressEvent(result));
+            }
+        } else {
+            return successCallback(result);
+        }
+    };
+    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String}          URL of the server to receive the file
+ * @param target {String}         Full path of the file on the device
+ * @param successCallback (Function}  Callback to be invoked when upload has completed
+ * @param errorCallback {Function}    Callback to be invoked upon error
+ * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts) {
+    // sanity parameter checking
+    if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
+    var self = this;
+    var win = function(result) {
+        if (typeof result.lengthComputable != "undefined") {
+            if (self.onprogress) {
+                return self.onprogress(newProgressEvent(result));
+            }
+        } else {
+            var entry = null;
+            if (result.isDirectory) {
+                entry = new (require('cordova/plugin/DirectoryEntry'))();
+            }
+            else if (result.isFile) {
+                entry = new (require('cordova/plugin/FileEntry'))();
+            }
+            entry.isDirectory = result.isDirectory;
+            entry.isFile = result.isFile;
+            entry.name = result.name;
+            entry.fullPath = result.fullPath;
+            successCallback(entry);
+        }
+    };
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(win, errorCallback, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id]);
+};
+
+/**
+ * Aborts the ongoing file transfer on this object
+ * @param successCallback {Function}  Callback to be invoked upon success
+ * @param errorCallback {Function}    Callback to be invoked upon error
+ */
+FileTransfer.prototype.abort = function(successCallback, errorCallback) {
+    exec(successCallback, errorCallback, 'FileTransfer', 'abort', [this._id]);
+};
+
+module.exports = FileTransfer;
+
+});
+
+// file: lib\common\plugin\FileTransferError.js
+define("cordova/plugin/FileTransferError", function(require, exports, module) {
+
+/**
+ * FileTransferError
+ * @constructor
+ */
+var FileTransferError = function(code, source, target, status) {
+    this.code = code || null;
+    this.source = source || null;
+    this.target = target || null;
+    this.http_status = status || null;
+};
+
+FileTransferError.FILE_NOT_FOUND_ERR = 1;
+FileTransferError.INVALID_URL_ERR = 2;
+FileTransferError.CONNECTION_ERR = 3;
+FileTransferError.ABORT_ERR = 4;
+
+module.exports = FileTransferError;
+
+});
+
+// file: lib\common\plugin\FileUploadOptions.js
+define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
+
+/**
+ * Options to customize the HTTP request used to upload files.
+ * @constructor
+ * @param fileKey {String}   Name of file request parameter.
+ * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
+ * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
+ * @param params {Object}    Object with key: value params to send to the server.
+ * @param headers {Object}   Keys are header names, values are header values. Multiple
+ *                           headers of the same name are not supported.
+ */
+var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers) {
+    this.fileKey = fileKey || null;
+    this.fileName = fileName || null;
+    this.mimeType = mimeType || null;
+    this.params = params || null;
+    this.headers = headers || null;
+};
+
+module.exports = FileUploadOptions;
+
+});
+
+// file: lib\common\plugin\FileUploadResult.js
+define("cordova/plugin/FileUploadResult", function(require, exports, module) {
+
+/**
+ * FileUploadResult
+ * @constructor
+ */
+var FileUploadResult = function() {
+    this.bytesSent = 0;
+    this.responseCode = null;
+    this.response = null;
+};
+
+module.exports = FileUploadResult;
+
+});
+
+// file: lib\common\plugin\FileWriter.js
+define("cordova/plugin/FileWriter", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class writes to the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To write to the SD card, the file name is "sdcard/my_file.txt"
+ *
+ * @constructor
+ * @param file {File} File object containing file properties
+ * @param append if true write to the end of the file, otherwise overwrite the file
+ */
+var FileWriter = function(file) {
+    this.fileName = "";
+    this.length = 0;
+    if (file) {
+        this.fileName = file.fullPath || file;
+        this.length = file.size || 0;
+    }
+    // default is to write at the beginning of the file
+    this.position = 0;
+
+    this.readyState = 0; // EMPTY
+
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onwritestart = null;   // When writing starts
+    this.onprogress = null;     // While writing the file, and reporting partial file data
+    this.onwrite = null;        // When the write has successfully completed.
+    this.onwriteend = null;     // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.
+    this.onerror = null;        // When the write has failed (see errors).
+};
+
+// States
+FileWriter.INIT = 0;
+FileWriter.WRITING = 1;
+FileWriter.DONE = 2;
+
+/**
+ * Abort writing file.
+ */
+FileWriter.prototype.abort = function() {
+    // check for invalid state
+    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // set error
+    this.error = new FileError(FileError.ABORT_ERR);
+
+    this.readyState = FileWriter.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === "function") {
+        this.onabort(new ProgressEvent("abort", {"target":this}));
+    }
+
+    // If write end callback
+    if (typeof this.onwriteend === "function") {
+        this.onwriteend(new ProgressEvent("writeend", {"target":this}));
+    }
+};
+
+/**
+ * Writes data to the file
+ *
+ * @param text to be written
+ */
+FileWriter.prototype.write = function(text) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // position always increases by bytes written because file would be extended
+            me.position += r;
+            // The length of the file is now where we are done writing.
+
+            me.length = me.position;
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "write", [this.fileName, text, this.position]);
+};
+
+/**
+ * Moves the file pointer to the location specified.
+ *
+ * If the offset is a negative number the position of the file
+ * pointer is rewound.  If the offset is greater than the file
+ * size the position is set to the end of the file.
+ *
+ * @param offset is the location to move the file pointer to.
+ */
+FileWriter.prototype.seek = function(offset) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    if (!offset && offset !== 0) {
+        return;
+    }
+
+    // See back from end of file.
+    if (offset < 0) {
+        this.position = Math.max(offset + this.length, 0);
+    }
+    // Offset is bigger than file size so set position
+    // to the end of the file.
+    else if (offset > this.length) {
+        this.position = this.length;
+    }
+    // Offset is between 0 and file size so set the position
+    // to start writing.
+    else {
+        this.position = offset;
+    }
+};
+
+/**
+ * Truncates the file to the size specified.
+ *
+ * @param size to chop the file at.
+ */
+FileWriter.prototype.truncate = function(size) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Update the length of the file
+            me.length = r;
+            me.position = Math.min(me.position, r);
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "truncate", [this.fileName, size]);
+};
+
+module.exports = FileWriter;
+
+});
+
+// file: lib\common\plugin\Flags.js
+define("cordova/plugin/Flags", function(require, exports, module) {
+
+/**
+ * Supplies arguments to methods that lookup or create files and directories.
+ *
+ * @param create
+ *            {boolean} file or directory if it doesn't exist
+ * @param exclusive
+ *            {boolean} used with create; if true the command will fail if
+ *            target path exists
+ */
+function Flags(create, exclusive) {
+    this.create = create || false;
+    this.exclusive = exclusive || false;
+}
+
+module.exports = Flags;
+
+});
+
+// file: lib\common\plugin\GlobalizationError.js
+define("cordova/plugin/GlobalizationError", function(require, exports, module) {
+
+
+/**
+ * Globalization error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var GlobalizationError = function(code, message) {
+    this.code = code || null;
+    this.message = message || '';
+};
+
+// Globalization error codes
+GlobalizationError.UNKNOWN_ERROR = 0;
+GlobalizationError.FORMATTING_ERROR = 1;
+GlobalizationError.PARSING_ERROR = 2;
+GlobalizationError.PATTERN_ERROR = 3;
+
+module.exports = GlobalizationError;
+
+});
+
+// file: lib\common\plugin\LocalFileSystem.js
+define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+/**
+ * Represents a local file system.
+ */
+var LocalFileSystem = function() {
+
+};
+
+LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
+LocalFileSystem.PERSISTENT = 1; //persistent
+
+module.exports = LocalFileSystem;
+
+});
+
+// file: lib\common\plugin\Media.js
+define("cordova/plugin/Media", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src                   The file name or url to play
+ * @param successCallback       The callback to be called when the file is done playing or recording.
+ *                                  successCallback()
+ * @param errorCallback         The callback to be called if there is an error.
+ *                                  errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback        The callback to be called when media status has changed.
+ *                                  statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+
+    // successCallback optional
+    if (successCallback && (typeof successCallback !== "function")) {
+        console.log("Media Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Media Error: errorCallback is not a function");
+        return;
+    }
+
+    // statusCallback optional
+    if (statusCallback && (typeof statusCallback !== "function")) {
+        console.log("Media Error: statusCallback is not a function");
+        return;
+    }
+
+    this.id = utils.createUUID();
+    mediaObjects[this.id] = this;
+    this.src = src;
+    this.successCallback = successCallback;
+    this.errorCallback = errorCallback;
+    this.statusCallback = statusCallback;
+    this._duration = -1;
+    this._position = -1;
+    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+    return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function(options) {
+    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+    var me = this;
+    exec(function() {
+        me._position = 0;
+    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return      duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+    return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+        success(p);
+    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+    exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+    exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+    exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+    exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id            The media object id (string)
+ * @param msgType       The 'type' of update this is
+ * @param value         Use of value is determined by the msgType
+ */
+Media.onStatus = function(id, msgType, value) {
+
+    var media = mediaObjects[id];
+
+    if(media) {
+        switch(msgType) {
+            case Media.MEDIA_STATE :
+                media.statusCallback && media.statusCallback(value);
+                if(value == Media.MEDIA_STOPPED) {
+                    media.successCallback && media.successCallback();
+                }
+                break;
+            case Media.MEDIA_DURATION :
+                media._duration = value;
+                break;
+            case Media.MEDIA_ERROR :
+                media.errorCallback && media.errorCallback(value);
+                break;
+            case Media.MEDIA_POSITION :
+                media._position = Number(value);
+                break;
+            default :
+                console && console.error && console.error("Unhandled Media.onStatus :: " + msgType);
+                break;
+        }
+    }
+    else {
+         console && console.error && console.error("Received Media.onStatus callback for unknown media :: " + id);
+    }
+
+};
+
+module.exports = Media;
+
+});
+
+// file: lib\common\plugin\MediaError.js
+define("cordova/plugin/MediaError", function(require, exports, module) {
+
+/**
+ * This class contains information about any Media errors.
+*/
+/*
+ According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror
+ We should never be creating these objects, we should just implement the interface
+ which has 1 property for an instance, 'code'
+
+ instead of doing :
+    errorCallbackFunction( new MediaError(3,'msg') );
+we should simply use a literal :
+    errorCallbackFunction( {'code':3} );
+ */
+
+ var _MediaError = window.MediaError;
+
+
+if(!_MediaError) {
+    window.MediaError = _MediaError = function(code, msg) {
+        this.code = (typeof code != 'undefined') ? code : null;
+        this.message = msg || ""; // message is NON-standard! do not use!
+    };
+}
+
+_MediaError.MEDIA_ERR_NONE_ACTIVE    = _MediaError.MEDIA_ERR_NONE_ACTIVE    || 0;
+_MediaError.MEDIA_ERR_ABORTED        = _MediaError.MEDIA_ERR_ABORTED        || 1;
+_MediaError.MEDIA_ERR_NETWORK        = _MediaError.MEDIA_ERR_NETWORK        || 2;
+_MediaError.MEDIA_ERR_DECODE         = _MediaError.MEDIA_ERR_DECODE         || 3;
+_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;
+// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.
+// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes
+_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;
+
+module.exports = _MediaError;
+
+});
+
+// file: lib\common\plugin\MediaFile.js
+define("cordova/plugin/MediaFile", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    File = require('cordova/plugin/File'),
+    CaptureError = require('cordova/plugin/CaptureError');
+/**
+ * Represents a single file.
+ *
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
+    MediaFile.__super__.constructor.apply(this, arguments);
+};
+
+utils.extend(MediaFile, File);
+
+/**
+ * Request capture format data for a specific file and type
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
+    } else {
+        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
+    }
+};
+
+module.exports = MediaFile;
+
+});
+
+// file: lib\common\plugin\MediaFileData.js
+define("cordova/plugin/MediaFileData", function(require, exports, module) {
+
+/**
+ * MediaFileData encapsulates format information of a media file.
+ *
+ * @param {DOMString} codecs
+ * @param {long} bitrate
+ * @param {long} height
+ * @param {long} width
+ * @param {float} duration
+ */
+var MediaFileData = function(codecs, bitrate, height, width, duration){
+    this.codecs = codecs || null;
+    this.bitrate = bitrate || 0;
+    this.height = height || 0;
+    this.width = width || 0;
+    this.duration = duration || 0;
+};
+
+module.exports = MediaFileData;
+
+});
+
+// file: lib\common\plugin\Metadata.js
+define("cordova/plugin/Metadata", function(require, exports, module) {
+
+/**
+ * Information about the state of the file or directory
+ *
+ * {Date} modificationTime (readonly)
+ */
+var Metadata = function(time) {
+    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
+};
+
+module.exports = Metadata;
+
+});
+
+// file: lib\common\plugin\Position.js
+define("cordova/plugin/Position", function(require, exports, module) {
+
+var Coordinates = require('cordova/plugin/Coordinates');
+
+var Position = function(coords, timestamp) {
+    if (coords) {
+        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
+    } else {
+        this.coords = new Coordinates();
+    }
+    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
+};
+
+module.exports = Position;
+
+});
+
+// file: lib\common\plugin\PositionError.js
+define("cordova/plugin/PositionError", function(require, exports, module) {
+
+/**
+ * Position error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var PositionError = function(code, message) {
+    this.code = code || null;
+    this.message = message || '';
+};
+
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+
+module.exports = PositionError;
+
+});
+
+// file: lib\common\plugin\ProgressEvent.js
+define("cordova/plugin/ProgressEvent", function(require, exports, module) {
+
+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
+// Feature test: See if we can instantiate a native ProgressEvent;
+// if so, use that approach,
+// otherwise fill-in with our own implementation.
+//
+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
+var ProgressEvent = (function() {
+    /*
+    var createEvent = function(data) {
+        var event = document.createEvent('Events');
+        event.initEvent('ProgressEvent', false, false);
+        if (data) {
+            for (var i in data) {
+                if (data.hasOwnProperty(i)) {
+                    event[i] = data[i];
+                }
+            }
+            if (data.target) {
+                // TODO: cannot call <some_custom_object>.dispatchEvent
+                // need to first figure out how to implement EventTarget
+            }
+        }
+        return event;
+    };
+    try {
+        var ev = createEvent({type:"abort",target:document});
+        return function ProgressEvent(type, data) {
+            data.type = type;
+            return createEvent(data);
+        };
+    } catch(e){
+    */
+        return function ProgressEvent(type, dict) {
+            this.type = type;
+            this.bubbles = false;
+            this.cancelBubble = false;
+            this.cancelable = false;
+            this.lengthComputable = false;
+            this.loaded = dict && dict.loaded ? dict.loaded : 0;
+            this.total = dict && dict.total ? dict.total : 0;
+            this.target = dict && dict.target ? dict.target : null;
+        };
+    //}
+})();
+
+module.exports = ProgressEvent;
+
+});
+
+// file: lib\common\plugin\accelerometer.js
+define("cordova/plugin/accelerometer", function(require, exports, module) {
+
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+var utils = require("cordova/utils"),
+    exec = require("cordova/exec"),
+    Acceleration = require('cordova/plugin/Acceleration');
+
+// Is the accel sensor running?
+var running = false;
+
+// Keeps reference to watchAcceleration calls.
+var timers = {};
+
+// Array of listeners; used to keep track of when we should call start and stop.
+var listeners = [];
+
+// Last returned acceleration object from native
+var accel = null;
+
+// Tells native to start.
+function start() {
+    exec(function(a) {
+        var tempListeners = listeners.slice(0);
+        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].win(accel);
+        }
+    }, function(e) {
+        var tempListeners = listeners.slice(0);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].fail(e);
+        }
+    }, "Accelerometer", "start", []);
+    running = true;
+}
+
+// Tells native to stop.
+function stop() {
+    exec(null, null, "Accelerometer", "stop", []);
+    running = false;
+}
+
+// Adds a callback pair to the listeners array
+function createCallbackPair(win, fail) {
+    return {win:win, fail:fail};
+}
+
+// Removes a win/fail listener pair from the listeners array
+function removeListeners(l) {
+    var idx = listeners.indexOf(l);
+    if (idx > -1) {
+        listeners.splice(idx, 1);
+        if (listeners.length === 0) {
+            stop();
+        }
+    }
+}
+
+var accelerometer = {
+    /**
+     * Asynchronously acquires the current acceleration.
+     *
+     * @param {Function} successCallback    The function to call when the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     */
+    getCurrentAcceleration: function(successCallback, errorCallback, options) {
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "getCurrentAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        var p;
+        var win = function(a) {
+            removeListeners(p);
+            successCallback(a);
+        };
+        var fail = function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        };
+
+        p = createCallbackPair(win, fail);
+        listeners.push(p);
+
+        if (!running) {
+            start();
+        }
+    },
+
+    /**
+     * Asynchronously acquires the acceleration repeatedly at a given interval.
+     *
+     * @param {Function} successCallback    The function to call each time the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchAcceleration: function(successCallback, errorCallback, options) {
+        // Default interval (10 sec)
+        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
+
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "watchAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        // Keep reference to watch id, and report accel readings as often as defined in frequency
+        var id = utils.createUUID();
+
+        var p = createCallbackPair(function(){}, function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        });
+        listeners.push(p);
+
+        timers[id] = {
+            timer:window.setInterval(function() {
+                if (accel) {
+                    successCallback(accel);
+                }
+            }, frequency),
+            listeners:p
+        };
+
+        if (running) {
+            // If we're already running then immediately invoke the success callback
+            // but only if we have retrieved a value, sample code does not check for null ...
+            if(accel) {
+                successCallback(accel);
+            }
+        } else {
+            start();
+        }
+
+        return id;
+    },
+
+    /**
+     * Clears the specified accelerometer watch.
+     *
+     * @param {String} id       The id of the watch returned from #watchAcceleration.
+     */
+    clearWatch: function(id) {
+        // Stop javascript timer & remove from timer list
+        if (id && timers[id]) {
+            window.clearInterval(timers[id].timer);
+            removeListeners(timers[id].listeners);
+            delete timers[id];
+        }
+    }
+};
+
+module.exports = accelerometer;
+
+});
+
+// file: lib\common\plugin\battery.js
+define("cordova/plugin/battery", function(require, exports, module) {
+
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var cordova = require('cordova'),
+    exec = require('cordova/exec');
+
+function handlers() {
+  return battery.channels.batterystatus.numHandlers +
+         battery.channels.batterylow.numHandlers +
+         battery.channels.batterycritical.numHandlers;
+}
+
+var Battery = function() {
+    this._level = null;
+    this._isPlugged = null;
+    // Create new event handlers on the window (returns a channel instance)
+    this.channels = {
+      batterystatus:cordova.addWindowEventHandler("batterystatus"),
+      batterylow:cordova.addWindowEventHandler("batterylow"),
+      batterycritical:cordova.addWindowEventHandler("batterycritical")
+    };
+    for (var key in this.channels) {
+        this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange;
+    }
+};
+/**
+ * Event handlers for when callbacks get registered for the battery.
+ * Keep track of how many handlers we have so we can start and stop the native battery listener
+ * appropriately (and hopefully save on battery life!).
+ */
+Battery.onHasSubscribersChange = function() {
+  // If we just registered the first handler, make sure native listener is started.
+  if (this.numHandlers === 1 && handlers() === 1) {
+      exec(battery._status, battery._error, "Battery", "start", []);
+  } else if (handlers() === 0) {
+      exec(null, null, "Battery", "stop", []);
+  }
+};
+
+/**
+ * Callback for battery status
+ *
+ * @param {Object} info            keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+    if (info) {
+        var me = battery;
+    var level = info.level;
+        if (me._level !== level || me._isPlugged !== info.isPlugged) {
+            // Fire batterystatus event
+            cordova.fireWindowEvent("batterystatus", info);
+
+            // Fire low battery event
+            if (level === 20 || level === 5) {
+                if (level === 20) {
+                    cordova.fireWindowEvent("batterylow", info);
+                }
+                else {
+                    cordova.fireWindowEvent("batterycritical", info);
+                }
+            }
+        }
+        me._level = level;
+        me._isPlugged = info.isPlugged;
+    }
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+    console.log("Error initializing Battery: " + e);
+};
+
+var battery = new Battery();
+
+module.exports = battery;
+
+});
+
+// file: lib\common\plugin\capture.js
+define("cordova/plugin/capture", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    MediaFile = require('cordova/plugin/MediaFile');
+
+/**
+ * Launches a capture of different types.
+ *
+ * @param (DOMString} type
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+function _capture(type, successCallback, errorCallback, options) {
+    var win = function(pluginResult) {
+        var mediaFiles = [];
+        var i;
+        for (i = 0; i < pluginResult.length; i++) {
+            var mediaFile = new MediaFile();
+            mediaFile.name = pluginResult[i].name;
+            mediaFile.fullPath = pluginResult[i].fullPath;
+            mediaFile.type = pluginResult[i].type;
+            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
+            mediaFile.size = pluginResult[i].size;
+            mediaFiles.push(mediaFile);
+        }
+        successCallback(mediaFiles);
+    };
+    exec(win, errorCallback, "Capture", type, [options]);
+}
+/**
+ * The Capture interface exposes an interface to the camera and microphone of the hosting device.
+ */
+function Capture() {
+    this.supportedAudioModes = [];
+    this.supportedImageModes = [];
+    this.supportedVideoModes = [];
+}
+
+/**
+ * Launch audio recorder application for recording audio clip(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureAudioOptions} options
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
+    _capture("captureAudio", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options){
+    _capture("captureImage", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch device camera application for recording video(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
+    _capture("captureVideo", successCallback, errorCallback, options);
+};
+
+
+module.exports = new Capture();
+
+});
+
+// file: lib\common\plugin\compass.js
+define("cordova/plugin/compass", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    utils = require('cordova/utils'),
+    CompassHeading = require('cordova/plugin/CompassHeading'),
+    CompassError = require('cordova/plugin/CompassError'),
+    timers = {},
+    compass = {
+        /**
+         * Asynchronously acquires the current heading.
+         * @param {Function} successCallback The function to call when the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {CompassOptions} options The options for getting the heading data (not used).
+         */
+        getCurrentHeading:function(successCallback, errorCallback, options) {
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var win = function(result) {
+                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
+                successCallback(ch);
+            };
+            var fail = function(code) {
+                var ce = new CompassError(code);
+                errorCallback(ce);
+            };
+
+            // Get heading
+            exec(win, fail, "Compass", "getHeading", [options]);
+        },
+
+        /**
+         * Asynchronously acquires the heading repeatedly at a given interval.
+         * @param {Function} successCallback The function to call each time the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {HeadingOptions} options The options for getting the heading data
+         * such as timeout and the frequency of the watch. For iOS, filter parameter
+         * specifies to watch via a distance filter rather than time.
+         */
+        watchHeading:function(successCallback, errorCallback, options) {
+            // Default interval (100 msec)
+            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
+            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
+
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var id = utils.createUUID();
+            if (filter > 0) {
+                // is an iOS request for watch by filter, no timer needed
+                timers[id] = "iOS";
+                compass.getCurrentHeading(successCallback, errorCallback, options);
+            } else {
+                // Start watch timer to get headings
+                timers[id] = window.setInterval(function() {
+                    compass.getCurrentHeading(successCallback, errorCallback);
+                }, frequency);
+            }
+
+            return id;
+        },
+
+        /**
+         * Clears the specified heading watch.
+         * @param {String} watchId The ID of the watch returned from #watchHeading.
+         */
+        clearWatch:function(id) {
+            // Stop javascript timer & remove from timer list
+            if (id && timers[id]) {
+                if (timers[id] != "iOS") {
+                      clearInterval(timers[id]);
+                  } else {
+                    // is iOS watch by filter so call into device to stop
+                    exec(null, null, "Compass", "stopHeading", []);
+                }
+                delete timers[id];
+            }
+        }
+    };
+
+module.exports = compass;
+
+});
+
+// file: lib\common\plugin\console-via-logger.js
+define("cordova/plugin/console-via-logger", function(require, exports, module) {
+
+//------------------------------------------------------------------------------
+
+var logger = require("cordova/plugin/logger");
+var utils  = require("cordova/utils");
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrappedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrappedOrigCall(WinConsole[key], console[key]);
+    }
+}
+
+});
+
+// file: lib\common\plugin\contacts.js
+define("cordova/plugin/contacts", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+* Represents a group of Contacts.
+* @constructor
+*/
+var contacts = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     * @param fields that should be searched
+     * @param successCB success callback
+     * @param errorCB error callback
+     * @param {ContactFindOptions} options that can be applied to contact searching
+     * @return array of Contacts matching search criteria
+     */
+    find:function(fields, successCB, errorCB, options) {
+        if (!successCB) {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+        if (!fields || (utils.isArray(fields) && fields.length === 0)) {
+            if (typeof errorCB === "function") {
+                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+        } else {
+            var win = function(result) {
+                var cs = [];
+                for (var i = 0, l = result.length; i < l; i++) {
+                    cs.push(contacts.create(result[i]));
+                }
+                successCB(cs);
+            };
+            exec(win, errorCB, "Contacts", "search", [fields, options]);
+        }
+    },
+
+    /**
+     * This function creates a new contact, but it does not persist the contact
+     * to device storage. To persist the contact to device storage, invoke
+     * contact.save().
+     * @param properties an object whose properties will be examined to create a new Contact
+     * @returns new Contact object
+     */
+    create:function(properties) {
+        var i;
+        var contact = new Contact();
+        for (i in properties) {
+            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
+                contact[i] = properties[i];
+            }
+        }
+        return contact;
+    }
+};
+
+module.exports = contacts;
+
+});
+
+// file: lib\common\plugin\device.js
+define("cordova/plugin/device", function(require, exports, module) {
+
+var channel = require('cordova/channel'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+    this.available = false;
+    this.platform = null;
+    this.version = null;
+    this.name = null;
+    this.uuid = null;
+    this.cordova = null;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribe(function() {
+        me.getInfo(function(info) {
+            me.available = true;
+            me.platform = info.platform;
+            me.version = info.version;
+            me.name = info.name;
+            me.uuid = info.uuid;
+            me.cordova = info.cordova;
+            channel.onCordovaInfoReady.fire();
+        },function(e) {
+            me.available = false;
+            utils.alert("[ERROR] Error initializing Cordova: " + e);
+        });
+    });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Device Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Device Error: errorCallback is not a function");
+        return;
+    }
+
+    // Get info
+    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib\common\plugin\echo.js
+define("cordova/plugin/echo", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+/**
+ * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
+ * @param successCallback  invoked with a FileSystem object
+ * @param errorCallback  invoked if error occurs retrieving file system
+ * @param message  The string to be echoed.
+ * @param forceAsync  Whether to force an async return value (for testing native->js bridge).
+ */
+module.exports = function(successCallback, errorCallback, message, forceAsync) {
+    var action = forceAsync ? 'echoAsync' : 'echo';
+    exec(successCallback, errorCallback, "Echo", action, [message]);
+};
+
+
+});
+
+// file: lib\common\plugin\geolocation.js
+define("cordova/plugin/geolocation", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    PositionError = require('cordova/plugin/PositionError'),
+    Position = require('cordova/plugin/Position');
+
+var timers = {};   // list of timers in use
+
+// Returns default params, overrides if provided with values
+function parseParameters(options) {
+    var opt = {
+        maximumAge: 0,
+        enableHighAccuracy: false,
+        timeout: Infinity
+    };
+
+    if (options) {
+        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
+            opt.maximumAge = options.maximumAge;
+        }
+        if (options.enableHighAccuracy !== undefined) {
+            opt.enableHighAccuracy = options.enableHighAccuracy;
+        }
+        if (options.timeout !== undefined && !isNaN(options.timeout)) {
+            if (options.timeout < 0) {
+                opt.timeout = 0;
+            } else {
+                opt.timeout = options.timeout;
+            }
+        }
+    }
+
+    return opt;
+}
+
+// Returns a timeout failure, closed over a specified timeout value and error callback.
+function createTimeout(errorCallback, timeout) {
+    var t = setTimeout(function() {
+        clearTimeout(t);
+        t = null;
+        errorCallback({
+            code:PositionError.TIMEOUT,
+            message:"Position retrieval timed out."
+        });
+    }, timeout);
+    return t;
+}
+
+var geolocation = {
+    lastPosition:null, // reference to last known (cached) position returned
+    /**
+   * Asynchronously acquires the current position.
+   *
+   * @param {Function} successCallback    The function to call when the position data is available
+   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
+   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
+   */
+    getCurrentPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("getCurrentPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        // Timer var that will fire an error callback if no position is retrieved from native
+        // before the "timeout" param provided expires
+        var timeoutTimer = {timer:null};
+
+        var win = function(p) {
+            clearTimeout(timeoutTimer.timer);
+            if (!(timeoutTimer.timer)) {
+                // Timeout already happened, or native fired error callback for
+                // this geo request.
+                // Don't continue with success callback.
+                return;
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+        var fail = function(e) {
+            clearTimeout(timeoutTimer.timer);
+            timeoutTimer.timer = null;
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
+        // fire the success callback with the cached position.
+        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
+            successCallback(geolocation.lastPosition);
+        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
+        } else if (options.timeout === 0) {
+            fail({
+                code:PositionError.TIMEOUT,
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."
+            });
+        // Otherwise we have to call into native to retrieve a position.
+        } else {
+            if (options.timeout !== Infinity) {
+                // If the timeout value was not set to Infinity (default), then
+                // set up a timeout function that will fire the error callback
+                // if no successful position was retrieved before timeout expired.
+                timeoutTimer.timer = createTimeout(fail, options.timeout);
+            } else {
+                // This is here so the check in the win function doesn't mess stuff up
+                // may seem weird but this guarantees timeoutTimer is
+                // always truthy before we call into native
+                timeoutTimer.timer = true;
+            }
+            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
+        }
+        return timeoutTimer;
+    },
+    /**
+     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
+     * the successCallback is called with the new location.
+     *
+     * @param {Function} successCallback    The function to call each time the location data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
+     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("watchPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        var id = utils.createUUID();
+
+        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
+        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
+
+        var fail = function(e) {
+            clearTimeout(timers[id].timer);
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        var win = function(p) {
+            clearTimeout(timers[id].timer);
+            if (options.timeout !== Infinity) {
+                timers[id].timer = createTimeout(fail, options.timeout);
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+
+        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
+
+        return id;
+    },
+    /**
+     * Clears the specified heading watch.
+     *
+     * @param {String} id       The ID of the watch returned from #watchPosition
+     */
+    clearWatch:function(id) {
+        if (id && timers[id] !== undefined) {
+            clearTimeout(timers[id].timer);
+            timers[id].timer = false;
+            exec(null, null, "Geolocation", "clearWatch", [id]);
+        }
+    }
+};
+
+module.exports = geolocation;
+
+});
+
+// file: lib\common\plugin\globalization.js
+define("cordova/plugin/globalization", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    GlobalizationError = require('cordova/plugin/GlobalizationError');
+
+var globalization = {
+
+/**
+* Returns the string identifier for the client's current language.
+* It returns the language identifier string to the successCB callback with a
+* properties object as a parameter. If there is an error getting the language,
+* then the errorCB callback is invoked.
+*
+* @param {Function} successCB
+* @param {Function} errorCB
+*
+* @return Object.value {String}: The language identifier
+*
+* @error GlobalizationError.UNKNOWN_ERROR
+*
+* Example
+*    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},
+*                                function () {});
+*/
+getPreferredLanguage:function(successCB, failureCB) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getPreferredLanguage Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getPreferredLanguage Error: failureCB is not a function");
+        return;
+    }
+
+    exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);
+},
+
+/**
+* Returns the string identifier for the client's current locale setting.
+* It returns the locale identifier string to the successCB callback with a
+* properties object as a parameter. If there is an error getting the locale,
+* then the errorCB callback is invoked.
+*
+* @param {Function} successCB
+* @param {Function} errorCB
+*
+* @return Object.value {String}: The locale identifier
+*
+* @error GlobalizationError.UNKNOWN_ERROR
+*
+* Example
+*    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},
+*                                function () {});
+*/
+getLocaleName:function(successCB, failureCB) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getLocaleName Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getLocaleName Error: failureCB is not a function");
+        return;
+    }
+    exec(successCB, failureCB, "Globalization","getLocaleName", []);
+},
+
+
+/**
+* Returns a date formatted as a string according to the client's user preferences and
+* calendar using the time zone of the client. It returns the formatted date string to the
+* successCB callback with a properties object as a parameter. If there is an error
+* formatting the date, then the errorCB callback is invoked.
+*
+* The defaults are: formatLenght="short" and selector="date and time"
+*
+* @param {Date} date
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            formatLength {String}: 'short', 'medium', 'long', or 'full'
+*            selector {String}: 'date', 'time', or 'date and time'
+*
+* @return Object.value {String}: The localized date string
+*
+* @error GlobalizationError.FORMATTING_ERROR
+*
+* Example
+*    globalization.dateToString(new Date(),
+*                function (date) {alert('date:' + date.value + '\n');},
+*                function (errorCode) {alert(errorCode);},
+*                {formatLength:'short'});
+*/
+dateToString:function(date, successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.dateToString Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.dateToString Error: failureCB is not a function");
+        return;
+    }
+
+
+    if (date instanceof Date){
+        var dateValue;
+        dateValue = date.valueOf();
+        exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);
+    }
+    else {
+        console.log("Globalization.dateToString Error: date is not a Date object");
+    }
+},
+
+
+/**
+* Parses a date formatted as a string according to the client's user
+* preferences and calendar using the time zone of the client and returns
+* the corresponding date object. It returns the date to the successCB
+* callback with a properties object as a parameter. If there is an error
+* parsing the date string, then the errorCB callback is invoked.
+*
+* The defaults are: formatLength="short" and selector="date and time"
+*
+* @param {String} dateString
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            formatLength {String}: 'short', 'medium', 'long', or 'full'
+*            selector {String}: 'date', 'time', or 'date and time'
+*
+* @return    Object.year {Number}: The four digit year
+*            Object.month {Number}: The month from (0 - 11)
+*            Object.day {Number}: The day from (1 - 31)
+*            Object.hour {Number}: The hour from (0 - 23)
+*            Object.minute {Number}: The minute from (0 - 59)
+*            Object.second {Number}: The second from (0 - 59)
+*            Object.millisecond {Number}: The milliseconds (from 0 - 999),
+*                                        not available on all platforms
+*
+* @error GlobalizationError.PARSING_ERROR
+*
+* Example
+*    globalization.stringToDate('4/11/2011',
+*                function (date) { alert('Month:' + date.month + '\n' +
+*                    'Day:' + date.day + '\n' +
+*                    'Year:' + date.year + '\n');},
+*                function (errorCode) {alert(errorCode);},
+*                {selector:'date'});
+*/
+stringToDate:function(dateString, successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.stringToDate Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.stringToDate Error: failureCB is not a function");
+        return;
+    }
+    if (typeof dateString == "string"){
+        exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);
+    }
+    else {
+        console.log("Globalization.stringToDate Error: dateString is not a string");
+    }
+},
+
+
+/**
+* Returns a pattern string for formatting and parsing dates according to the client's
+* user preferences. It returns the pattern to the successCB callback with a
+* properties object as a parameter. If there is an error obtaining the pattern,
+* then the errorCB callback is invoked.
+*
+* The defaults are: formatLength="short" and selector="date and time"
+*
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            formatLength {String}: 'short', 'medium', 'long', or 'full'
+*            selector {String}: 'date', 'time', or 'date and time'
+*
+* @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.
+*                                    The patterns follow Unicode Technical Standard #35
+*                                    http://unicode.org/reports/tr35/tr35-4.html
+*            Object.timezone {String}: The abbreviated name of the time zone on the client
+*            Object.utc_offset {Number}: The current difference in seconds between the client's
+*                                        time zone and coordinated universal time.
+*            Object.dst_offset {Number}: The current daylight saving time offset in seconds
+*                                        between the client's non-daylight saving's time zone
+*                                        and the client's daylight saving's time zone.
+*
+* @error GlobalizationError.PATTERN_ERROR
+*
+* Example
+*    globalization.getDatePattern(
+*                function (date) {alert('pattern:' + date.pattern + '\n');},
+*                function () {},
+*                {formatLength:'short'});
+*/
+getDatePattern:function(successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getDatePattern Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getDatePattern Error: failureCB is not a function");
+        return;
+    }
+
+    exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);
+},
+
+
+/**
+* Returns an array of either the names of the months or days of the week
+* according to the client's user preferences and calendar. It returns the array of names to the
+* successCB callback with a properties object as a parameter. If there is an error obtaining the
+* names, then the errorCB callback is invoked.
+*
+* The defaults are: type="wide" and item="months"
+*
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            type {String}: 'narrow' or 'wide'
+*            item {String}: 'months', or 'days'
+*
+* @return Object.value {Array{String}}: The array of names starting from either
+*                                        the first month in the year or the
+*                                        first day of the week.
+* @error GlobalizationError.UNKNOWN_ERROR
+*
+* Example
+*    globalization.getDateNames(function (names) {
+*        for(var i = 0; i < names.value.length; i++) {
+*            alert('Month:' + names.value[i] + '\n');}},
+*        function () {});
+*/
+getDateNames:function(successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getDateNames Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getDateNames Error: failureCB is not a function");
+        return;
+    }
+    exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);
+},
+
+/**
+* Returns whether daylight savings time is in effect for a given date using the client's
+* time zone and calendar. It returns whether or not daylight savings time is in effect
+* to the successCB callback with a properties object as a parameter. If there is an error
+* reading the date, then the errorCB callback is invoked.
+*
+* @param {Date} date
+* @param {Function} successCB
+* @param {Function} errorCB
+*
+* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is
+*                                in effect for the given date and "false" indicate that it is not.
+*
+* @error GlobalizationError.UNKNOWN_ERROR
+*
+* Example
+*    globalization.isDayLightSavingsTime(new Date(),
+*                function (date) {alert('dst:' + date.dst + '\n');}
+*                function () {});
+*/
+isDayLightSavingsTime:function(date, successCB, failureCB) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.isDayLightSavingsTime Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.isDayLightSavingsTime Error: failureCB is not a function");
+        return;
+    }
+
+
+    if (date instanceof Date){
+        var dateValue;
+        dateValue = date.valueOf();
+        exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);
+    }
+    else {
+        console.log("Globalization.isDayLightSavingsTime Error: date is not a Date object");
+    }
+
+},
+
+/**
+* Returns the first day of the week according to the client's user preferences and calendar.
+* The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
+* It returns the day to the successCB callback with a properties object as a parameter.
+* If there is an error obtaining the pattern, then the errorCB callback is invoked.
+*
+* @param {Function} successCB
+* @param {Function} errorCB
+*
+* @return Object.value {Number}: The number of the first day of the week.
+*
+* @error GlobalizationError.UNKNOWN_ERROR
+*
+* Example
+*    globalization.getFirstDayOfWeek(function (day)
+*                { alert('Day:' + day.value + '\n');},
+*                function () {});
+*/
+getFirstDayOfWeek:function(successCB, failureCB) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getFirstDayOfWeek Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getFirstDayOfWeek Error: failureCB is not a function");
+        return;
+    }
+
+    exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);
+},
+
+
+/**
+* Returns a number formatted as a string according to the client's user preferences.
+* It returns the formatted number string to the successCB callback with a properties object as a
+* parameter. If there is an error formatting the number, then the errorCB callback is invoked.
+*
+* The defaults are: type="decimal"
+*
+* @param {Number} number
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            type {String}: 'decimal', "percent", or 'currency'
+*
+* @return Object.value {String}: The formatted number string.
+*
+* @error GlobalizationError.FORMATTING_ERROR
+*
+* Example
+*    globalization.numberToString(3.25,
+*                function (number) {alert('number:' + number.value + '\n');},
+*                function () {},
+*                {type:'decimal'});
+*/
+numberToString:function(number, successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.numberToString Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.numberToString Error: failureCB is not a function");
+        return;
+    }
+
+    if(typeof number == "number") {
+        exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);
+    }
+    else {
+        console.log("Globalization.numberToString Error: number is not a number");
+    }
+},
+
+/**
+* Parses a number formatted as a string according to the client's user preferences and
+* returns the corresponding number. It returns the number to the successCB callback with a
+* properties object as a parameter. If there is an error parsing the number string, then
+* the errorCB callback is invoked.
+*
+* The defaults are: type="decimal"
+*
+* @param {String} numberString
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            type {String}: 'decimal', "percent", or 'currency'
+*
+* @return Object.value {Number}: The parsed number.
+*
+* @error GlobalizationError.PARSING_ERROR
+*
+* Example
+*    globalization.stringToNumber('1234.56',
+*                function (number) {alert('Number:' + number.value + '\n');},
+*                function () { alert('Error parsing number');});
+*/
+stringToNumber:function(numberString, successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.stringToNumber Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.stringToNumber Error: failureCB is not a function");
+        return;
+    }
+
+    if(typeof numberString == "string") {
+        exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);
+    }
+    else {
+        console.log("Globalization.stringToNumber Error: numberString is not a string");
+    }
+},
+
+/**
+* Returns a pattern string for formatting and parsing numbers according to the client's user
+* preferences. It returns the pattern to the successCB callback with a properties object as a
+* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
+*
+* The defaults are: type="decimal"
+*
+* @param {Function} successCB
+* @param {Function} errorCB
+* @param {Object} options {optional}
+*            type {String}: 'decimal', "percent", or 'currency'
+*
+* @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.
+*                                    The patterns follow Unicode Technical Standard #35.
+*                                    http://unicode.org/reports/tr35/tr35-4.html
+*            Object.symbol {String}: The symbol to be used when formatting and parsing
+*                                    e.g., percent or currency symbol.
+*            Object.fraction {Number}: The number of fractional digits to use when parsing and
+*                                    formatting numbers.
+*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
+*            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
+*            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
+*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
+*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
+*
+* @error GlobalizationError.PATTERN_ERROR
+*
+* Example
+*    globalization.getNumberPattern(
+*                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},
+*                function () {});
+*/
+getNumberPattern:function(successCB, failureCB, options) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getNumberPattern Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getNumberPattern Error: failureCB is not a function");
+        return;
+    }
+
+    exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);
+},
+
+/**
+* Returns a pattern string for formatting and parsing currency values according to the client's
+* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
+* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
+* callback is invoked.
+*
+* @param {String} currencyCode
+* @param {Function} successCB
+* @param {Function} errorCB
+*
+* @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.
+*                                    The patterns follow Unicode Technical Standard #35
+*                                    http://unicode.org/reports/tr35/tr35-4.html
+*            Object.code {String}: The ISO 4217 currency code for the pattern.
+*            Object.fraction {Number}: The number of fractional digits to use when parsing and
+*                                    formatting currency.
+*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
+*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
+*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
+*
+* @error GlobalizationError.FORMATTING_ERROR
+*
+* Example
+*    globalization.getCurrencyPattern('EUR',
+*                function (currency) {alert('Pattern:' + currency.pattern + '\n');}
+*                function () {});
+*/
+getCurrencyPattern:function(currencyCode, successCB, failureCB) {
+    // successCallback required
+    if (typeof successCB != "function") {
+        console.log("Globalization.getCurrencyPattern Error: successCB is not a function");
+        return;
+    }
+
+    // errorCallback required
+    if (typeof failureCB != "function") {
+        console.log("Globalization.getCurrencyPattern Error: failureCB is not a function");
+        return;
+    }
+
+    if(typeof currencyCode == "string") {
+        exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);
+    }
+    else {
+        console.log("Globalization.getCurrencyPattern Error: currencyCode is not a currency code");
+    }
+}
+
+};
+
+module.exports = globalization;
+
+});
+
+// file: lib\common\plugin\logger.js
+define("cordova/plugin/logger", function(require, exports, module) {
+
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+var utils   = require('cordova/utils');
+
+var UseConsole   = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  E.g., the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.  Otherwise, it will use the
+ * native Logger plugin.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level, message /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 2);
+    message    = utils.vformat(message, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // if not using the console, use the native logger
+    if (!UseConsole) {
+        exec(null, null, "Logger", "logLevel", [level, message]);
+        return;
+    }
+
+    // make sure console is not using logger
+    if (console.__usingCordovaLogger) {
+        throw new Error("console and logger are too intertwingly");
+    }
+
+    // log to the console
+    switch (level) {
+        case logger.LOG:   console.log(message); break;
+        case logger.ERROR: console.log("ERROR: " + message); break;
+        case logger.WARN:  console.log("WARN: "  + message); break;
+        case logger.INFO:  console.log("INFO: "  + message); break;
+        case logger.DEBUG: console.log("DEBUG: " + message); break;
+    }
+};
+
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);
+
+});
+
+// file: lib\common\plugin\network.js
+define("cordova/plugin/network", function(require, exports, module) {
+
+var exec = require('cordova/exec'),
+    cordova = require('cordova'),
+    channel = require('cordova/channel'),
+    utils = require('cordova/utils');
+
+// Link the onLine property with the Cordova-supplied network info.
+// This works because we clobber the naviagtor object with our own
+// object in bootstrap.js.
+if (typeof navigator != 'undefined') {
+    utils.defineGetter(navigator, 'onLine', function() {
+        return this.connection.type != 'none';
+    });
+}
+
+var NetworkConnection = function () {
+    this.type = null;
+    this._firstRun = true;
+    this._timer = null;
+    this.timeout = 500;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribe(function() {
+        me.getInfo(function (info) {
+            me.type = info;
+            if (info === "none") {
+                // set a timer if still offline at the end of timer send the offline event
+                me._timer = setTimeout(function(){
+                    cordova.fireDocumentEvent("offline");
+                    me._timer = null;
+                    }, me.timeout);
+            } else {
+                // If there is a current offline event pending clear it
+                if (me._timer !== null) {
+                    clearTimeout(me._timer);
+                    me._timer = null;
+                }
+                cordova.fireDocumentEvent("online");
+            }
+
+            // should only fire this once
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+        },
+        function (e) {
+            // If we can't get the network info we should still tell Cordova
+            // to fire the deviceready event.
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+            console.log("Error initializing Network Connection: " + e);
+        });
+    });
+};
+
+/**
+ * Get connection info
+ *
+ * @param {Function} successCallback The function to call when the Connection data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
+ */
+NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {
+    // Get info
+    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
+};
+
+module.exports = new NetworkConnection();
+
+});
+
+// file: lib\common\plugin\notification.js
+define("cordova/plugin/notification", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+/**
+ * Provides access to notifications on the device.
+ */
+
+module.exports = {
+
+    /**
+     * Open a native alert dialog, with a customizable title and button text.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Alert)
+     * @param {String} buttonLabel          Label of the close button (default: OK)
+     */
+    alert: function(message, completeCallback, title, buttonLabel) {
+        var _title = (title || "Alert");
+        var _buttonLabel = (buttonLabel || "OK");
+        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
+    },
+
+    /**
+     * Open a native confirm dialog, with a customizable title and button text.
+     * The result that the user selects is returned to the result callback.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Confirm)
+     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+     */
+    confirm: function(message, resultCallback, title, buttonLabels) {
+        var _title = (title || "Confirm");
+        var _buttonLabels = (buttonLabels || "OK,Cancel");
+        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
+    },
+
+    /**
+     * Causes the device to vibrate.
+     *
+     * @param {Integer} mills       The number of milliseconds to vibrate for.
+     */
+    vibrate: function(mills) {
+        exec(null, null, "Notification", "vibrate", [mills]);
+    },
+
+    /**
+     * Causes the device to beep.
+     * On Android, the default notification ringtone is played "count" times.
+     *
+     * @param {Integer} count       The number of beeps.
+     */
+    beep: function(count) {
+        exec(null, null, "Notification", "beep", [count]);
+    }
+};
+
+});
+
+// file: lib\common\plugin\requestFileSystem.js
+define("cordova/plugin/requestFileSystem", function(require, exports, module) {
+
+var FileError = require('cordova/plugin/FileError'),
+    FileSystem = require('cordova/plugin/FileSystem'),
+    exec = require('cordova/exec');
+
+/**
+ * Request a file system in which to store application data.
+ * @param type  local file system type
+ * @param size  indicates how much storage space, in bytes, the application expects to need
+ * @param successCallback  invoked with a FileSystem object
+ * @param errorCallback  invoked if error occurs retrieving file system
+ */
+var requestFileSystem = function(type, size, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    if (type < 0 || type > 3) {
+        fail(FileError.SYNTAX_ERR);
+    } else {
+        // if successful, return a FileSystem object
+        var success = function(file_system) {
+            if (file_system) {
+                if (typeof successCallback === 'function') {
+                    // grab the name and root from the file system object
+                    var result = new FileSystem(file_system.name, file_system.root);
+                    successCallback(result);
+                }
+            }
+            else {
+                // no FileSystem object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+        exec(success, fail, "File", "requestFileSystem", [type, size]);
+    }
+};
+
+module.exports = requestFileSystem;
+
+});
+
+// file: lib\common\plugin\resolveLocalFileSystemURI.js
+define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
+
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    FileError = require('cordova/plugin/FileError'),
+    exec = require('cordova/exec');
+
+/**
+ * Look up file system Entry referred to by local URI.
+ * @param {DOMString} uri  URI referring to a local file or directory
+ * @param successCallback  invoked with Entry object corresponding to URI
+ * @param errorCallback    invoked if error occurs retrieving file system entry
+ */
+module.exports = function(uri, successCallback, errorCallback) {
+    // error callback
+    var fail = function(error) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(error));
+        }
+    };
+    // sanity check for 'not:valid:filename'
+    if(!uri || uri.split(":").length > 2) {
+        setTimeout( function() {
+            fail(FileError.ENCODING_ERR);
+        },0);
+        return;
+    }
+    // if successful, return either a file or directory entry
+    var success = function(entry) {
+        var result;
+        if (entry) {
+            if (typeof successCallback === 'function') {
+                // create appropriate Entry object
+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
+                try {
+                    successCallback(result);
+                }
+                catch (e) {
+                    console.log('Error invoking callback: ' + e);
+                }
+            }
+        }
+        else {
+            // no Entry object returned
+            fail(FileError.NOT_FOUND_ERR);
+        }
+    };
+
+    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+};
+
+});
+
+// file: lib\common\plugin\splashscreen.js
+define("cordova/plugin/splashscreen", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+var splashscreen = {
+    show:function() {
+        exec(null, null, "SplashScreen", "show", []);
+    },
+    hide:function() {
+        exec(null, null, "SplashScreen", "hide", []);
+    }
+};
+
+module.exports = splashscreen;
+
+});
+
+// file: lib\webos\plugin\webos\accelerometer.js
+define("cordova/plugin/webos/accelerometer", function(require, exports, module) {
+
+var callback;
+module.exports = {
+    /*
+     * Tells WebOS to put higher priority on accelerometer resolution. Also relaxes the internal garbage collection events.
+     * @param {Boolean} state
+     * Dependencies: Mojo.windowProperties
+     * Example:
+     *         navigator.accelerometer.setFastAccelerometer(true)
+     */
+    setFastAccelerometer: function(state) {
+        navigator.windowProperties.fastAccelerometer = state;
+        navigator.window.setWindowProperties();
+    },
+
+    /*
+     * Starts the native acceleration listener.
+     */
+    start: function(win,fail,args) {
+        console.error("webos plugin accelerometer start");
+        window.removeEventListener("acceleration", callback);
+        callback = function(event) {
+            var accel = new Acceleration(event.accelX*-9.81, event.accelY*-9.81, event.accelZ*-9.81);
+            win(accel);
+        };
+        document.addEventListener("acceleration", callback);
+    },
+    stop: function (win,fail,args) {
+        console.error("webos plugin accelerometer stop");
+        window.removeEventListener("acceleration", callback);
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\application.js
+define("cordova/plugin/webos/application", function(require, exports, module) {
+
+module.exports = {
+    isActivated: function(inWindow) {
+        inWindow = inWindow || window;
+        if(inWindow.PalmSystem) {
+            return inWindow.PalmSystem.isActivated;
+        }
+        return false;
+    },
+
+    /*
+     * Tell webOS to activate the current page of your app, bringing it into focus.
+     * Example:
+     *         navigator.application.activate();
+     */
+    activate: function(inWindow) {
+        inWindow = inWindow || window;
+        if(inWindow.PalmSystem) {
+            inWindow.PalmSystem.activate();
+        }
+    },
+
+    /*
+     * Tell webOS to deactivate your app.
+     * Example:
+     *        navigator.application.deactivate();
+     */
+    deactivate: function(inWindow) {
+        inWindow = inWindow || window;
+        if(inWindow.PalmSystem) {
+            inWindow.PalmSystem.deactivate();
+        }
+    },
+
+    /*
+     * Returns the identifier of the current running application (e.g. com.yourdomain.yourapp).
+     * Example:
+     *        navigator.application.getIdentifier();
+     */
+    getIdentifier: function() {
+        return PalmSystem.identifier;
+    },
+
+    fetchAppId: function() {
+        if (window.PalmSystem) {
+            // PalmSystem.identifier: <appid> <processid>
+            return PalmSystem.identifier.split(" ")[0];
+        }
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\camera.js
+define("cordova/plugin/webos/camera", function(require, exports, module) {
+
+var service = require('cordova/plugin/webos/service');
+
+module.exports = {
+    takePicture: function(successCallback, errorCallback, options) {
+        var filename = (options || {}).filename | "";
+
+        service.Request('palm://com.palm.applicationManager', {
+            method: 'launch',
+            parameters: {
+            id: 'com.palm.app.camera',
+            params: {
+                    appId: 'com.palm.app.camera',
+                    name: 'capture',
+                    sublaunch: true,
+                    filename: filename
+                }
+            },
+            onSuccess: successCallback,
+            onFailure: errorCallback
+        });
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\compass.js
+define("cordova/plugin/webos/compass", function(require, exports, module) {
+
+var CompassHeading = require('cordova/plugin/CompassHeading'),
+    CompassError = require('cordova/plugin/CompassError');
+
+module.exports = {
+    getHeading: function (win, lose) {
+        // only TouchPad and Pre3 have a Compass/Gyro
+        if (window.device.name !== "TouchPad" && window.device.name !== "Prē3") {
+            lose({code: CompassError.COMPASS_NOT_SUPPORTED});
+        } else {
+            console.error("webos plugin compass getheading");
+            var onReadingChanged = function (e) {
+                var heading = new CompassHeading(e.magHeading, e.trueHeading);
+                document.removeEventListener("compass", onReadingChanged);
+                //win(CompassHeading(e.magHeading, e.trueHeading));
+                win(heading);
+            };
+            document.addEventListener("compass", onReadingChanged);
+        }
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\device.js
+define("cordova/plugin/webos/device", function(require, exports, module) {
+
+var service = require('cordova/plugin/webos/service');
+
+module.exports = {
+    getDeviceInfo: function(success, fail, args) {
+        console.log("webOS Plugin: Device - getDeviceInfo");
+
+        service.Request('palm://com.palm.preferences/systemProperties', {
+            method:"Get",
+            parameters:{"key": "com.palm.properties.nduid" },
+            onSuccess: function (result) {
+                var parsedData = JSON.parse(PalmSystem.deviceInfo);
+
+                success({
+                    cordova: "2.2.0",
+                    platform: "HP webOS",
+                    name: parsedData.modelName,
+                    version: parsedData.platformVersion,
+                    uuid: result["com.palm.properties.nduid"]
+                });
+            }
+        });
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\file.js
+define("cordova/plugin/webos/file", function(require, exports, module) {
+
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+    this.name = name || '';
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+};
+
+module.exports = File;
+
+});
+
+// file: lib\webos\plugin\webos\filereader.js
+define("cordova/plugin/webos/filereader", function(require, exports, module) {
+
+var FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+var FileReader = function() {
+    this.fileName = "";
+
+    this.readyState = 0; // FileReader.EMPTY
+
+    // File data
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onloadstart = null;    // When the read starts.
+    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)
+    this.onload = null;         // When the read has successfully completed.
+    this.onerror = null;        // When the read has failed (see errors).
+    this.onloadend = null;      // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.
+};
+
+FileReader.prototype.readAsText = function(file, encoding) {
+    console.error("webos plugin filereader readastext:" + file);
+    //Mojo has no file i/o yet, so we use an xhr. very limited
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    // Default encoding is UTF-8
+    var enc = encoding ? encoding : "UTF-8";
+
+    var me = this;
+
+    var xhr = new XMLHttpRequest();
+    xhr.onreadystatechange = function() {
+        console.error("onreadystatechange:"+xhr.readyState+" "+xhr.status);
+        if (xhr.readyState == 4) {
+            if (xhr.status == 200 && xhr.responseText) {
+                console.error("file read completed");
+                // Save result
+                me.result = xhr.responseText;
+
+                // If onload callback
+                if (typeof me.onload === "function") {
+                    me.onload(new ProgressEvent("load", {target:me}));
+                }
+
+                // DONE state
+                me.readyState = FileReader.DONE;
+
+                // If onloadend callback
+                if (typeof me.onloadend === "function") {
+                    me.onloadend(new ProgressEvent("loadend", {target:me}));
+                }
+
+            } else {
+                // If DONE (cancelled), then don't do anything
+                if (me.readyState === FileReader.DONE) {
+                    return;
+                }
+
+                // DONE state
+                me.readyState = FileReader.DONE;
+
+                me.result = null;
+
+                // Save error
+                me.error = new FileError(FileError.NOT_FOUND_ERR);
+
+                // If onerror callback
+                if (typeof me.onerror === "function") {
+                    me.onerror(new ProgressEvent("error", {target:me}));
+                }
+
+                // If onloadend callback
+                if (typeof me.onloadend === "function") {
+                    me.onloadend(new ProgressEvent("loadend", {target:me}));
+                }
+            }
+        }
+    };
+    xhr.open("GET", file, true);
+    xhr.send();
+};
+
+module.exports = FileReader;
+
+});
+
+// file: lib\webos\plugin\webos\geolocation.js
+define("cordova/plugin/webos/geolocation", function(require, exports, module) {
+
+var service = require('cordova/plugin/webos/service');
+
+module.exports = {
+    getLocation: function(successCallback, errorCallback, options) {
+        console.error("webos plugin geolocation getlocation");
+        var request = service.Request('palm://com.palm.location', {
+            method: "getCurrentPosition",
+            onSuccess: function(event) {
+                var alias={};
+                alias.lastPosition = {
+                    coords: {
+                        latitude: event.latitude,
+                        longitude: event.longitude,
+                        altitude: (event.altitude >= 0 ? event.altitude: null),
+                        speed: (event.velocity >= 0 ? event.velocity: null),
+                        heading: (event.heading >= 0 ? event.heading: null),
+                        accuracy: (event.horizAccuracy >= 0 ? event.horizAccuracy: null),
+                        altitudeAccuracy: (event.vertAccuracy >= 0 ? event.vertAccuracy: null)
+                    },
+                    timestamp: new Date().getTime()
+                };
+
+                successCallback(alias.lastPosition);
+            },
+            onFailure: function() {
+                errorCallback();
+            }
+        });
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\keyboard.js
+define("cordova/plugin/webos/keyboard", function(require, exports, module) {
+
+var _isShowing = null,
+    _manual = null;
+
+module.exports = {
+    types: {
+        text: 0,
+        password: 1,
+        search: 2,
+        range: 3,
+        email: 4,
+        number: 5,
+        phone: 6,
+        url: 7,
+        color: 8
+    },
+    isShowing: function() {
+        return !!_isShowing;
+    },
+    show: function(type){
+        if(this.isManualMode()) {
+            PalmSystem.keyboardShow(type || 0);
+        }
+    },
+    hide: function(){
+        if(this.isManualMode()) {
+            PalmSystem.keyboardHide();
+        }
+    },
+    setManualMode: function(mode){
+        _manual = mode;
+        PalmSystem.setManualKeyboardEnabled(mode);
+    },
+    isManualMode: function(){
+        return _manual || false;
+    },
+    forceShow: function(inType){
+        this.setManualMode(true);
+        PalmSystem.keyboardShow(inType || 0);
+    },
+    forceHide: function(){
+        this.setManualMode(true);
+        PalmSystem.keyboardHide();
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\network.js
+define("cordova/plugin/webos/network", function(require, exports, module) {
+
+var service=require('cordova/plugin/webos/service');
+
+module.exports = {
+    /**
+     * Get connection info
+     *
+     * @param {Function} successCallback The function to call when the Connection data is available
+     * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
+     */
+    getConnectionInfo: function (successCallback, errorCallback) {
+        // Get info
+        console.log("webos Plugin: NetworkStatus - getConnectionInfo");
+
+        service.Request('palm://com.palm.connectionmanager', {
+            method: 'getstatus',
+            parameters: {},
+            onSuccess: function (result) {
+                console.log("result:"+JSON.stringify(result));
+
+                var info={};
+                if (!result.isInternetConnectionAvailable) { info.type="Connection.NONE"; }
+                if (result.wifi.onInternet) { info.type="Connection.WIFI"; }
+                if (result.wan.state==="connected") { info.type="Connection.CELL_2G"; }
+
+                successCallback(info.type);
+            },
+            onFailure: errorCallback
+        });
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\notification.js
+define("cordova/plugin/webos/notification", function(require, exports, module) {
+
+module.exports = {
+    /*
+     * adds a dashboard to the WebOS app
+     * @param {String} url
+     * @param {String} html
+     * Example:
+     *        navigator.notification.newDashboard("dashboard.html");
+     */
+    newDashboard: function(url, html) {
+        var win = window.open(url, "_blank", "attributes={\"window\":\"dashboard\"}");
+        html && win.document.write(html);
+        win.PalmSystem.stageReady();
+    },
+
+    /*
+     * Displays a banner notification. If specified, will send your 'response' object as data via the 'palmsystem' DOM event.
+     * If no 'icon' filename is specified, will use a small version of your application icon.
+     * @param {String} message
+     * @param {Object} response
+     * @param {String} icon
+     * @param {String} soundClass class of the sound; supported classes are: "ringtones", "alerts", "alarm", "calendar", "notification"
+     * @param {String} soundFile partial or full path to the sound file
+     * @param {String} soundDurationMs of sound in ms
+     * Example:
+     *        navigator.notification.showBanner('test message');
+     */
+    showBanner: function(message, response, icon, soundClass, soundFile, soundDurationMs) {
+        response = response || {
+            banner: true
+        };
+        PalmSystem.addBannerMessage(message, JSON.stringify(response), icon, soundClass, soundFile, soundDurationMs);
+    },
+
+    /**
+     * Remove a banner from the banner area. The category parameter defaults to 'banner'. Will not remove
+     * messages that are already displayed.
+     * @param {String} category
+            Value defined by the application and usually same one used in {@link showBanner}.
+            It is used if you have more than one kind of banner message.
+     */
+    removeBannerMessage: function(category) {
+        var bannerKey = category || 'banner';
+        var bannerId = this.banners.get(bannerKey);
+        if (bannerId) {
+            try {
+                PalmSystem.removeBannerMessage(bannerId);
+            } catch(removeBannerException) {
+                window.debug.error(removeBannerException.toString());
+            }
+        }
+    },
+
+    /*
+     * Remove all pending banner messages from the banner area. Will not remove messages that are already displayed.
+     */
+    clearBannerMessage: function() {
+        PalmSystem.clearBannerMessage();
+    },
+
+    /*
+     * This function vibrates the device
+     * @param {number} duration The duration in ms to vibrate for.
+     * @param {number} intensity The intensity of the vibration
+     */
+    vibrate_private: function(duration, intensity) {
+        //the intensity for palm is inverted; 0=high intensity, 100=low intensity
+        //this is opposite from our api, so we invert
+        if (isNaN(intensity) || intensity > 100 || intensity <= 0)
+        intensity = 0;
+        else
+        intensity = 100 - intensity;
+
+        // if the app id does not have the namespace "com.palm.", an error will be thrown here
+        //this.vibhandle = new Mojo.Service.Request("palm://com.palm.vibrate", {
+        this.vibhandle = navigator.service.Request("palm://com.palm.vibrate", {
+            method: 'vibrate',
+            parameters: {
+                'period': intensity,
+                'duration': duration
+            }
+        },
+        false);
+    },
+
+    vibrate: function(param) {
+        PalmSystem.playSoundNotification('vibrate');
+    },
+    /*
+     * Plays the specified sound
+     * @param {String} soundClass class of the sound; supported classes are: "ringtones", "alerts", "alarm", "calendar", "notification"
+     * @param {String} soundFile partial or full path to the sound file
+     * @param {String} soundDurationMs of sound in ms
+     */
+    beep: function(param) {
+        PalmSystem.playSoundNotification('alerts');
+    },
+
+    getRootWindow: function() {
+        var w = window.opener || window.rootWindow || window.top || window;
+        if(!w.setTimeout) { // use this window as the root if we don't have access to the real root.
+            w = window;
+        }
+        return w;
+    },
+
+    open: function(inOpener, inUrl, inName, inAttributes, inWindowInfo) {
+        var url = inUrl;
+        var a = inAttributes && JSON.stringify(inAttributes);
+        a = "attributes=" + a;
+        var i = inWindowInfo ? inWindowInfo + ", " : "";
+        return inOpener.open(url, inName, i + a);
+    },
+
+    openWindow: function(inUrl, inName, inParams, inAttributes, inWindowInfo) {
+        //var attributes = inAttributes || {};
+        //attributes.window = attributes.window || "card";
+        // NOTE: make the root window open all windows.
+        return this.open(this.getRootWindow(), inUrl, inName || "", inAttributes, inWindowInfo);
+    },
+
+    alert: function(message,callback,title,buttonName) {
+        var inAttributes = {};
+        //inAttributes.window = "card"; // create card
+        inAttributes.window = "popupalert"; // create popup
+        //inAttributes.window="dashboard"; // create dashboard
+        var html='<html><head><script>setTimeout(function(f){var el=window.document.getElementById("b1");console.error(el);el.addEventListener("click",function(f){window.close();},false);},500);</script></head><body>'+message+'<br/><button id="b1">'+buttonName+'</button></body></html>';
+        var inName="PopupAlert";
+        var inUrl="";
+        var inParams={};
+        var inHeight=120;
+        var w = this.openWindow(inUrl, inName, inParams, inAttributes, "height=" + (inHeight || 200));
+        w.document.write(html);
+        w.PalmSystem.stageReady();
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\orientation.js
+define("cordova/plugin/webos/orientation", function(require, exports, module) {
+
+module.exports = {
+    setOrientation: function(orientation) {
+        PalmSystem.setWindowOrientation(orientation);
+    },
+
+    /*
+     * Returns the current window orientation
+     * orientation is one of 'up', 'down', 'left', 'right', or 'free'
+     */
+    getCurrentOrientation: function() {
+          return PalmSystem.windowOrientation;
+    }
+};
+
+});
+
+// file: lib\webos\plugin\webos\requestfilesystem.js
+define("cordova/plugin/webos/requestfilesystem", function(require, exports, module) {
+
+module.exports = function(type,size,successCallback,errorCallback) {
+    console.error("requestFileSystem");
+
+    var theFileSystem={};
+    theFileSystem.name="webOS";
+    theFileSystem.root={};
+    theFileSystem.root.name="Root";
+
+    theFileSystem.root.getFile=function(filename,options,successCallback,errorCallback) {
+        console.error("getFile");
+        if (options.create) { errorCallback(); }
+        var theFile=filename;
+        successCallback(theFile);
+    };
+
+    successCallback(theFileSystem);
+};
+
+});
+
+// file: lib\webos\plugin\webos\service.js
+define("cordova/plugin/webos/service", function(require, exports, module) {
+
+function Service() { }
+
+Service.prototype.Request = function (uri, params) {
+    var req = new PalmServiceBridge();
+    var url = uri + "/" + (params.method || "");
+    req.url = url;
+
+    this.req = req;
+    this.url = url;
+    this.params = params || {};
+
+    this.call(params);
+
+    return this;
+};
+
+Service.prototype.call = function(params) {
+    var onsuccess = null;
+    var onfailure = null;
+    var oncomplete = null;
+
+    if (typeof params.onSuccess === 'function')
+        onsuccess = params.onSuccess;
+
+    if (typeof params.onFailure === 'function')
+        onerror = params.onFailure;
+
+    if (typeof params.onComplete === 'function')
+        oncomplete = params.onComplete;
+
+    this.req.onservicecallback = callback;
+
+    function callback(msg) {
+        var response = JSON.parse(msg);
+
+        if ((response.errorCode) && onfailure)
+            onfailure(response);
+        else if (onsuccess)
+            onsuccess(response);
+
+        if (oncomplete)
+            oncomplete(response);
+    }
+
+    this.data = (typeof params.parameters === 'object') ? JSON.stringify(params.parameters) : '{}';
+
+    this.req.call(this.url, this.data);
+};
+
+module.exports = new Service();
+
+});
+
+// file: lib\webos\plugin\webos\window.js
+define("cordova/plugin/webos/window", function(require, exports, module) {
+
+module.exports={
+    launchParams: function() {
+        return JSON.parse(PalmSystem.launchParams) || {};
+    },
+    /*
+     * This is a thin wrapper for 'window.open()' which optionally sets document contents to 'html', and calls 'PalmSystem.stageReady()'
+     * on your new card. Note that this new card will not come with your framework (if any) or anything for that matter.
+     * @param {String} url
+     * @param {String} html
+     * Example:
+     *        navigator.window.newCard('about:blank', '<html><body>Hello again!</body></html>');
+     */
+    newCard: function(url, html) {
+        var win = window.open(url || "");
+        if (html)
+            win.document.write(html);
+        win.PalmSystem.stageReady();
+    },
+
+    /*
+     * Enable or disable full screen display (full screen removes the app menu bar and the rounded corners of the screen).
+     * @param {Boolean} state
+     * Example:
+     *        navigator.window.setFullScreen(true);
+     */
+    setFullScreen: function(state) {
+        // valid state values are: true or false
+        PalmSystem.enableFullScreenMode(state);
+    },
+
+    /*
+     * used to set the window properties of the WebOS app
+     * @param {Object} props
+     * Example:
+     *         private method used by other member functions - ideally we shouldn't call this method
+     */
+    setWindowProperties: function(inWindow, inProps) {
+        if(arguments.length==1) {
+            inProps = inWindow;
+            inWindow = window;
+        }
+        if(inWindow.PalmSystem) {
+            inWindow.PalmSystem.setWindowProperties(inProps);
+        }
+    },
+
+    /*
+     * Enable or disable screen timeout. When enabled, the device screen will not dim. This is useful for navigation, clocks or other "dock" apps.
+     * @param {Boolean} state
+     * Example:
+     *        navigator.window.blockScreenTimeout(true);
+     */
+    blockScreenTimeout: function(state) {
+        navigator.windowProperties.blockScreenTimeout = state;
+        this.setWindowProperties();
+    },
+
+    /*
+     * Sets the lightbar to be a little dimmer for screen locked notifications.
+     * @param {Boolean} state
+     * Example:
+     *        navigator.window.setSubtleLightbar(true);
+     */
+    setSubtleLightbar: function(state) {
+        navigator.windowProperties.setSubtleLightbar = state;
+        this.setWindowProperties();
+    }
+};
+
+});
+
+// file: lib\common\utils.js
+define("cordova/utils", function(require, exports, module) {
+
+var utils = exports;
+
+/**
+ * Defines a property getter for obj[key].
+ */
+utils.defineGetter = function(obj, key, func) {
+    if (Object.defineProperty) {
+        Object.defineProperty(obj, key, { get: func });
+    } else {
+        obj.__defineGetter__(key, func);
+    }
+};
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return Object.prototype.toString.call(a) == '[object Array]';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return Object.prototype.toString.call(d) == '[object Date]';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrapped version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (window.alert) {
+        window.alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+/**
+ * Formats a string and arguments following it ala sprintf()
+ *
+ * see utils.vformat() for more information
+ */
+utils.format = function(formatString /* ,... */) {
+    var args = [].slice.call(arguments, 1);
+    return utils.vformat(formatString, args);
+};
+
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+utils.vformat = function(formatString, args) {
+    if (formatString === null || formatString === undefined) return "";
+    if (arguments.length == 1) return formatString.toString();
+    if (typeof formatString != "string") return formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var arg   = args.shift();
+        var match = pattern.exec(rest);
+
+        if (!match) break;
+
+        rest = match[3];
+
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    return result.join('');
+};
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+//------------------------------------------------------------------------------
+function formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+});
+
+
+window.cordova = require('cordova');
+
+// file: lib\scripts\bootstrap.js
+
+(function (context) {
+    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
+    // We replace it so that properties that can't be clobbered can instead be overridden.
+    if (typeof navigator != 'undefined') {
+        var CordovaNavigator = function () {};
+        CordovaNavigator.prototype = navigator;
+        navigator = new CordovaNavigator();
+    }
+
+    var channel = require("cordova/channel"),
+        _self = {
+            boot: function () {
+                /**
+                 * Create all cordova objects once page has fully loaded and native side is ready.
+                 */
+                channel.join(function() {
+                    var builder = require('cordova/builder'),
+                        base = require('cordova/common'),
+                        platform = require('cordova/platform');
+
+                    // Drop the common globals into the window object, but be nice and don't overwrite anything.
+                    builder.build(base.objects).intoButDoNotClobber(window);
+
+                    // Drop the platform-specific globals into the window object
+                    // and clobber any existing object.
+                    builder.build(platform.objects).intoAndClobber(window);
+
+                    // Merge the platform-specific overrides/enhancements into
+                    // the window object.
+                    if (typeof platform.merges !== 'undefined') {
+                        builder.build(platform.merges).intoAndMerge(window);
+                    }
+
+                    // Call the platform-specific initialization
+                    platform.initialize();
+
+                    // Fire event to notify that all objects are created
+                    channel.onCordovaReady.fire();
+
+                    // Fire onDeviceReady event once all constructors have run and
+                    // cordova info has been received from native side.
+                    channel.join(function() {
+                        require('cordova').fireDocumentEvent('deviceready');
+                    }, channel.deviceReadyChannelsArray);
+
+                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+            }
+        };
+
+    // boot up once native side is ready
+    channel.onNativeReady.subscribe(_self.boot);
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+}(window));
+
+// file: lib\scripts\bootstrap-webos.js
+
+require('cordova/channel').onNativeReady.fire();
+
+
+})();
diff --git a/lib/thumbs.0.5.2.js b/lib/thumbs.0.5.2.js
deleted file mode 100644
index c5770c6..0000000
--- a/lib/thumbs.0.5.2.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-The MIT License
-
-Copyright (c) 2010 Michael Brooks
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-(function(window) {
-
-    /**
-     * Do not use thumbs.js on touch-enabled devices
-     * 
-     * Thanks to Jesse MacFadyen (purplecabbage):
-     * https://gist.github.com/850593#gistcomment-22484
-     */
-    try {
-        document.createEvent('TouchEvent');
-        return;
-    }
-    catch(e) {
-    }
-
-    /**
-     * Map touch events to mouse events
-     */
-    var eventMap = {
-        'mousedown': 'touchstart',
-        'mouseup':   'touchend',
-        'mousemove': 'touchmove'
-    };
-
-    /**
-     * Fire touch events
-     *
-     * Monitor mouse events and fire a touch event on the
-     * object broadcasting the mouse event. This approach
-     * likely has poorer performance than hijacking addEventListener
-     * but it is a little more browser friendly.
-     */
-    window.addEventListener('load', function() {
-        for (var key in eventMap) {
-            document.body.addEventListener(key, function(e) {
-                // Supports:
-                //   - addEventListener
-                //   - setAttribute
-                var event = createTouchEvent(eventMap[e.type], e);
-                e.target.dispatchEvent(event);
-
-                // Supports:
-                //   - element.ontouchstart
-                var fn = e.target['on' + eventMap[e.type]];
-                if (typeof fn === 'function') fn(e);
-            }, false);
-        }
-    }, false);
-
-    /**
-     * Utility function to create a touch event.
-     *
-     * @param  name  {String} of the event
-     * @return event {Object}
-     */
-    var createTouchEvent = function(name, e) {
-        var event = document.createEvent('MouseEvents');
-
-        event.initMouseEvent(
-            name,
-            e.bubbles,
-            e.cancelable,
-            e.view,
-            e.detail,
-            e.screenX,
-            e.screenY,
-            e.clientX,
-            e.clientY,
-            e.ctrlKey,
-            e.altKey,
-            e.shiftKey,
-            e.metaKey,
-            e.button,
-            e.relatedTarget
-        );
-
-        return event;
-    };
-
-})(window);
