diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..aad4c63 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2080e83 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.DS_Store +bin diff --git a/.project b/.project new file mode 100644 index 0000000..f426ea0 --- /dev/null +++ b/.project @@ -0,0 +1,33 @@ + + + PusherExample + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..df26f9c --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/www/index.html b/assets/www/index.html new file mode 100644 index 0000000..6fbdae2 --- /dev/null +++ b/assets/www/index.html @@ -0,0 +1,22 @@ + + + + Pusher Example + + +

Hello Pusher

+

Device Info:

+
+ +

Pusher

+ no loaded
+ not loaded
+ + + + + + + + + \ No newline at end of file diff --git a/assets/www/js/app.js b/assets/www/js/app.js new file mode 100644 index 0000000..d99ccb6 --- /dev/null +++ b/assets/www/js/app.js @@ -0,0 +1,54 @@ +( function( $ ) { + + var CONFIG = { + PUSHER: { + APP_KEY: '49e26cb8e9dde3dfc009' + } + }; + + document.addEventListener("deviceready", onDeviceReady, false); + + function onDeviceReady() { + + // Get device info + var deviceInfo = 'Device Name: ' + device.name + '
' + + 'Device Cordova: ' + device.cordova + '
' + + 'Device Platform: ' + device.platform + '
' + + 'Device UUID: ' + device.uuid + '
' + + 'Device Version: ' + device.version + '
'; + + $('#deviceProperties').html(deviceInfo) + + // Connect + var pusher = new Pusher(CONFIG.PUSHER.APP_KEY); + pusher.connection.bind('state_change', connectionStateChange); + + function connectionStateChange(state) { + $('#connectionStatus').html(state.current); + } + + // Subscribe + var channel = pusher.subscribe('my-channel'); + channel.bind('pusher:subscription_succeeded', subscriptionSucceeded); + + function subscriptionSucceeded() { + $('#subscriptionStatus').html('succeeded'); + } + + var clicks = 0; + $('#subscribeBtn').click( subscribeBtnClicked ); + function subscribeBtnClicked() { + var channelName = 'channel-' + clicks; + ++clicks; + pusher.subscribe(channelName); + } + + } + +} )( jQuery ); + +Pusher.log = function( msg ) { + if( window.console && window.console.log ) { + window.console.log( msg ); + } +}; \ No newline at end of file diff --git a/assets/www/js/libs/cordova-1.9.0.js b/assets/www/js/libs/cordova-1.9.0.js new file mode 100755 index 0000000..2fdf2d5 --- /dev/null +++ b/assets/www/js/libs/cordova-1.9.0.js @@ -0,0 +1,5758 @@ +// commit 5647225e12e18e15aefc33b151430d9a3804d9ea + +// File generated at :: Fri Jun 29 2012 12:32:24 GMT-0400 (EDT) + +/* + 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 = {}; + + 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"; + } + return modules[id].factory ? build(modules[id]) : 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') { + if (evt === 'deviceready') { + documentEventHandlers[e].subscribeOnce(handler); + } else { + 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 unsubcribing 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 unsubcribing 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, opts) { + return (windowEventHandlers[event] = channel.create(event, opts)); + }, + addDocumentEventHandler:function(event, opts) { + return (documentEventHandlers[event] = channel.create(event, opts)); + }, + removeWindowEventHandler:function(event) { + delete windowEventHandlers[event]; + }, + removeDocumentEventHandler:function(event) { + delete documentEventHandlers[event]; + }, + /** + * Retreive 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 + */ + fireDocumentEvent: function(type, data) { + var evt = createEvent(type, data); + if (typeof documentEventHandlers[type] != 'undefined') { + 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); + } + }, + // TODO: this is Android only; think about how to do this better + shuttingDown:false, + UsePolling:false, + // END TODO + + // TODO: iOS only + // This queue holds the currently executing command and all pending + // commands executed with cordova.exec(). + commandQueue:[], + // Indicates if we're currently in the middle of flushing the command + // queue on the native side. + commandQueueFlushing:false, + // END TODO + /** + * Plugin callback mechanism. + */ + callbackId: 0, + 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. + * + * @param callbackId + * @param args + */ + callbackSuccess: function(callbackId, args) { + if (cordova.callbacks[callbackId]) { + + // If result is to be sent to callback + if (args.status == cordova.callbackStatus.OK) { + try { + if (cordova.callbacks[callbackId].success) { + cordova.callbacks[callbackId].success(args.message); + } + } + catch (e) { + console.log("Error in success callback: "+callbackId+" = "+e); + } + } + + // Clear callback if not expecting any more results + if (!args.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + }, + + /** + * Called by native code when returning error result from an action. + * + * @param callbackId + * @param args + */ + callbackError: function(callbackId, args) { + if (cordova.callbacks[callbackId]) { + try { + if (cordova.callbacks[callbackId].fail) { + cordova.callbacks[callbackId].fail(args.message); + } + } + catch (e) { + console.log("Error in error callback: "+callbackId+" = "+e); + } + + // Clear callback if not expecting any more results + if (!args.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + }, + // TODO: remove in 2.0. + addPlugin: function(name, obj) { + console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0."); + if (!window.plugins[name]) { + window.plugins[name] = obj; + } + else { + console.log("Error: Plugin "+name+" already exists."); + } + }, + + addConstructor: function(func) { + channel.onCordovaReady.subscribeOnce(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.addDocumentEventHandler('deviceready'); + +// Adds deprecation warnings to functions of an object (but only logs a message once) +function deprecateFunctions(obj, objLabel) { + var newObj = {}; + var logHash = {}; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + if (typeof obj[i] == 'function') { + newObj[i] = (function(prop){ + var oldFunk = obj[prop]; + var funkId = objLabel + '_' + prop; + return function() { + if (!logHash[funkId]) { + console.log('[DEPRECATION NOTICE] The "' + objLabel + '" global will be removed in version 2.0, please use lowercase "cordova".'); + logHash[funkId] = true; + } + oldFunk.apply(obj, arguments); + }; + })(i); + } else { + newObj[i] = (function(prop) { return obj[prop]; })(i); + } + } + } + return newObj; +} + +/** + * Legacy variable for plugin support + * TODO: remove in 2.0. + */ +if (!window.PhoneGap) { + window.PhoneGap = deprecateFunctions(cordova, 'PhoneGap'); +} +if (!window.Cordova) { + window.Cordova = deprecateFunctions(cordova, 'Cordova'); +} + +/** + * Plugins object + * TODO: remove in 2.0. + */ +if (!window.plugins) { + window.plugins = {}; +} + +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 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') { + parent[key] = result; + } else if (typeof obj.path !== 'undefined') { + // If merging, merge properties onto parent, otherwise, clobber. + if (merge) { + recursiveMerge(parent[key], result); + } else { + parent[key] = result; + } + } + result = parent[key]; + } else { + // Overwrite if not currently defined. + if (typeof parent[key] == 'undefined') { + parent[key] = result; + } 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 { + intoButDontClobber: 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'); + +/** + * 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. + * + * 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 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 + * @param opts Object options to pass into the channel, currently + * supports: + * onSubscribe: callback that fires when + * something subscribes to the Channel. Sets + * context to the Channel. + * onUnsubscribe: callback that fires when + * something unsubscribes to the Channel. Sets + * context to the Channel. + */ +var Channel = function(type, opts) { + this.type = type; + this.handlers = {}; + this.numHandlers = 0; + this.guid = 1; + this.fired = false; + this.enabled = true; + this.events = { + onSubscribe:null, + onUnsubscribe:null + }; + if (opts) { + if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe; + if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe; + } +}, + channel = { + /** + * Calls the provided function only after all of the channels specified + * have been fired. + */ + join: function (h, c) { + var i = c.length; + var len = i; + var f = function() { + if (!(--i)) h(); + }; + for (var j=0; j 0) { + var v = JSON.parse(r); + + // If status is OK, then return value back to caller + if (v.status === cordova.callbackStatus.OK) { + + // If there is a success callback, then call it now with + // returned value + if (success) { + try { + success(v.message); + } catch (e) { + console.log("Error in success callback: " + callbackId + " = " + e); + } + + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return v.message; + } + + // If no result + else if (v.status === cordova.callbackStatus.NO_RESULT) { + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + + // If error, then display error + else { + console.log("Error: Status="+v.status+" Message="+v.message); + + // If there is a fail callback, then call it now with returned value + if (fail) { + try { + fail(v.message); + } + catch (e1) { + console.log("Error in error callback: "+callbackId+" = "+e1); + } + + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return null; + } + } + } catch (e2) { + console.log("Error: "+e2); + } +}; + +}); + +// file: lib/android/platform.js +define("cordova/platform", function(require, exports, module) { +module.exports = { + id: "android", + initialize:function() { + var channel = require("cordova/channel"), + cordova = require('cordova'), + callback = require('cordova/plugin/android/callback'), + polling = require('cordova/plugin/android/polling'), + exec = require('cordova/exec'); + + channel.onDestroy.subscribe(function() { + cordova.shuttingDown = true; + }); + + // Start listening for XHR callbacks + // Figure out which bridge approach will work on this Android + // device: polling or XHR-based callbacks + setTimeout(function() { + if (cordova.UsePolling) { + polling(); + } + else { + var isPolling = prompt("usePolling", "gap_callbackServer:"); + cordova.UsePolling = isPolling; + if (isPolling == "true") { + cordova.UsePolling = true; + polling(); + } else { + cordova.UsePolling = false; + callback(); + } + } + }, 1); + + // Inject a listener for the backbutton on the document. + var backButtonChannel = cordova.addDocumentEventHandler('backbutton', { + onSubscribe:function() { + // If we just attached the first handler, let native know we need to override the back button. + if (this.numHandlers === 1) { + exec(null, null, "App", "overrideBackbutton", [true]); + } + }, + onUnsubscribe:function() { + // If we just detached the last handler, let native know we no longer override the back button. + if (this.numHandlers === 0) { + exec(null, null, "App", "overrideBackbutton", [false]); + } + } + }); + + // Add hardware MENU and SEARCH button handlers + cordova.addDocumentEventHandler('menubutton'); + cordova.addDocumentEventHandler('searchbutton'); + + // Figure out if we need to shim-in localStorage and WebSQL + // support from the native side. + var storage = require('cordova/plugin/android/storage'); + + // First patch WebSQL if necessary + if (typeof window.openDatabase == 'undefined') { + // Not defined, create an openDatabase function for all to use! + window.openDatabase = storage.openDatabase; + } else { + // Defined, but some Android devices will throw a SECURITY_ERR - + // so we wrap the whole thing in a try-catch and shim in our own + // if the device has Android bug 16175. + var originalOpenDatabase = window.openDatabase; + window.openDatabase = function(name, version, desc, size) { + var db = null; + try { + db = originalOpenDatabase(name, version, desc, size); + } + catch (ex) { + if (ex.code === 18) { + db = null; + } else { + throw ex; + } + } + + if (db === null) { + return storage.openDatabase(name, version, desc, size); + } + else { + return db; + } + + }; + } + + // Patch localStorage if necessary + if (typeof window.localStorage == 'undefined' || window.localStorage === null) { + window.localStorage = new storage.CupcakeLocalStorage(); + } + + // Let native code know we are all done on the JS side. + // Native code will then un-hide the WebView. + channel.join(function() { + prompt("", "gap_init:"); + }, [channel.onCordovaReady]); + }, + objects: { + cordova: { + children: { + JSCallback:{ + path:"cordova/plugin/android/callback" + }, + JSCallbackPolling:{ + path:"cordova/plugin/android/polling" + } + } + }, + navigator: { + children: { + app:{ + path: "cordova/plugin/android/app" + } + } + }, + device:{ + path: "cordova/plugin/android/device" + }, + File: { // exists natively on Android WebView, override + path: "cordova/plugin/File" + }, + FileReader: { // exists natively on Android WebView, override + path: "cordova/plugin/FileReader" + }, + FileError: { //exists natively on Android WebView on Android 4.x + path: "cordova/plugin/FileError" + }, + MediaError: { // exists natively on Android WebView on Android 4.x + path: "cordova/plugin/MediaError" + } + }, + merges: { + navigator: { + children: { + notification: { + path: 'cordova/plugin/android/notification' + } + } + } + } +}; + +}); + +// 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) { + // 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 (options && typeof options.quality == "number") { + quality = options.quality; + } else if (options && 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; + } + + exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions]); +}; + +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 occured + * @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.} phoneNumbers array of phone numbers +* @param {Array.} emails array of email addresses +* @param {Array.} addresses array of addresses +* @param {Array.} ims instant messaging user ids +* @param {Array.} organizations +* @param {DOMString} birthday contact's birthday +* @param {DOMString} note user notes about contact +* @param {Array.} photos +* @param {Array.} categories +* @param {Array.} 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 occured + * @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) + * {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 excluively 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 excluively 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][;base64], + * + * @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) { + console.log('root.name ' + name); + console.log('root.root ' + 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'); + +/** + * FileTransfer uploads a file to a remote server. + * @constructor + */ +var FileTransfer = function() {}; + +/** +* 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; + if (options) { + fileKey = options.fileKey; + fileName = options.fileName; + mimeType = options.mimeType; + 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); + }; + + exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]); +}; + +/** + * 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 + */ +FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) { + // sanity parameter checking + if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum."); + var win = function(result) { + 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]); +}; + +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; + +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. + */ +var FileUploadOptions = function(fileKey, fileName, mimeType, params) { + this.fileKey = fileKey || null; + this.fileName = fileName || null; + this.mimeType = mimeType || null; + this.params = params || 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 then 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/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; + me.successCallback(); + }, 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(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); +}; + +/** + * Stop recording audio file. + */ +Media.prototype.stopRecord = function() { + exec(this.successCallback, 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 status The status code (int) + * @param msg The status message (string) + */ +Media.onStatus = function(id, msg, value) { + var media = mediaObjects[id]; + // If state update + if (msg === Media.MEDIA_STATE) { + if (value === Media.MEDIA_STOPPED) { + if (media.successCallback) { + media.successCallback(); + } + } + if (media.statusCallback) { + media.statusCallback(value); + } + } + else if (msg === Media.MEDIA_DURATION) { + media._duration = value; + } + else if (msg === Media.MEDIA_ERROR) { + if (media.errorCallback) { + // value should be a MediaError object when msg == MEDIA_ERROR + media.errorCallback(value); + } + } + else if (msg === Media.MEDIA_POSITION) { + media._position = value; + } +}; + +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. + * @constructor + */ +var MediaError = function(code, msg) { + this.code = (code !== undefined ? code : null); + this.message = msg || ""; +}; + +MediaError.MEDIA_ERR_NONE_ACTIVE = 0; +MediaError.MEDIA_ERR_ABORTED = 1; +MediaError.MEDIA_ERR_NETWORK = 2; +MediaError.MEDIA_ERR_DECODE = 3; +MediaError.MEDIA_ERR_NONE_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]); + } +}; + +// TODO: can we axe this? +/** + * Casts a PluginResult message property (array of objects) to an array of MediaFile objects + * (used in Objective-C and Android) + * + * @param {PluginResult} pluginResult + */ +MediaFile.cast = function(pluginResult) { + var mediaFiles = []; + for (var i=0; i.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 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. (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) { + successCallback(a); + removeListeners(p); + }; + var fail = function(e) { + errorCallback(e); + removeListeners(p); + }; + + p = createCallbackPair(win, fail); + listeners.push(p); + + if (!running) { + start(); + } + }, + + /** + * 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. (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) { + errorCallback(e); + removeListeners(p); + }); + 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 + 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/android/plugin/android/app.js +define("cordova/plugin/android/app", function(require, exports, module) { +var exec = require('cordova/exec'); + +module.exports = { + /** + * Clear the resource cache. + */ + clearCache:function() { + exec(null, null, "App", "clearCache", []); + }, + + /** + * Load the url into the webview or into new browser instance. + * + * @param url The URL to load + * @param props Properties that can be passed in to the activity: + * wait: int => wait msec before loading URL + * loadingDialog: "Title,Message" => display a native loading dialog + * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error + * clearHistory: boolean => clear webview history (default=false) + * openExternal: boolean => open in a new browser (default=false) + * + * Example: + * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000}); + */ + loadUrl:function(url, props) { + exec(null, null, "App", "loadUrl", [url, props]); + }, + + /** + * Cancel loadUrl that is waiting to be loaded. + */ + cancelLoadUrl:function() { + exec(null, null, "App", "cancelLoadUrl", []); + }, + + /** + * Clear web history in this web view. + * Instead of BACK button loading the previous web page, it will exit the app. + */ + clearHistory:function() { + exec(null, null, "App", "clearHistory", []); + }, + + /** + * Go to previous page displayed. + * This is the same as pressing the backbutton on Android device. + */ + backHistory:function() { + exec(null, null, "App", "backHistory", []); + }, + + /** + * Override the default behavior of the Android back button. + * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired. + * + * Note: The user should not have to call this method. Instead, when the user + * registers for the "backbutton" event, this is automatically done. + * + * @param override T=override, F=cancel override + */ + overrideBackbutton:function(override) { + exec(null, null, "App", "overrideBackbutton", [override]); + }, + + /** + * Exit and terminate the application. + */ + exitApp:function() { + return exec(null, null, "App", "exitApp", []); + } +}; +}); + +// file: lib/android/plugin/android/callback.js +define("cordova/plugin/android/callback", function(require, exports, module) { +var port = null, + token = null, + cordova = require('cordova'), + polling = require('cordova/plugin/android/polling'), + callback = function() { + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If polling flag was changed, start using polling from now on + if (cordova.UsePolling) { + polling(); + return; + } + + var xmlhttp = new XMLHttpRequest(); + + // Callback function when XMLHttpRequest is ready + xmlhttp.onreadystatechange=function(){ + if(xmlhttp.readyState === 4){ + + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If callback has JavaScript statement to execute + if (xmlhttp.status === 200) { + + // Need to url decode the response + var msg = decodeURIComponent(xmlhttp.responseText); + setTimeout(function() { + try { + var t = eval(msg); + } + catch (e) { + // If we're getting an error here, seeing the message will help in debugging + console.log("JSCallback: Message from Server: " + msg); + console.log("JSCallback Error: "+e); + } + }, 1); + setTimeout(callback, 1); + } + + // If callback ping (used to keep XHR request from timing out) + else if (xmlhttp.status === 404) { + setTimeout(callback, 10); + } + + // If security error + else if (xmlhttp.status === 403) { + console.log("JSCallback Error: Invalid token. Stopping callbacks."); + } + + // If server is stopping + else if (xmlhttp.status === 503) { + console.log("JSCallback Server Closed: Stopping callbacks."); + } + + // If request wasn't GET + else if (xmlhttp.status === 400) { + console.log("JSCallback Error: Bad request. Stopping callbacks."); + } + + // If error, revert to polling + else { + console.log("JSCallback Error: Request failed."); + cordova.UsePolling = true; + polling(); + } + } + }; + + if (port === null) { + port = prompt("getPort", "gap_callbackServer:"); + } + if (token === null) { + token = prompt("getToken", "gap_callbackServer:"); + } + xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true); + xmlhttp.send(); +}; + +module.exports = callback; +}); + +// file: lib/android/plugin/android/device.js +define("cordova/plugin/android/device", function(require, exports, module) { +var channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'); + +/** + * 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.subscribeOnce(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", []); +}; + +/* + * DEPRECATED + * This is only for Android. + * + * You must explicitly override the back button. + */ +Device.prototype.overrideBackButton = function() { + console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true)."); + navigator.app.overrideBackbutton(true); +}; + +/* + * DEPRECATED + * This is only for Android. + * + * This resets the back button to the default behaviour + */ +Device.prototype.resetBackButton = function() { + console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); + navigator.app.overrideBackbutton(false); +}; + +/* + * DEPRECATED + * This is only for Android. + * + * This terminates the activity! + */ +Device.prototype.exitApp = function() { + console.log("Device.exitApp() is deprecated. Use App.exitApp()."); + navigator.app.exitApp(); +}; + +module.exports = new Device(); +}); + +// file: lib/android/plugin/android/notification.js +define("cordova/plugin/android/notification", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides Android enhanced notification API. + */ +module.exports = { + activityStart : function(title, message) { + // If title and message not specified then mimic Android behavior of + // using default strings. + if (typeof title === "undefined" && typeof message == "undefined") { + title = "Busy"; + message = 'Please wait...'; + } + + exec(null, null, 'Notification', 'activityStart', [ title, message ]); + }, + + /** + * Close an activity dialog + */ + activityStop : function() { + exec(null, null, 'Notification', 'activityStop', []); + }, + + /** + * Display a progress dialog with progress bar that goes from 0 to 100. + * + * @param {String} + * title Title of the progress dialog. + * @param {String} + * message Message to display in the dialog. + */ + progressStart : function(title, message) { + exec(null, null, 'Notification', 'progressStart', [ title, message ]); + }, + + /** + * Close the progress dialog. + */ + progressStop : function() { + exec(null, null, 'Notification', 'progressStop', []); + }, + + /** + * Set the progress dialog value. + * + * @param {Number} + * value 0-100 + */ + progressValue : function(value) { + exec(null, null, 'Notification', 'progressValue', [ value ]); + } +}; +}); + +// file: lib/android/plugin/android/polling.js +define("cordova/plugin/android/polling", function(require, exports, module) { +var cordova = require('cordova'), + period = 50, + polling = function() { + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If polling flag was changed, stop using polling from now on and switch to XHR server / callback + if (!cordova.UsePolling) { + require('cordova/plugin/android/callback')(); + return; + } + + var msg = prompt("", "gap_poll:"); + if (msg) { + setTimeout(function() { + try { + var t = eval(""+msg); + } + catch (e) { + console.log("JSCallbackPolling: Message from Server: " + msg); + console.log("JSCallbackPolling Error: "+e); + } + }, 1); + setTimeout(polling, 1); + } + else { + setTimeout(polling, period); + } +}; + +module.exports = polling; +}); + +// file: lib/android/plugin/android/storage.js +define("cordova/plugin/android/storage", function(require, exports, module) { +var utils = require('cordova/utils'), + exec = require('cordova/exec'), + channel = require('cordova/channel'); + +var queryQueue = {}; + +/** + * SQL result set object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Rows = function() { + this.resultSet = []; // results array + this.length = 0; // number of rows +}; + +/** + * Get item from SQL result set + * + * @param row The row number to return + * @return The row object + */ +DroidDB_Rows.prototype.item = function(row) { + return this.resultSet[row]; +}; + +/** + * SQL result set that is returned to user. + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Result = function() { + this.rows = new DroidDB_Rows(); +}; + +/** + * Callback from native code when query is complete. + * PRIVATE METHOD + * + * @param id Query id + */ +function completeQuery(id, data) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + + // Save query results + var r = new DroidDB_Result(); + r.rows.resultSet = data; + r.rows.length = data.length; + try { + if (typeof query.successCallback === 'function') { + query.successCallback(query.tx, r); + } + } catch (ex) { + console.log("executeSql error calling user success callback: "+ex); + } + + tx.queryComplete(id); + } + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * Callback from native code when query fails + * PRIVATE METHOD + * + * @param reason Error message + * @param id Query id + */ +function failQuery(reason, id) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + tx.queryList = {}; + + try { + if (typeof query.errorCallback === 'function') { + query.errorCallback(query.tx, reason); + } + } catch (ex) { + console.log("executeSql error calling user error callback: "+ex); + } + + tx.queryFailed(id, reason); + } + + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * SQL query object + * PRIVATE METHOD + * + * @constructor + * @param tx The transaction object that this query belongs to + */ +var DroidDB_Query = function(tx) { + + // Set the id of the query + this.id = utils.createUUID(); + + // Add this query to the queue + queryQueue[this.id] = this; + + // Init result + this.resultSet = []; + + // Set transaction that this query belongs to + this.tx = tx; + + // Add this query to transaction list + this.tx.queryList[this.id] = this; + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + +}; + +/** + * Transaction object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Tx = function() { + + // Set the id of the transaction + this.id = utils.createUUID(); + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + + // Query list + this.queryList = {}; +}; + +/** + * Mark query in transaction as complete. + * If all queries are complete, call the user's transaction success callback. + * + * @param id Query id + */ +DroidDB_Tx.prototype.queryComplete = function(id) { + delete this.queryList[id]; + + // If no more outstanding queries, then fire transaction success + if (this.successCallback) { + var count = 0; + var i; + for (i in this.queryList) { + if (this.queryList.hasOwnProperty(i)) { + count++; + } + } + if (count === 0) { + try { + this.successCallback(); + } catch(e) { + console.log("Transaction error calling user success callback: " + e); + } + } + } +}; + +/** + * Mark query in transaction as failed. + * + * @param id Query id + * @param reason Error message + */ +DroidDB_Tx.prototype.queryFailed = function(id, reason) { + + // The sql queries in this transaction have already been run, since + // we really don't have a real transaction implemented in native code. + // However, the user callbacks for the remaining sql queries in transaction + // will not be called. + this.queryList = {}; + + if (this.errorCallback) { + try { + this.errorCallback(reason); + } catch(e) { + console.log("Transaction error calling user error callback: " + e); + } + } +}; + +/** + * Execute SQL statement + * + * @param sql SQL statement to execute + * @param params Statement parameters + * @param successCallback Success callback + * @param errorCallback Error callback + */ +DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) { + + // Init params array + if (typeof params === 'undefined') { + params = []; + } + + // Create query and add to queue + var query = new DroidDB_Query(this); + queryQueue[query.id] = query; + + // Save callbacks + query.successCallback = successCallback; + query.errorCallback = errorCallback; + + // Call native code + exec(null, null, "Storage", "executeSql", [sql, params, query.id]); +}; + +var DatabaseShell = function() { +}; + +/** + * Start a transaction. + * Does not support rollback in event of failure. + * + * @param process {Function} The transaction function + * @param successCallback {Function} + * @param errorCallback {Function} + */ +DatabaseShell.prototype.transaction = function(process, errorCallback, successCallback) { + var tx = new DroidDB_Tx(); + tx.successCallback = successCallback; + tx.errorCallback = errorCallback; + try { + process(tx); + } catch (e) { + console.log("Transaction error: "+e); + if (tx.errorCallback) { + try { + tx.errorCallback(e); + } catch (ex) { + console.log("Transaction error calling user error callback: "+e); + } + } + } +}; + +/** + * Open database + * + * @param name Database name + * @param version Database version + * @param display_name Database display name + * @param size Database size in bytes + * @return Database object + */ +var DroidDB_openDatabase = function(name, version, display_name, size) { + exec(null, null, "Storage", "openDatabase", [name, version, display_name, size]); + var db = new DatabaseShell(); + return db; +}; + +/** + * For browsers with no localStorage we emulate it with SQLite. Follows the w3c api. + * TODO: Do similar for sessionStorage. + * @constructor + */ +var CupcakeLocalStorage = function() { + channel.waitForInitialization("cupcakeStorage"); + + try { + + this.db = openDatabase('localStorage', '1.0', 'localStorage', 2621440); + var storage = {}; + this.length = 0; + function setLength (length) { + this.length = length; + localStorage.length = length; + } + this.db.transaction( + function (transaction) { + var i; + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('SELECT * FROM storage', [], function(tx, result) { + for(var i = 0; i < result.rows.length; i++) { + storage[result.rows.item(i).id] = result.rows.item(i).body; + } + setLength(result.rows.length); + channel.initializationComplete("cupcakeStorage"); + }); + + }, + function (err) { + utils.alert(err.message); + } + ); + this.setItem = function(key, val) { + if (typeof(storage[key])=='undefined') { + this.length++; + } + storage[key] = val; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('REPLACE INTO storage (id, body) values(?,?)', [key,val]); + } + ); + }; + this.getItem = function(key) { + return storage[key]; + }; + this.removeItem = function(key) { + delete storage[key]; + this.length--; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('DELETE FROM storage where id=?', [key]); + } + ); + }; + this.clear = function() { + storage = {}; + this.length = 0; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('DELETE FROM storage', []); + } + ); + }; + this.key = function(index) { + var i = 0; + for (var j in storage) { + if (i==index) { + return j; + } else { + i++; + } + } + return null; + }; + + } catch(e) { + utils.alert("Database error "+e+"."); + return; + } +}; + +module.exports = { + openDatabase:DroidDB_openDatabase, + CupcakeLocalStorage:CupcakeLocalStorage, + failQuery:failQuery, + completeQuery:completeQuery +}; + +}); + +// 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) + var subscriptionEvents = { + onSubscribe:this.onSubscribe, + onUnsubscribe:this.onUnsubscribe + }; + this.channels = { + batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents), + batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents), + batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents) + }; +}; +/** + * 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.prototype.onSubscribe = function() { + var me = battery; + // If we just registered the first handler, make sure native listener is started. + if (handlers() === 1) { + exec(me._status, me._error, "Battery", "start", []); + } +}; + +Battery.prototype.onUnsubscribe = function() { + var me = battery; + + // If we just unregistered the last handler, make sure native listener is stopped. + 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 wrapperedOrigCall(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] = wrapperedOrigCall(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 who's 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/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 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 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 = null; + + var win = function(p) { + clearTimeout(timeoutTimer); + if (!timeoutTimer) { + // 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); + timeoutTimer = 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 exceed's 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 = 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 = 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]); + var err = new PositionError(e.code, e.message); + if (errorCallback) { + errorCallback(err); + } + }; + + var win = function(p) { + clearTimeout(timers[id]); + if (options.timeout !== Infinity) { + timers[id] = 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]); + delete timers[id]; + exec(null, null, "Geolocation", "clearWatch", [id]); + } + } +}; + +module.exports = geolocation; + +}); + +// 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 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 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/common/utils.js +define("cordova/utils", function(require, exports, module) { +var utils = exports; + +/** + * 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 wrappered 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 (alert) { + 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 + + + + \ No newline at end of file diff --git a/res/menu/activity_main.xml b/res/menu/activity_main.xml new file mode 100644 index 0000000..cfc10fd --- /dev/null +++ b/res/menu/activity_main.xml @@ -0,0 +1,6 @@ + + + diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml new file mode 100644 index 0000000..5c4a502 --- /dev/null +++ b/res/values-large/dimens.xml @@ -0,0 +1,7 @@ + + + 8dp + 16dp + 16dp + + \ No newline at end of file diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml new file mode 100644 index 0000000..d408cbc --- /dev/null +++ b/res/values-v11/styles.xml @@ -0,0 +1,5 @@ + + +