merging 2.9.1->2.9.x
diff --git a/common/Plugins/Accelerometer.cs b/common/Plugins/Accelerometer.cs
index cba911c..c06cc20 100644
--- a/common/Plugins/Accelerometer.cs
+++ b/common/Plugins/Accelerometer.cs
@@ -114,6 +114,11 @@
         /// <returns>status of listener</returns>
         public void start(string options)
         {
+            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+            string callbackId = args[0];
+
+            //Debug.WriteLine("start called with callbackId : " + callbackId);
+
             if ((currentStatus == Running) || (currentStatus == Starting))
             {
                 return;
@@ -137,23 +142,28 @@
                 if (currentStatus != Running)
                 {
                     this.SetStatus(ErrorFailedToStart);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart), callbackId);
                     return;
                 }
             }
             catch (Exception)
             {
                 this.SetStatus(ErrorFailedToStart);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart), callbackId);
                 return;
             }
             PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
             result.KeepCallback = true;
-            DispatchCommandResult(result);
+            DispatchCommandResult(result, callbackId);
         }
 
         public void stop(string options)
         {
+            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+            string callbackId = args[0];
+
+            //Debug.WriteLine("stop called with callbackId : " + callbackId);
+
             if (currentStatus == Running)
             {
                 lock (accelerometer)
@@ -163,7 +173,7 @@
                     this.SetStatus(Stopped);
                 }
             }
-            DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+            DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
         }
 
         /// <summary>
diff --git a/common/Plugins/AudioPlayer.cs b/common/Plugins/AudioPlayer.cs
index cc65939..f103cf5 100644
--- a/common/Plugins/AudioPlayer.cs
+++ b/common/Plugins/AudioPlayer.cs
@@ -27,6 +27,7 @@
 
 namespace WPCordovaClassLib.Cordova.Commands
 {
+
     /// <summary>
     /// Implements audio record and play back functionality.
     /// </summary>
@@ -62,6 +63,7 @@
 
         #endregion
 
+
         /// <summary>
         /// The AudioHandler object
         /// </summary>
@@ -77,6 +79,7 @@
         /// </summary>
         DispatcherTimer dtXna;
 
+
         /// <summary>
         /// Output buffer
         /// </summary>
@@ -128,6 +131,7 @@
             this.id = id;
         }
 
+
         /// <summary>
         /// Destroys player and stop audio playing or recording
         /// </summary>
@@ -194,8 +198,26 @@
                     this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
                     this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
                     this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
-                    this.memoryStream = new MemoryStream();
-                    this.memoryStream.InitializeWavStream(this.recorder.SampleRate);
+                    MemoryStream stream = new MemoryStream();
+                    this.memoryStream = stream;
+                    int numBits = 16;
+                    int numBytes = numBits / 8;
+
+                    // inline version from AudioFormatsHelper
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
+                    stream.Write(BitConverter.GetBytes(0), 0, 4);
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
+                    stream.Write(BitConverter.GetBytes(16), 0, 4);
+                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
+                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
+                    stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
+                    stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
+                    stream.Write(BitConverter.GetBytes(0), 0, 4);
+
                     this.recorder.Start();
                     FrameworkDispatcher.Update();
                     this.SetState(PlayerState_Running);
@@ -284,7 +306,7 @@
                                 {
                                     this.player.Stop(); // stop it!
                                 }
-                                
+
                                 this.player.Source = null; // Garbage collect it.
                                 this.player.MediaOpened += MediaOpened;
                                 this.player.MediaEnded += MediaEnded;
@@ -312,7 +334,7 @@
                                 {
                                     using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
                                     {
-                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);          
+                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
 
                                         string[] dirParts = filePath.Split('/');
                                         string dirName = "";
@@ -410,10 +432,7 @@
         /// </summary>
         private void MediaFailed(object sender, RoutedEventArgs arg)
         {
-            if (player != null)
-            {
-                player.Stop();
-            }
+            player.Stop();
             InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
             //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
         }
@@ -558,12 +577,17 @@
         /// <returns></returns>
         private void SaveAudioClipToLocalStorage()
         {
-            if (this.memoryStream == null || this.memoryStream.Length <= 0)
+            if (memoryStream == null || memoryStream.Length <= 0)
             {
                 return;
             }
 
-            this.memoryStream.UpdateWavStream();
+            long position = memoryStream.Position;
+            memoryStream.Seek(4, SeekOrigin.Begin);
+            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
+            memoryStream.Seek(40, SeekOrigin.Begin);
+            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
+            memoryStream.Seek(position, SeekOrigin.Begin);
 
             try
             {
@@ -589,7 +613,7 @@
                 //TODO: log or do something else
                 throw;
             }
-        }    
+        }
 
         #region Xna loop
         /// <summary>
@@ -620,4 +644,4 @@
 
         #endregion
     }
-}
+}
\ No newline at end of file
diff --git a/common/Plugins/Compass.cs b/common/Plugins/Compass.cs
index c9e1c4d..148fb62 100644
--- a/common/Plugins/Compass.cs
+++ b/common/Plugins/Compass.cs
@@ -140,6 +140,9 @@
 
         public void getHeading(string options)
         {
+            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
+            string callbackId = args[1];
+
             if (!DeviceCompass.IsSupported)
             {
                 DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "{code:" + Not_Supported + "}"));
@@ -180,7 +183,7 @@
 
                     if (currentStatus != Running)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart), callbackId);
                         return;
                     }
                 }
@@ -196,11 +199,11 @@
             }
             catch (UnauthorizedAccessException)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart), callbackId);
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart), callbackId);
             }
         }
 
@@ -252,6 +255,7 @@
 
         public void startWatch(string options)
         {
+
             if (!DeviceCompass.IsSupported)
             {
                 DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
diff --git a/common/Plugins/Contacts.cs b/common/Plugins/Contacts.cs
index af78942..5d861a1 100644
--- a/common/Plugins/Contacts.cs
+++ b/common/Plugins/Contacts.cs
@@ -443,7 +443,10 @@
             List<Contact> foundContacts = null;
 
             // if we have multiple search fields
-            if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
+            if (searchParams.options.filter != null && 
+                searchParams.options.filter.Length > 0 &&
+                searchParams.fields != null && 
+                searchParams.fields.Count() > 1)
             {
                 foundContacts = new List<Contact>();
                 if (searchParams.fields.Contains("emails"))
diff --git a/common/Plugins/FileTransfer.cs b/common/Plugins/FileTransfer.cs
index e585895..4f99e06 100644
--- a/common/Plugins/FileTransfer.cs
+++ b/common/Plugins/FileTransfer.cs
@@ -1,10 +1,10 @@
-/*  
+/*
 	Licensed 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.
@@ -30,115 +30,63 @@
         {
             // This class stores the State of the request.
             public HttpWebRequest request;
-            public DownloadOptions options;
+            public TransferOptions options;
+            public bool isCancelled;
 
             public DownloadRequestState()
             {
                 request = null;
                 options = null;
+                isCancelled = false;
+            }
+        }
+
+
+        public class TransferOptions
+        {
+            /// File path to upload  OR File path to download to
+            public string FilePath { get; set; }
+
+            public string Url { get; set; }
+            /// Flag to recognize if we should trust every host (only in debug environments)
+            public bool TrustAllHosts { get; set; }
+            public string Id { get; set; }
+            public string Headers { get; set; }
+            public string CallbackId { get; set; }
+            public bool ChunkedMode { get; set; }
+            /// Server address
+            public string Server { get; set; }
+            /// File key
+            public string FileKey { get; set; }
+            /// File name on the server
+            public string FileName { get; set; }
+            /// File Mime type
+            public string MimeType { get; set; }
+            /// Additional options
+            public string Params { get; set; }
+            public string Method { get; set; }
+
+            public TransferOptions()
+            {
+                FileKey = "file";
+                FileName = "image.jpg";
+                MimeType = "image/jpeg";
             }
         }
 
         /// <summary>
         /// Boundary symbol
-        /// </summary>       
+        /// </summary>
         private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
 
         // Error codes
         public const int FileNotFoundError = 1;
         public const int InvalidUrlError = 2;
         public const int ConnectionError = 3;
+        public const int AbortError = 4; // not really an error, but whatevs
 
-        /// <summary>
-        /// Options for downloading file
-        /// </summary>
-        [DataContract]
-        public class DownloadOptions
-        {
-            /// <summary>
-            /// File path to download to
-            /// </summary>
-            [DataMember(Name = "filePath", IsRequired = true)]
-            public string FilePath { get; set; }
+        private static Dictionary<string, DownloadRequestState> InProcDownloads = new Dictionary<string, DownloadRequestState>();
 
-            /// <summary>
-            /// Server address to the file to download
-            /// </summary>
-            [DataMember(Name = "url", IsRequired = true)]
-            public string Url { get; set; }
-        }
-
-        /// <summary>
-        /// Options for uploading file
-        /// </summary>
-        [DataContract]
-        public class UploadOptions
-        {
-            /// <summary>
-            /// File path to upload
-            /// </summary>
-            [DataMember(Name = "filePath", IsRequired = true)]
-            public string FilePath { get; set; }
-
-            /// <summary>
-            /// Server address
-            /// </summary>
-            [DataMember(Name = "server", IsRequired = true)]
-            public string Server { get; set; }
-
-            /// <summary>
-            /// File key
-            /// </summary>
-            [DataMember(Name = "fileKey")]
-            public string FileKey { get; set; }
-
-            /// <summary>
-            /// File name on the server
-            /// </summary>
-            [DataMember(Name = "fileName")]
-            public string FileName { get; set; }
-
-            /// <summary>
-            /// File Mime type
-            /// </summary>
-            [DataMember(Name = "mimeType")]
-            public string MimeType { get; set; }
-
-
-            /// <summary>
-            /// Additional options
-            /// </summary>
-            [DataMember(Name = "params")]
-            public string Params { get; set; }
-
-            /// <summary>
-            /// Flag to recognize if we should trust every host (only in debug environments)
-            /// </summary>
-            [DataMember(Name = "debug")]
-            public bool Debug { get; set; }
-
-            /// <summary>
-            /// Creates options object with default parameters
-            /// </summary>
-            public UploadOptions()
-            {
-                this.SetDefaultValues(new StreamingContext());
-            }
-
-            /// <summary>
-            /// Initializes default values for class fields.
-            /// Implemented in separate method because default constructor is not invoked during deserialization.
-            /// </summary>
-            /// <param name="context"></param>
-            [OnDeserializing()]
-            public void SetDefaultValues(StreamingContext context)
-            {
-                this.FileKey = "file";
-                this.FileName = "image.jpg";
-                this.MimeType = "image/jpeg";
-            }
-
-        }
 
         /// <summary>
         /// Uploading response info
@@ -177,7 +125,6 @@
                 this.Response = response;
             }
         }
-
         /// <summary>
         /// Represents transfer error codes for callback
         /// </summary>
@@ -199,9 +146,13 @@
             /// <summary>
             /// The target URI
             /// </summary>
+            ///
             [DataMember(Name = "target", IsRequired = true)]
             public string Target { get; set; }
 
+            [DataMember(Name = "body", IsRequired = true)]
+            public string Body { get; set; }
+
             /// <summary>
             /// The http status code response from the remote URI
             /// </summary>
@@ -218,20 +169,54 @@
                 this.Source = null;
                 this.Target = null;
                 this.HttpStatus = 0;
+                this.Body = "";
             }
-            public FileTransferError(int errorCode, string source, string target, int status)
+            public FileTransferError(int errorCode, string source, string target, int status, string body = "")
             {
                 this.Code = errorCode;
                 this.Source = source;
                 this.Target = target;
                 this.HttpStatus = status;
+                this.Body = body;
             }
         }
 
         /// <summary>
+        /// Represents a singular progress event to be passed back to javascript
+        /// </summary>
+        [DataContract]
+        public class FileTransferProgress
+        {
+            /// <summary>
+            /// Is the length of the response known?
+            /// </summary>
+            [DataMember(Name = "lengthComputable", IsRequired = true)]
+            public bool LengthComputable { get; set; }
+            /// <summary>
+            /// amount of bytes loaded
+            /// </summary>
+            [DataMember(Name = "loaded", IsRequired = true)]
+            public long BytesLoaded { get; set; }
+            /// <summary>
+            /// Total bytes
+            /// </summary>
+            [DataMember(Name = "total", IsRequired = false)]
+            public long BytesTotal { get; set; }
+
+            public FileTransferProgress(long bTotal = 0, long bLoaded = 0)
+            {
+                LengthComputable = bTotal > 0;
+                BytesLoaded = bLoaded;
+                BytesTotal = bTotal;
+            }
+
+
+        }
+
+        /// <summary>
         /// Upload options
         /// </summary>
-        private UploadOptions uploadOptions;
+        //private TransferOptions uploadOptions;
 
         /// <summary>
         /// Bytes sent
@@ -242,17 +227,46 @@
         /// sends a file to a server
         /// </summary>
         /// <param name="options">Upload options</param>
+        /// exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
         public void upload(string options)
         {
-            Debug.WriteLine("options = " + options);
-            options = options.Replace("{}", "null");
+            options = options.Replace("{}", ""); // empty objects screw up the Deserializer
+            string callbackId = "";
 
-            try 
+            TransferOptions uploadOptions = null;
+            HttpWebRequest webRequest = null;
+
+            try
             {
-                try 
+                try
                 {
                     string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                    uploadOptions = JSON.JsonHelper.Deserialize<UploadOptions>(args[0]);
+                    uploadOptions = new TransferOptions();
+                    uploadOptions.FilePath = args[0];
+                    uploadOptions.Server = args[1];
+                    uploadOptions.FileKey = args[2];
+                    uploadOptions.FileName = args[3];
+                    uploadOptions.MimeType = args[4];
+                    uploadOptions.Params = args[5];
+
+
+                    bool trustAll = false;
+                    bool.TryParse(args[6], out trustAll);
+                    uploadOptions.TrustAllHosts = trustAll;
+
+                    bool doChunked = false;
+                    bool.TryParse(args[7], out doChunked);
+                    uploadOptions.ChunkedMode = doChunked;
+
+                    //8 : Headers
+                    //9 : id
+                    //10: method
+
+                    uploadOptions.Headers = args[8];
+                    uploadOptions.Id = args[9];
+                    uploadOptions.Method = args[10];
+
+                    uploadOptions.CallbackId = callbackId = args[11];
                 }
                 catch (Exception)
                 {
@@ -270,29 +284,97 @@
                     DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
                     return;
                 }
-                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
+                webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
                 webRequest.ContentType = "multipart/form-data;boundary=" + Boundary;
-                webRequest.Method = "POST";
-                webRequest.BeginGetRequestStream(WriteCallback, webRequest);
+                webRequest.Method = uploadOptions.Method;
+
+                if (!string.IsNullOrEmpty(uploadOptions.Headers))
+                {
+                    Dictionary<string, string> headers = parseHeaders(uploadOptions.Headers);
+                    foreach (string key in headers.Keys)
+                    {
+                        webRequest.Headers[key] = headers[key];
+                    }
+                }
+
+                DownloadRequestState reqState = new DownloadRequestState();
+                reqState.options = uploadOptions;
+                reqState.request = webRequest;
+
+                InProcDownloads[uploadOptions.Id] = reqState;
+
+
+                webRequest.BeginGetRequestStream(uploadCallback, reqState);
             }
-            catch (Exception)
+            catch (Exception ex)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId);
+
+
             }
         }
 
+        // example : "{\"Authorization\":\"Basic Y29yZG92YV91c2VyOmNvcmRvdmFfcGFzc3dvcmQ=\"}"
+        protected Dictionary<string, string> parseHeaders(string jsonHeaders)
+        {
+            try
+            {
+                Dictionary<string, string> result = new Dictionary<string, string>();
+
+                string temp = jsonHeaders.StartsWith("{") ? jsonHeaders.Substring(1) : jsonHeaders;
+                temp = temp.EndsWith("}") ? temp.Substring(0, temp.Length - 1) : temp;
+
+                string[] strHeaders = temp.Split(',');
+                for (int n = 0; n < strHeaders.Length; n++)
+                {
+                    // we need to use indexOf in order to WP7 compatible
+                    int splitIndex = strHeaders[n].IndexOf(':');
+                    if (splitIndex > 0)
+                    {
+                        string[] split = new string[2];
+                        split[0] = strHeaders[n].Substring(0, splitIndex);
+                        split[1] = strHeaders[n].Substring(splitIndex + 1);
+
+                        split[0] = JSON.JsonHelper.Deserialize<string>(split[0]);
+                        split[1] = JSON.JsonHelper.Deserialize<string>(split[1]);
+                        result[split[0]] = split[1];
+                    }
+                }
+                return result;
+            }
+            catch (Exception)
+            {
+                Debug.WriteLine("Failed to parseHeaders from string :: " + jsonHeaders);
+            }
+            return null;
+        }
+
+
+
         public void download(string options)
         {
-            DownloadOptions downloadOptions = null;
+            TransferOptions downloadOptions = null;
             HttpWebRequest webRequest = null;
+            string callbackId;
 
             try
             {
+                // source, target, trustAllHosts, this._id, headers
                 string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
 
-                downloadOptions = new DownloadOptions();// JSON.JsonHelper.Deserialize<DownloadOptions>(options);
+                downloadOptions = new TransferOptions();
                 downloadOptions.Url = optionStrings[0];
                 downloadOptions.FilePath = optionStrings[1];
+
+                bool trustAll = false;
+                bool.TryParse(optionStrings[2], out trustAll);
+                downloadOptions.TrustAllHosts = trustAll;
+
+                downloadOptions.Id = optionStrings[3];
+                downloadOptions.Headers = optionStrings[4];
+                downloadOptions.CallbackId = callbackId = optionStrings[5];
+
             }
             catch (Exception)
             {
@@ -302,11 +384,94 @@
 
             try
             {
-                webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
+                // is the URL a local app file?
+                if (downloadOptions.Url.StartsWith("x-wmapp0") || downloadOptions.Url.StartsWith("file:"))
+                {
+                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+                    {
+                        // just copy from one area of iso-store to another ...
+                        if (isoFile.FileExists(downloadOptions.Url))
+                        {
+                            isoFile.CopyFile(downloadOptions.Url, downloadOptions.FilePath);
+                        }
+                        else
+                        {
+                            // need to unpack resource from the dll
+                            string cleanUrl = downloadOptions.Url.Replace("x-wmapp0:", "").Replace("file:", "");
+                            Uri uri = new Uri(cleanUrl, UriKind.Relative);
+                            var resource = Application.GetResourceStream(uri);
+
+                            if (resource != null)
+                            {
+                                // create the file destination
+                                if (!isoFile.FileExists(downloadOptions.FilePath))
+                                {
+                                    var destFile = isoFile.CreateFile(downloadOptions.FilePath);
+                                    destFile.Close();
+                                }
+
+                                using (FileStream fileStream = new IsolatedStorageFileStream(downloadOptions.FilePath, FileMode.Open, FileAccess.Write, isoFile))
+                                {
+                                    long totalBytes = resource.Stream.Length;
+                                    int bytesRead = 0;
+                                    using (BinaryReader reader = new BinaryReader(resource.Stream))
+                                    {
+                                        using (BinaryWriter writer = new BinaryWriter(fileStream))
+                                        {
+                                            int BUFFER_SIZE = 1024;
+                                            byte[] buffer;
+
+                                            while (true)
+                                            {
+                                                buffer = reader.ReadBytes(BUFFER_SIZE);
+                                                // fire a progress event ?
+                                                bytesRead += buffer.Length;
+                                                if (buffer.Length > 0)
+                                                {
+                                                    writer.Write(buffer);
+                                                    DispatchFileTransferProgress(bytesRead, totalBytes, callbackId);
+                                                }
+                                                else
+                                                {
+                                                    writer.Close();
+                                                    reader.Close();
+                                                    fileStream.Close();
+                                                    break;
+                                                }
+                                            }
+                                        }
+
+                                    }
+                                }
+                            }
+                        }
+
+                    }
+
+                    File.FileEntry entry = File.FileEntry.GetEntry(downloadOptions.FilePath);
+                    if (entry != null)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
+                    }
+                    else
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, File.NOT_FOUND_ERR), callbackId);
+                    }
+
+                    return;
+
+                }
+                else
+                {
+                    // otherwise it is web-bound, we will actually download it
+                    //Debug.WriteLine("Creating WebRequest for url : " + downloadOptions.Url);
+                    webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
+                }
             }
-            catch (Exception)
+            catch (Exception ex)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
+                                      new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
                 return;
             }
 
@@ -315,26 +480,103 @@
                 DownloadRequestState state = new DownloadRequestState();
                 state.options = downloadOptions;
                 state.request = webRequest;
-                webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
+                InProcDownloads[downloadOptions.Id] = state;
+
+                if (!string.IsNullOrEmpty(downloadOptions.Headers))
+                {
+                    Dictionary<string, string> headers = parseHeaders(downloadOptions.Headers);
+                    foreach (string key in headers.Keys)
+                    {
+                        webRequest.Headers[key] = headers[key];
+                    }
+                }
+
+                try
+                {
+                    webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
+                }
+                catch (WebException)
+                {
+                    // eat it
+                }
+                // dispatch an event for progress ( 0 )
+                lock (state)
+                {
+                    if (!state.isCancelled)
+                    {
+                        var plugRes = new PluginResult(PluginResult.Status.OK, new FileTransferProgress());
+                        plugRes.KeepCallback = true;
+                        plugRes.CallbackId = callbackId;
+                        DispatchCommandResult(plugRes, callbackId);
+                    }
+                }
             }
 
-
-
         }
 
+        public void abort(string options)
+        {
+            Debug.WriteLine("Abort :: " + options);
+            string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+            string id = optionStrings[0];
+            string callbackId = optionStrings[1];
+
+            if (InProcDownloads.ContainsKey(id))
+            {
+                DownloadRequestState state = InProcDownloads[id];
+                if (!state.isCancelled)
+                { // prevent multiple callbacks for the same abort
+                    state.isCancelled = true;
+                    if (!state.request.HaveResponse)
+                    {
+                        state.request.Abort();
+                        InProcDownloads.Remove(id);
+                        //callbackId = state.options.CallbackId;
+                        //state = null;
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
+                                                               new FileTransferError(FileTransfer.AbortError)),
+                                                               state.options.CallbackId);
+                    }
+                }
+
+            }
+            else
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION), callbackId); // TODO: is it an IO exception?
+            }
+        }
+
+        private void DispatchFileTransferProgress(long bytesLoaded, long bytesTotal, string callbackId, bool keepCallback = true)
+        {
+            Debug.WriteLine("DispatchFileTransferProgress : " + callbackId);
+            // send a progress change event
+            FileTransferProgress progEvent = new FileTransferProgress(bytesTotal);
+            progEvent.BytesLoaded = bytesLoaded;
+            PluginResult plugRes = new PluginResult(PluginResult.Status.OK, progEvent);
+            plugRes.KeepCallback = keepCallback;
+            plugRes.CallbackId = callbackId;
+            DispatchCommandResult(plugRes, callbackId);
+        }
+
         /// <summary>
-        /// 
+        ///
         /// </summary>
         /// <param name="asynchronousResult"></param>
         private void downloadCallback(IAsyncResult asynchronousResult)
         {
+
+
             DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
             HttpWebRequest request = reqState.request;
 
+            string callbackId = reqState.options.CallbackId;
             try
             {
                 HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
 
+                // send a progress change event
+                DispatchFileTransferProgress(0, response.ContentLength, callbackId);
+
                 using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                 {
                     // create the file if not exists
@@ -350,7 +592,6 @@
                         int bytesRead = 0;
                         using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
                         {
-
                             using (BinaryWriter writer = new BinaryWriter(fileStream))
                             {
                                 int BUFFER_SIZE = 1024;
@@ -361,9 +602,10 @@
                                     buffer = reader.ReadBytes(BUFFER_SIZE);
                                     // fire a progress event ?
                                     bytesRead += buffer.Length;
-                                    if (buffer.Length > 0)
+                                    if (buffer.Length > 0 && !reqState.isCancelled)
                                     {
                                         writer.Write(buffer);
+                                        DispatchFileTransferProgress(bytesRead, totalBytes, callbackId);
                                     }
                                     else
                                     {
@@ -372,47 +614,100 @@
                                         fileStream.Close();
                                         break;
                                     }
+                                    System.Threading.Thread.Sleep(1);
                                 }
                             }
 
                         }
-
-
                     }
+                    if (reqState.isCancelled)
+                    {
+                        isoFile.DeleteFile(reqState.options.FilePath);
+                    }
+
                 }
-                WPCordovaClassLib.Cordova.Commands.File.FileEntry entry = new WPCordovaClassLib.Cordova.Commands.File.FileEntry(reqState.options.FilePath);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry));
+
+                if (reqState.isCancelled)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(AbortError)),
+                  callbackId);
+
+                }
+                else
+                {
+                    File.FileEntry entry = new File.FileEntry(reqState.options.FilePath);
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
+                }
             }
             catch (IsolatedStorageException)
             {
                 // Trying to write the file somewhere within the IsoStorage.
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)),
+                                      callbackId);
             }
             catch (SecurityException)
             {
                 // Trying to write the file somewhere not allowed.
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)),
+                                      callbackId);
             }
             catch (WebException webex)
             {
                 // TODO: probably need better work here to properly respond with all http status codes back to JS
                 // Right now am jumping through hoops just to detect 404.
-                if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound) || webex.Status == WebExceptionStatus.UnknownError)
+                HttpWebResponse response = (HttpWebResponse)webex.Response;
+                if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound)
+                    || webex.Status == WebExceptionStatus.UnknownError)
                 {
+
                     // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
                     // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
                     // FACEPALM
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError, null, null, 404)));
+                    // Or just cast it to an int, whiner ... -jm
+                    int statusCode = (int)response.StatusCode;
+                    string body = "";
+
+                    using (Stream streamResponse = response.GetResponseStream())
+                    {
+                        using (StreamReader streamReader = new StreamReader(streamResponse))
+                        {
+                            body = streamReader.ReadToEnd();
+                        }
+                    }
+                    FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode, body);
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError),
+                                          callbackId);
                 }
                 else
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
+                    lock (reqState)
+                    {
+                        if (!reqState.isCancelled)
+                        {
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
+                                                                   new FileTransferError(ConnectionError)),
+                                                  callbackId);
+                        }
+                        else
+                        {
+                            Debug.WriteLine("It happened");
+                        }
+                    }
                 }
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
+                                                        new FileTransferError(FileNotFoundError)),
+                                      callbackId);
             }
+
+            //System.Threading.Thread.Sleep(1000);
+            if (InProcDownloads.ContainsKey(reqState.options.Id))
+            {
+                InProcDownloads.Remove(reqState.options.Id);
+            }
+
         }
 
 
@@ -421,11 +716,14 @@
         /// Read file from Isolated Storage and sends it to server
         /// </summary>
         /// <param name="asynchronousResult"></param>
-        private void WriteCallback(IAsyncResult asynchronousResult)
+        private void uploadCallback(IAsyncResult asynchronousResult)
         {
+            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
+            HttpWebRequest webRequest = reqState.request;
+            string callbackId = reqState.options.CallbackId;
+
             try
             {
-                HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
                 using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
                 {
                     string lineStart = "--";
@@ -433,18 +731,15 @@
                     byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
                     string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
 
-                    if (uploadOptions.Params != null)
+
+
+                    if (!string.IsNullOrEmpty(reqState.options.Params))
                     {
-
-                        string[] arrParams = uploadOptions.Params.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
-
-                        foreach (string param in arrParams)
+                        Dictionary<string, string> paramMap = parseHeaders(reqState.options.Params);
+                        foreach (string key in paramMap.Keys)
                         {
-                            string[] split = param.Split('=');
-                            string key = split[0];
-                            string val = split[1];
                             requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-                            string formItem = string.Format(formdataTemplate, key, val);
+                            string formItem = string.Format(formdataTemplate, key, paramMap[key]);
                             byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
                             requestStream.Write(formItemBytes, 0, formItemBytes.Length);
                         }
@@ -452,40 +747,59 @@
                     }
                     using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
                     {
-                        if (!isoFile.FileExists(uploadOptions.FilePath))
+                        if (!isoFile.FileExists(reqState.options.FilePath))
                         {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, uploadOptions.Server, uploadOptions.FilePath, 0)));
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, reqState.options.Server, reqState.options.FilePath, 0)));
                             return;
                         }
 
-                        using (FileStream fileStream = new IsolatedStorageFileStream(uploadOptions.FilePath, FileMode.Open, isoFile))
+                        byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
+                        long totalBytesToSend = 0;
+
+                        using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, isoFile))
                         {
+
                             string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
-                            string header = string.Format(headerTemplate, uploadOptions.FileKey, uploadOptions.FileName, uploadOptions.MimeType);
+                            string header = string.Format(headerTemplate, reqState.options.FileKey, reqState.options.FileName, reqState.options.MimeType);
                             byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
-                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-                            requestStream.Write(headerBytes, 0, headerBytes.Length);
+
                             byte[] buffer = new byte[4096];
                             int bytesRead = 0;
+                            totalBytesToSend = fileStream.Length;
+
+                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
+
+                            requestStream.Write(headerBytes, 0, headerBytes.Length);
 
                             while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                             {
-                                requestStream.Write(buffer, 0, bytesRead);
-                                bytesSent += bytesRead;
+                                if (!reqState.isCancelled)
+                                {
+                                    requestStream.Write(buffer, 0, bytesRead);
+                                    bytesSent += bytesRead;
+                                    DispatchFileTransferProgress(bytesSent, totalBytesToSend, callbackId);
+                                    System.Threading.Thread.Sleep(1);
+                                }
+                                else
+                                {
+                                    throw new Exception("UploadCancelledException");
+                                }
                             }
                         }
-                        byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
+
                         requestStream.Write(endRequest, 0, endRequest.Length);
                     }
                 }
-                webRequest.BeginGetResponse(ReadCallback, webRequest);
+                // webRequest
+
+                webRequest.BeginGetResponse(ReadCallback, reqState);
             }
-            catch (Exception)
+            catch (Exception ex)
             {
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                if (!reqState.isCancelled)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)));
-                });
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId);
+                }
             }
         }
 
@@ -495,9 +809,17 @@
         /// <param name="asynchronousResult"></param>
         private void ReadCallback(IAsyncResult asynchronousResult)
         {
+            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
             try
             {
-                HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
+                HttpWebRequest webRequest = reqState.request;
+                string callbackId = reqState.options.CallbackId;
+
+                if (InProcDownloads.ContainsKey(reqState.options.Id))
+                {
+                    InProcDownloads.Remove(reqState.options.Id);
+                }
+
                 using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
                 {
                     using (Stream streamResponse = response.GetResponseStream())
@@ -513,14 +835,30 @@
                     }
                 }
             }
-            catch (Exception)
+            catch (WebException webex)
             {
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                // TODO: probably need better work here to properly respond with all http status codes back to JS
+                // Right now am jumping through hoops just to detect 404.
+                if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound)
+                    || webex.Status == WebExceptionStatus.UnknownError)
                 {
-                    FileTransferError transferError = new FileTransferError(ConnectionError, uploadOptions.Server, uploadOptions.FilePath, 403);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError));
-                });
+                    int statusCode = (int)((HttpWebResponse)webex.Response).StatusCode;
+                    FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode);
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError), reqState.options.CallbackId);
+                }
+                else
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
+                                                           new FileTransferError(ConnectionError)),
+                                          reqState.options.CallbackId);
+                }
+            }
+            catch (Exception ex)
+            {
+                FileTransferError transferError = new FileTransferError(ConnectionError, reqState.options.Server, reqState.options.FilePath, 403);
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError), reqState.options.CallbackId);
+
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/common/Plugins/Media.cs b/common/Plugins/Media.cs
index 5de4884..74d53af 100644
--- a/common/Plugins/Media.cs
+++ b/common/Plugins/Media.cs
@@ -53,6 +53,8 @@
             /// </summary>
             [DataMember(Name = "milliseconds")]
             public int Milliseconds { get; set; }
+
+            public string CallbackId { get; set; }
         }
 
         /// <summary>
@@ -60,25 +62,26 @@
         /// </summary>  
         public void release(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
-                MediaOptions mediaOptions;
+                MediaOptions mediaOptions = new MediaOptions();
 
                 try
                 {
                     string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
                     mediaOptions.Id = optionsString[0];
+                    callbackId = mediaOptions.CallbackId = optionsString[1];
                 }
                 catch (Exception)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
                     return;
                 }
 
                 if (!Media.players.ContainsKey(mediaOptions.Id))
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false), callbackId);
                     return;
                 }
 
@@ -89,39 +92,58 @@
                         AudioPlayer audio = Media.players[mediaOptions.Id];
                         Media.players.Remove(mediaOptions.Id);
                         audio.Dispose();
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true), mediaOptions.CallbackId);
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), mediaOptions.CallbackId);
                     }
                 });
             }
             catch (Exception e)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
             }
         }
 
+        private AudioPlayer GetOrCreatePlayerById(string id)
+        {
+            AudioPlayer audio = null;
+
+            lock (Media.players)
+            {
+                if (!Media.players.TryGetValue(id, out audio))
+                {
+                    audio = new AudioPlayer(this, id);
+                    Media.players.Add(id, audio);
+                }
+            }
+
+
+
+            return audio;
+        }
+
         /// <summary>
         /// Starts recording and save the specified file 
         /// </summary>
         public void startRecordingAudio(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
-                MediaOptions mediaOptions;
+                MediaOptions mediaOptions = new MediaOptions();
 
                 try
                 {
                     string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
                     mediaOptions.Id = optionsString[0];
                     mediaOptions.Src = optionsString[1];
+                    callbackId = mediaOptions.CallbackId = optionsString[2];
                 }
                 catch (Exception)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), mediaOptions.CallbackId);
                     return;
                 }
 
@@ -146,30 +168,31 @@
                             if (audio != null)
                             {
                                 audio.startRecording(mediaOptions.Src);
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK), mediaOptions.CallbackId);
                             }
                             else
                             {
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
+                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
+                                                        "Error accessing AudioPlayer for key " + mediaOptions.Id), mediaOptions.CallbackId);
                             }
-                            
-                            
+
+
                         }
                         catch (Exception e)
                         {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), mediaOptions.CallbackId);
                         }
 
                     });
                 }
                 else
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), mediaOptions.CallbackId);
                 }
             }
             catch (Exception e)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
             }
         }
 
@@ -178,9 +201,13 @@
         /// </summary>
         public void stopRecordingAudio(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
+
             try
             {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                string[] optStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+                string mediaId = optStrings[0];
+                callbackId = optStrings[1];
                 Deployment.Current.Dispatcher.BeginInvoke(() =>
                 {
                     try
@@ -191,27 +218,31 @@
                             audio.stopRecording();
                             Media.players.Remove(mediaId);
                         }
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                     }
                 });
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
             }
         }
 
         public void setVolume(string options) // id,volume
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
                 string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
                 string id = optionsString[0];
-                double volume = double.Parse(optionsString[1]);
+                double volume = 0.0d;
+                double.TryParse(optionsString[1], out volume);
+
+                callbackId = optionsString[2];
 
                 if (Media.players.ContainsKey(id))
                 {
@@ -224,15 +255,15 @@
                         }
                         catch (Exception e)
                         {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                         }
                     });
                 }
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
-                return;
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION,
+                                                        "Error parsing options into setVolume method"), callbackId);
             }
         }
 
@@ -241,10 +272,10 @@
         // While playing, a MediaElement stops all other media playback on the phone.
         // Multiple MediaElement controls are NOT supported
 
-        // Called when you create a new Media('blah') object in JS.
+        // Called when you create a new Media('blah.wav') object in JS.
         public void create(string options)
         {
-            // Debug.WriteLine("Creating Audio :: " + options);
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
                 MediaOptions mediaOptions;
@@ -254,21 +285,22 @@
                     mediaOptions = new MediaOptions();
                     mediaOptions.Id = optionsString[0];
                     mediaOptions.Src = optionsString[1];
+                    callbackId = mediaOptions.CallbackId = optionsString[2];
                 }
                 catch (Exception)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION,
+                                            "Error parsing options into create method"), callbackId);
                     return;
                 }
 
-                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
-                Media.players.Add(mediaOptions.Id, audio);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                GetOrCreatePlayerById(mediaOptions.Id);
+                DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
 
             }
             catch (Exception e)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
             }
         }
 
@@ -277,6 +309,7 @@
         /// </summary>
         public void startPlayingAudio(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
                 MediaOptions mediaOptions;
@@ -286,47 +319,38 @@
                     mediaOptions = new MediaOptions();
                     mediaOptions.Id = optionsString[0];
                     mediaOptions.Src = optionsString[1];
-                    if (optionsString.Length > 2 && optionsString[2] != null)
+                    int msec = 0;
+                    if (int.TryParse(optionsString[2], out msec))
                     {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[2]);
+                        mediaOptions.Milliseconds = msec;
                     }
+                    callbackId = mediaOptions.CallbackId = optionsString[3];
 
                 }
                 catch (Exception)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
                     return;
                 }
 
-                AudioPlayer audio;
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players.Add(mediaOptions.Id, audio);
-                }
-                else
-                {
-                    //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
-                    audio = Media.players[mediaOptions.Id];
-                }
+                AudioPlayer audio = GetOrCreatePlayerById(mediaOptions.Id);
 
                 Deployment.Current.Dispatcher.BeginInvoke(() =>
                 {
                     try
                     {
                         audio.startPlaying(mediaOptions.Src);
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                     }
                 });
             }
             catch (Exception e)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
             }
         }
 
@@ -336,6 +360,7 @@
         /// </summary>
         public void seekToAudio(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
                 MediaOptions mediaOptions;
@@ -345,14 +370,17 @@
                     string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
                     mediaOptions = new MediaOptions();
                     mediaOptions.Id = optionsString[0];
-                    if (optionsString.Length > 1 && optionsString[1] != null)
+                    int msec = 0;
+                    if (int.TryParse(optionsString[2], out msec))
                     {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[1]);
+                        mediaOptions.Milliseconds = msec;
                     }
+                    callbackId = mediaOptions.CallbackId = optionsString[3];
+
                 }
                 catch (Exception)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
                     return;
                 }
 
@@ -370,17 +398,17 @@
                             Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
                         }
 
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                     }
                 });
             }
             catch (Exception e)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
             }
         }
 
@@ -389,10 +417,12 @@
         /// </summary>
         public void pausePlayingAudio(string options)
         {
-
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                string mediaId = optionsString[0];
+                callbackId = optionsString[1];
 
                 Deployment.Current.Dispatcher.BeginInvoke(() =>
                 {
@@ -408,11 +438,11 @@
                             Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
                         }
 
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                     }
                 });
 
@@ -420,7 +450,7 @@
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
             }
 
 
@@ -432,9 +462,12 @@
         /// </summary>
         public void stopPlayingAudio(String options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                string[] optionsStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+                string mediaId = optionsStrings[0];
+                callbackId = optionsStrings[1];
                 Deployment.Current.Dispatcher.BeginInvoke(() =>
                 {
                     try
@@ -449,18 +482,18 @@
                             Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
                         }
 
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                     }
                 });
 
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
             }
         }
 
@@ -469,9 +502,12 @@
         /// </summary>
         public void getCurrentPositionAudio(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                string[] optionsStrings = JSON.JsonHelper.Deserialize<string[]>(options);
+                string mediaId = optionsStrings[0];
+                callbackId = optionsStrings[1];
                 Deployment.Current.Dispatcher.BeginInvoke(() =>
                 {
                     try
@@ -479,22 +515,22 @@
                         if (Media.players.ContainsKey(mediaId))
                         {
                             AudioPlayer audio = Media.players[mediaId];
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()), callbackId);
                         }
                         else
                         {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1), callbackId);
                         }
                     }
                     catch (Exception e)
                     {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
                     }
                 });
             }
             catch (Exception)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
                 return;
             }
         }
@@ -503,21 +539,27 @@
         /// <summary>
         /// Gets the duration of the audio file
         /// </summary>
-        
+
         [Obsolete("This method will be removed shortly")]
         public void getDurationAudio(string options)
         {
+            string callbackId = this.CurrentCommandCallbackId;
             try
             {
                 MediaOptions mediaOptions;
 
                 try
                 {
-                    mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
+                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+
+                    mediaOptions = new MediaOptions();
+                    mediaOptions.Id = optionsString[0];
+                    mediaOptions.Src = optionsString[1];
+                    callbackId = mediaOptions.CallbackId = optionsString[2];
                 }
                 catch (Exception)
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
                     return;
                 }
 
@@ -535,13 +577,13 @@
 
                 Deployment.Current.Dispatcher.BeginInvoke(() =>
                 {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)), callbackId);
                 });
             }
             catch (Exception e)
             {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId);
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/common/resources/notification-beep.wav b/common/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
--- a/common/resources/notification-beep.wav
+++ /dev/null
Binary files differ
diff --git a/common/www/cordova.js b/common/www/cordova.js
index 60baeee..c000ff3 100644
--- a/common/www/cordova.js
+++ b/common/www/cordova.js
@@ -1,6791 +1,6251 @@
-// Platform: windowsphone
-// 2.9.0rc1-12-g83dc4bd
-/*
- 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() {
-var CORDOVA_JS_BUILD_LABEL = '2.9.0rc1-12-g83dc4bd';
-// file: lib/scripts/require.js
-
-var require,
-    define;
-
-(function () {
-    var modules = {},
-    // Stack of moduleIds currently being built.
-        requireStack = [],
-    // Map of module ID -> index into requireStack of modules currently being built.
-        inProgressModules = {},
-        SEPERATOR = ".";
-
-
-
-    function build(module) {
-        var factory = module.factory,
-            localRequire = function (id) {
-                var resultantId = id;
-                //Its a relative path, so lop off the last portion and add the id (minus "./")
-                if (id.charAt(0) === ".") {
-                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
-                }
-                return require(resultantId);
-            };
-        module.exports = {};
-        delete module.factory;
-        factory(localRequire, module.exports, module);
-        return module.exports;
-    }
-
-    require = function (id) {
-        if (!modules[id]) {
-            throw "module " + id + " not found";
-        } else if (id in inProgressModules) {
-            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
-            throw "Cycle in require graph: " + cycle;
-        }
-        if (modules[id].factory) {
-            try {
-                inProgressModules[id] = requireStack.length;
-                requireStack.push(id);
-                return build(modules[id]);
-            } finally {
-                delete inProgressModules[id];
-                requireStack.pop();
-            }
-        }
-        return modules[id].exports;
-    };
-
-    define = function (id, factory) {
-        if (modules[id]) {
-            throw "module " + id + " already defined";
-        }
-
-        modules[id] = {
-            id: id,
-            factory: factory
-        };
-    };
-
-    define.remove = function (id) {
-        delete modules[id];
-    };
-
-    define.moduleMap = modules;
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
-    module.exports.require = require;
-    module.exports.define = define;
-}
-
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-
-
-var channel = require('cordova/channel');
-
-/**
- * Listen for DOMContentLoaded and notify our channel subscribers.
- */
-document.addEventListener('DOMContentLoaded', function() {
-    channel.onDOMContentLoaded.fire();
-}, false);
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
-    channel.onDOMContentLoaded.fire();
-}
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
-    windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof documentEventHandlers[e] != 'undefined') {
-        documentEventHandlers[e].subscribe(handler);
-    } else {
-        m_document_addEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.addEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    if (typeof windowEventHandlers[e] != 'undefined') {
-        windowEventHandlers[e].subscribe(handler);
-    } else {
-        m_window_addEventListener.call(window, evt, handler, capture);
-    }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof documentEventHandlers[e] != "undefined") {
-        documentEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_document_removeEventListener.call(document, evt, handler, capture);
-    }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
-    var e = evt.toLowerCase();
-    // If unsubscribing from an event that is handled by a plugin
-    if (typeof windowEventHandlers[e] != "undefined") {
-        windowEventHandlers[e].unsubscribe(handler);
-    } else {
-        m_window_removeEventListener.call(window, evt, handler, capture);
-    }
-};
-
-function createEvent(type, data) {
-    var event = document.createEvent('Events');
-    event.initEvent(type, false, false);
-    if (data) {
-        for (var i in data) {
-            if (data.hasOwnProperty(i)) {
-                event[i] = data[i];
-            }
-        }
-    }
-    return event;
-}
-
-if(typeof window.console === "undefined") {
-    window.console = {
-        log:function(){}
-    };
-}
-
-var cordova = {
-    define:define,
-    require:require,
-    /**
-     * Methods to add/remove your own addEventListener hijacking on document + window.
-     */
-    addWindowEventHandler:function(event) {
-        return (windowEventHandlers[event] = channel.create(event));
-    },
-    addStickyDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.createSticky(event));
-    },
-    addDocumentEventHandler:function(event) {
-        return (documentEventHandlers[event] = channel.create(event));
-    },
-    removeWindowEventHandler:function(event) {
-        delete windowEventHandlers[event];
-    },
-    removeDocumentEventHandler:function(event) {
-        delete documentEventHandlers[event];
-    },
-    /**
-     * Retrieve original event handlers that were replaced by Cordova
-     *
-     * @return object
-     */
-    getOriginalHandlers: function() {
-        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
-        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
-    },
-    /**
-     * Method to fire event from native code
-     * bNoDetach is required for events which cause an exception which needs to be caught in native code
-     */
-    fireDocumentEvent: function(type, data, bNoDetach) {
-        var evt = createEvent(type, data);
-        if (typeof documentEventHandlers[type] != 'undefined') {
-            if( bNoDetach ) {
-              documentEventHandlers[type].fire(evt);
-            }
-            else {
-              setTimeout(function() {
-                  // Fire deviceready on listeners that were registered before cordova.js was loaded.
-                  if (type == 'deviceready') {
-                      document.dispatchEvent(evt);
-                  }
-                  documentEventHandlers[type].fire(evt);
-              }, 0);
-            }
-        } else {
-            document.dispatchEvent(evt);
-        }
-    },
-    fireWindowEvent: function(type, data) {
-        var evt = createEvent(type,data);
-        if (typeof windowEventHandlers[type] != 'undefined') {
-            setTimeout(function() {
-                windowEventHandlers[type].fire(evt);
-            }, 0);
-        } else {
-            window.dispatchEvent(evt);
-        }
-    },
-
-    /**
-     * Plugin callback mechanism.
-     */
-    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
-    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
-    callbackId: Math.floor(Math.random() * 2000000000),
-    callbacks:  {},
-    callbackStatus: {
-        NO_RESULT: 0,
-        OK: 1,
-        CLASS_NOT_FOUND_EXCEPTION: 2,
-        ILLEGAL_ACCESS_EXCEPTION: 3,
-        INSTANTIATION_EXCEPTION: 4,
-        MALFORMED_URL_EXCEPTION: 5,
-        IO_EXCEPTION: 6,
-        INVALID_ACTION: 7,
-        JSON_EXCEPTION: 8,
-        ERROR: 9
-    },
-
-    /**
-     * Called by native code when returning successful result from an action.
-     */
-    callbackSuccess: function(callbackId, args) {
-        try {
-            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning error result from an action.
-     */
-    callbackError: function(callbackId, args) {
-        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
-        // Derive success from status.
-        try {
-            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
-        } catch (e) {
-            console.log("Error in error callback: " + callbackId + " = "+e);
-        }
-    },
-
-    /**
-     * Called by native code when returning the result from an action.
-     */
-    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
-        var callback = cordova.callbacks[callbackId];
-        if (callback) {
-            if (success && status == cordova.callbackStatus.OK) {
-                callback.success && callback.success.apply(null, args);
-            } else if (!success) {
-                callback.fail && callback.fail.apply(null, args);
-            }
-
-            // Clear callback if not expecting any more results
-            if (!keepCallback) {
-                delete cordova.callbacks[callbackId];
-            }
-        }
-    },
-    addConstructor: function(func) {
-        channel.onCordovaReady.subscribe(function() {
-            try {
-                func();
-            } catch(e) {
-                console.log("Failed to run constructor: " + e);
-            }
-        });
-    }
-};
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
-
-module.exports = cordova;
-
-});
-
-// file: lib/common/argscheck.js
-define("cordova/argscheck", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var moduleExports = module.exports;
-
-var typeMap = {
-    'A': 'Array',
-    'D': 'Date',
-    'N': 'Number',
-    'S': 'String',
-    'F': 'Function',
-    'O': 'Object'
-};
-
-function extractParamName(callee, argIndex) {
-  return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
-}
-
-function checkArgs(spec, functionName, args, opt_callee) {
-    if (!moduleExports.enableChecks) {
-        return;
-    }
-    var errMsg = null;
-    var typeName;
-    for (var i = 0; i < spec.length; ++i) {
-        var c = spec.charAt(i),
-            cUpper = c.toUpperCase(),
-            arg = args[i];
-        // Asterix means allow anything.
-        if (c == '*') {
-            continue;
-        }
-        typeName = utils.typeName(arg);
-        if ((arg === null || arg === undefined) && c == cUpper) {
-            continue;
-        }
-        if (typeName != typeMap[cUpper]) {
-            errMsg = 'Expected ' + typeMap[cUpper];
-            break;
-        }
-    }
-    if (errMsg) {
-        errMsg += ', but got ' + typeName + '.';
-        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
-        // Don't log when running jake test.
-        if (typeof jasmine == 'undefined') {
-            console.error(errMsg);
-        }
-        throw TypeError(errMsg);
-    }
-}
-
-function getValue(value, defaultValue) {
-    return value === undefined ? defaultValue : value;
-}
-
-moduleExports.checkArgs = checkArgs;
-moduleExports.getValue = getValue;
-moduleExports.enableChecks = true;
-
-
-});
-
-// 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 clobber(obj, key, value) {
-    exports.replaceHookForTesting(obj, key);
-    obj[key] = value;
-    // Getters can only be overridden by getters.
-    if (obj[key] !== value) {
-        utils.defineGetter(obj, key, function() {
-            return value;
-        });
-    }
-}
-
-function assignOrWrapInDeprecateGetter(obj, key, value, message) {
-    if (message) {
-        utils.defineGetter(obj, key, function() {
-            console.log(message);
-            delete obj[key];
-            clobber(obj, key, value);
-            return value;
-        });
-    } else {
-        clobber(obj, key, value);
-    }
-}
-
-function include(parent, objects, clobber, merge) {
-    each(objects, function (obj, key) {
-        try {
-          var result = obj.path ? require(obj.path) : {};
-
-          if (clobber) {
-              // Clobber if it doesn't exist.
-              if (typeof parent[key] === 'undefined') {
-                  assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-              } else if (typeof obj.path !== 'undefined') {
-                  // If merging, merge properties onto parent, otherwise, clobber.
-                  if (merge) {
-                      recursiveMerge(parent[key], result);
-                  } else {
-                      assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-                  }
-              }
-              result = parent[key];
-          } else {
-            // Overwrite if not currently defined.
-            if (typeof parent[key] == 'undefined') {
-              assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
-            } else {
-              // 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 (target.prototype && target.prototype.constructor === target) {
-                // If the target object is a constructor override off prototype.
-                clobber(target.prototype, prop, src[prop]);
-            } else {
-                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
-                    recursiveMerge(target[prop], src[prop]);
-                } else {
-                    clobber(target, prop, src[prop]);
-                }
-            }
-        }
-    }
-}
-
-exports.buildIntoButDoNotClobber = function(objects, target) {
-    include(target, objects, false, false);
-};
-exports.buildIntoAndClobber = function(objects, target) {
-    include(target, objects, true, false);
-};
-exports.buildIntoAndMerge = function(objects, target) {
-    include(target, objects, true, true);
-};
-exports.recursiveMerge = recursiveMerge;
-exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
-exports.replaceHookForTesting = function() {};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    nextGuid = 1;
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization, as well as for custom events thereafter.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
- * onNativeReady*              Internal event that indicates the Cordova native side is ready.
- * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
- * onCordovaInfoReady*         Internal event fired when device properties are available.
- * onCordovaConnectionReady*   Internal event fired when the connection property has been set.
- * onDeviceReady*              User event fired to indicate that Cordova is ready
- * onResume                    User event fired to indicate a start/resume lifecycle event
- * onPause                     User event fired to indicate a pause lifecycle event
- * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
- * All listeners that subscribe after the event is fired will be executed right away.
- *
- * The only Cordova events that user code should register for are:
- *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
- *      pause                 App has moved to background
- *      resume                App has returned to foreground
- *
- * Listeners can be registered as:
- *      document.addEventListener("deviceready", myDeviceReadyListener, false);
- *      document.addEventListener("resume", myResumeListener, false);
- *      document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- *      window.onload
- *      window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type  String the channel name
- */
-var Channel = function(type, sticky) {
-    this.type = type;
-    // Map of guid -> function.
-    this.handlers = {};
-    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
-    this.state = sticky ? 1 : 0;
-    // Used in sticky mode to remember args passed to fire().
-    this.fireArgs = null;
-    // Used by onHasSubscribersChange to know if there are any listeners.
-    this.numHandlers = 0;
-    // Function that is called when the first listener is subscribed, or when
-    // the last listener is unsubscribed.
-    this.onHasSubscribersChange = null;
-},
-    channel = {
-        /**
-         * Calls the provided function only after all of the channels specified
-         * have been fired. All channels must be sticky channels.
-         */
-        join: function(h, c) {
-            var len = c.length,
-                i = len,
-                f = function() {
-                    if (!(--i)) h();
-                };
-            for (var j=0; j<len; j++) {
-                if (c[j].state === 0) {
-                    throw Error('Can only use join with sticky channels.');
-                }
-                c[j].subscribe(f);
-            }
-            if (!len) h();
-        },
-        create: function(type) {
-            return channel[type] = new Channel(type, false);
-        },
-        createSticky: function(type) {
-            return channel[type] = new Channel(type, true);
-        },
-
-        /**
-         * cordova Channels that must fire before "deviceready" is fired.
-         */
-        deviceReadyChannelsArray: [],
-        deviceReadyChannelsMap: {},
-
-        /**
-         * Indicate that a feature needs to be initialized before it is ready to be used.
-         * This holds up Cordova's "deviceready" event until the feature has been initialized
-         * and Cordova.initComplete(feature) is called.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        waitForInitialization: function(feature) {
-            if (feature) {
-                var c = channel[feature] || this.createSticky(feature);
-                this.deviceReadyChannelsMap[feature] = c;
-                this.deviceReadyChannelsArray.push(c);
-            }
-        },
-
-        /**
-         * Indicate that initialization code has completed and the feature is ready to be used.
-         *
-         * @param feature {String}     The unique feature name
-         */
-        initializationComplete: function(feature) {
-            var c = this.deviceReadyChannelsMap[feature];
-            if (c) {
-                c.fire();
-            }
-        }
-    };
-
-function forceFunction(f) {
-    if (typeof f != 'function') throw "Function required as first argument!";
-}
-
-/**
- * Subscribes the given function to the channel. Any time that
- * Channel.fire is called so too will the function.
- * Optionally specify an execution context for the function
- * and a guid that can be used to stop subscribing to the channel.
- * Returns the guid.
- */
-Channel.prototype.subscribe = function(f, c) {
-    // need a function to call
-    forceFunction(f);
-    if (this.state == 2) {
-        f.apply(c || this, this.fireArgs);
-        return;
-    }
-
-    var func = f,
-        guid = f.observer_guid;
-    if (typeof c == "object") { func = utils.close(c, f); }
-
-    if (!guid) {
-        // first time any channel has seen this subscriber
-        guid = '' + nextGuid++;
-    }
-    func.observer_guid = guid;
-    f.observer_guid = guid;
-
-    // Don't add the same handler more than once.
-    if (!this.handlers[guid]) {
-        this.handlers[guid] = func;
-        this.numHandlers++;
-        if (this.numHandlers == 1) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Unsubscribes the function with the given guid from the channel.
- */
-Channel.prototype.unsubscribe = function(f) {
-    // need a function to unsubscribe
-    forceFunction(f);
-
-    var guid = f.observer_guid,
-        handler = this.handlers[guid];
-    if (handler) {
-        delete this.handlers[guid];
-        this.numHandlers--;
-        if (this.numHandlers === 0) {
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-/**
- * Calls all functions subscribed to this channel.
- */
-Channel.prototype.fire = function(e) {
-    var fail = false,
-        fireArgs = Array.prototype.slice.call(arguments);
-    // Apply stickiness.
-    if (this.state == 1) {
-        this.state = 2;
-        this.fireArgs = fireArgs;
-    }
-    if (this.numHandlers) {
-        // Copy the values first so that it is safe to modify it from within
-        // callbacks.
-        var toCall = [];
-        for (var item in this.handlers) {
-            toCall.push(this.handlers[item]);
-        }
-        for (var i = 0; i < toCall.length; ++i) {
-            toCall[i].apply(this, fireArgs);
-        }
-        if (this.state == 2 && this.numHandlers) {
-            this.numHandlers = 0;
-            this.handlers = {};
-            this.onHasSubscribersChange && this.onHasSubscribersChange();
-        }
-    }
-};
-
-
-// defining them here so they are ready super fast!
-// DOM event that is received when the web page is loaded and parsed.
-channel.createSticky('onDOMContentLoaded');
-
-// Event to indicate the Cordova native side is ready.
-channel.createSticky('onNativeReady');
-
-// Event to indicate that all Cordova JavaScript objects have been created
-// and it's time to run plugin constructors.
-channel.createSticky('onCordovaReady');
-
-// Event to indicate that device properties are available
-channel.createSticky('onCordovaInfoReady');
-
-// Event to indicate that the connection property has been set.
-channel.createSticky('onCordovaConnectionReady');
-
-// Event to indicate that all automatically loaded JS plugins are loaded and ready.
-channel.createSticky('onPluginsReady');
-
-// Event to indicate that Cordova is ready
-channel.createSticky('onDeviceReady');
-
-// Event to indicate a resume lifecycle event
-channel.create('onResume');
-
-// Event to indicate a pause lifecycle event
-channel.create('onPause');
-
-// Event to indicate a destroy lifecycle event
-channel.createSticky('onDestroy');
-
-// Channels that must fire before "deviceready" is fired.
-channel.waitForInitialization('onCordovaReady');
-channel.waitForInitialization('onCordovaConnectionReady');
-channel.waitForInitialization('onDOMContentLoaded');
-
-module.exports = channel;
-
-});
-
-// file: lib/common/commandProxy.js
-define("cordova/commandProxy", function(require, exports, module) {
-
-
-// internal map of proxy function
-var CommandProxyMap = {};
-
-module.exports = {
-
-    // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
-    add:function(id,proxyObj) {
-        console.log("adding proxy for " + id);
-        CommandProxyMap[id] = proxyObj;
-        return proxyObj;
-    },
-
-    // cordova.commandProxy.remove("Accelerometer");
-    remove:function(id) {
-        var proxy = CommandProxyMap[id];
-        delete CommandProxyMap[id];
-        CommandProxyMap[id] = null;
-        return proxy;
-    },
-
-    get:function(service,action) {
-        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
-    }
-};
-});
-
-// file: lib/windowsphone/exec.js
-define("cordova/exec", function(require, exports, module) {
-
-var cordova = require('cordova');
-
-/**
- * Execute a cordova command.  It is up to the native side whether this action
- * is synchronous or asynchronous.  The native side can return:
- *      Synchronous: PluginResult object as a JSON string
- *      Asynchronous: Empty string ""
- * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
- * depending upon the result of the action.
- *
- * @param {Function} success    The success callback
- * @param {Function} fail       The fail callback
- * @param {String} service      The name of the service to use
- * @param {String} action       Action to be run in cordova
- * @param {String[]} [args]     Zero or more arguments to pass to the method
-
- */
-
-module.exports = function(success, fail, service, action, args) {
-
-    var callbackId = service + cordova.callbackId++;
-    if (typeof success == "function" || typeof fail == "function") {
-        cordova.callbacks[callbackId] = {success:success, fail:fail};
-    }
-    // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]
-    for(var n = 0; n < args.length; n++)
-    {
-        if(typeof args[n] !== "string")
-        {
-            args[n] = JSON.stringify(args[n]);
-        }
-    }
-    var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);
-    // pass it on to Notify
-    try {
-        if(window.external) {
-            window.external.Notify(command);
-        }
-        else {
-            console.log("window.external not available :: command=" + command);
-        }
-    }
-    catch(e) {
-        console.log("Exception calling native with command :: " + command + " :: exception=" + e);
-    }
-};
-
-
-});
-
-// file: lib/common/modulemapper.js
-define("cordova/modulemapper", function(require, exports, module) {
-
-var builder = require('cordova/builder'),
-    moduleMap = define.moduleMap,
-    symbolList,
-    deprecationMap;
-
-exports.reset = function() {
-    symbolList = [];
-    deprecationMap = {};
-};
-
-function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
-    if (!(moduleName in moduleMap)) {
-        throw new Error('Module ' + moduleName + ' does not exist.');
-    }
-    symbolList.push(strategy, moduleName, symbolPath);
-    if (opt_deprecationMessage) {
-        deprecationMap[symbolPath] = opt_deprecationMessage;
-    }
-}
-
-// Note: Android 2.3 does have Function.bind().
-exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
-    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
-};
-
-function prepareNamespace(symbolPath, context) {
-    if (!symbolPath) {
-        return context;
-    }
-    var parts = symbolPath.split('.');
-    var cur = context;
-    for (var i = 0, part; part = parts[i]; ++i) {
-        cur = cur[part] = cur[part] || {};
-    }
-    return cur;
-}
-
-exports.mapModules = function(context) {
-    var origSymbols = {};
-    context.CDV_origSymbols = origSymbols;
-    for (var i = 0, len = symbolList.length; i < len; i += 3) {
-        var strategy = symbolList[i];
-        var moduleName = symbolList[i + 1];
-        var symbolPath = symbolList[i + 2];
-        var lastDot = symbolPath.lastIndexOf('.');
-        var namespace = symbolPath.substr(0, lastDot);
-        var lastName = symbolPath.substr(lastDot + 1);
-
-        var module = require(moduleName);
-        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
-        var parentObj = prepareNamespace(namespace, context);
-        var target = parentObj[lastName];
-
-        if (strategy == 'm' && target) {
-            builder.recursiveMerge(target, module);
-        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
-            if (!(symbolPath in origSymbols)) {
-                origSymbols[symbolPath] = target;
-            }
-            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
-        }
-    }
-};
-
-exports.getOriginalSymbol = function(context, symbolPath) {
-    var origSymbols = context.CDV_origSymbols;
-    if (origSymbols && (symbolPath in origSymbols)) {
-        return origSymbols[symbolPath];
-    }
-    var parts = symbolPath.split('.');
-    var obj = context;
-    for (var i = 0; i < parts.length; ++i) {
-        obj = obj && obj[parts[i]];
-    }
-    return obj;
-};
-
-exports.loadMatchingModules = function(matchingRegExp) {
-    for (var k in moduleMap) {
-        if (matchingRegExp.exec(k)) {
-            require(k);
-        }
-    }
-};
-
-exports.reset();
-
-
-});
-
-// file: lib/windowsphone/platform.js
-define("cordova/platform", function(require, exports, module) {
-
-var cordova = require('cordova'),
-      exec = require('cordova/exec');
-
-module.exports = {
-    id: "windowsphone",
-    initialize:function() {
-        var modulemapper = require('cordova/modulemapper');
-
-        modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);
-
-        modulemapper.loadMatchingModules(/cordova.*\/symbols$/);
-
-        modulemapper.mapModules(window);
-
-        // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners
-        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
-        backButtonChannel.onHasSubscribersChange = function() {
-            exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);
-        };
-    }
-};
-
-});
-
-// 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 argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    Camera = require('cordova/plugin/CameraConstants'),
-    CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');
-
-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) {
-    argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
-    options = options || {};
-    var getValue = argscheck.getValue;
-
-    var quality = getValue(options.quality, 50);
-    var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
-    var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
-    var targetWidth = getValue(options.targetWidth, -1);
-    var targetHeight = getValue(options.targetHeight, -1);
-    var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
-    var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
-    var allowEdit = !!options.allowEdit;
-    var correctOrientation = !!options.correctOrientation;
-    var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
-    var popoverOptions = getValue(options.popoverOptions, null);
-    var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
-
-    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
-                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
-
-    exec(successCallback, errorCallback, "Camera", "takePicture", args);
-    return new CameraPopoverHandle();
-};
-
-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)
-    NATIVE_URI: 2        // Return native uri (eg. asset-library://... for iOS)
-  },
-  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
-  },
-  Direction:{
-      BACK: 0,
-      FRONT: 1
-  }
-};
-
-});
-
-// file: lib/common/plugin/CameraPopoverHandle.js
-define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-
-/**
- * A handle to an image picker popover.
- */
-var CameraPopoverHandle = function() {
-    this.setPosition = function(popoverOptions) {
-        console.log('CameraPopoverHandle.setPosition is only supported on iOS.');
-    };
-};
-
-module.exports = CameraPopoverHandle;
-
-});
-
-// 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;
-};
-
-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;
-};
-
-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;
-};
-
-module.exports = CaptureVideoOptions;
-
-});
-
-// file: lib/common/plugin/CompassError.js
-define("cordova/plugin/CompassError", function(require, exports, module) {
-
-/**
- *  CompassError.
- *  An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var CompassError = function(err) {
-    this.code = (err !== undefined ? err : null);
-};
-
-CompassError.COMPASS_INTERNAL_ERR = 0;
-CompassError.COMPASS_NOT_SUPPORTED = 20;
-
-module.exports = CompassError;
-
-});
-
-// file: lib/common/plugin/CompassHeading.js
-define("cordova/plugin/CompassHeading", function(require, exports, module) {
-
-var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
-  this.magneticHeading = magneticHeading;
-  this.trueHeading = trueHeading;
-  this.headingAccuracy = headingAccuracy;
-  this.timestamp = 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",
-        CELL:"cellular",
-        NONE: "none"
-};
-
-});
-
-// file: lib/common/plugin/Contact.js
-define("cordova/plugin/Contact", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    ContactError = require('cordova/plugin/ContactError'),
-    utils = require('cordova/utils');
-
-/**
-* Converts primitives into Complex Object
-* Currently only used for Date fields
-*/
-function convertIn(contact) {
-    var value = contact.birthday;
-    try {
-      contact.birthday = new Date(parseFloat(value));
-    } catch (exception){
-      console.log("Cordova Contact convertIn error: exception creating date.");
-    }
-    return contact;
-}
-
-/**
-* Converts Complex objects into primitives
-* Only conversion at present is for Dates.
-**/
-
-function convertOut(contact) {
-    var value = contact.birthday;
-    if (value !== null) {
-        // try to make it a Date object if it is not already
-        if (!utils.isDate(value)){
-            try {
-                value = new Date(value);
-            } catch(exception){
-                value = null;
-            }
-        }
-        if (utils.isDate(value)){
-            value = value.valueOf(); // convert to milliseconds
-        }
-        contact.birthday = value;
-    }
-    return contact;
-}
-
-/**
-* Contains information about a single contact.
-* @constructor
-* @param {DOMString} id unique identifier
-* @param {DOMString} displayName
-* @param {ContactName} name
-* @param {DOMString} nickname
-* @param {Array.<ContactField>} phoneNumbers array of phone numbers
-* @param {Array.<ContactField>} emails array of email addresses
-* @param {Array.<ContactAddress>} addresses array of addresses
-* @param {Array.<ContactField>} ims instant messaging user ids
-* @param {Array.<ContactOrganization>} organizations
-* @param {DOMString} birthday contact's birthday
-* @param {DOMString} note user notes about contact
-* @param {Array.<ContactField>} photos
-* @param {Array.<ContactField>} categories
-* @param {Array.<ContactField>} urls contact's web sites
-*/
-var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
-    ims, organizations, birthday, note, photos, categories, urls) {
-    this.id = id || null;
-    this.rawId = null;
-    this.displayName = displayName || null;
-    this.name = name || null; // ContactName
-    this.nickname = nickname || null;
-    this.phoneNumbers = phoneNumbers || null; // ContactField[]
-    this.emails = emails || null; // ContactField[]
-    this.addresses = addresses || null; // ContactAddress[]
-    this.ims = ims || null; // ContactField[]
-    this.organizations = organizations || null; // ContactOrganization[]
-    this.birthday = birthday || null;
-    this.note = note || null;
-    this.photos = photos || null; // ContactField[]
-    this.categories = categories || null; // ContactField[]
-    this.urls = urls || null; // ContactField[]
-};
-
-/**
-* Removes contact from device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.remove = function(successCB, errorCB) {
-    argscheck.checkArgs('FF', 'Contact.remove', arguments);
-    var fail = errorCB && 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);
-    clonedContact.id = null;
-    clonedContact.rawId = null;
-
-    function nullIds(arr) {
-        if (arr) {
-            for (var i = 0; i < arr.length; ++i) {
-                arr[i].id = null;
-            }
-        }
-    }
-
-    // Loop through and clear out any id's in phones, emails, etc.
-    nullIds(clonedContact.phoneNumbers);
-    nullIds(clonedContact.emails);
-    nullIds(clonedContact.addresses);
-    nullIds(clonedContact.ims);
-    nullIds(clonedContact.organizations);
-    nullIds(clonedContact.categories);
-    nullIds(clonedContact.photos);
-    nullIds(clonedContact.urls);
-    return clonedContact;
-};
-
-/**
-* Persists contact to device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.save = function(successCB, errorCB) {
-    argscheck.checkArgs('FFO', 'Contact.save', arguments);
-    var fail = errorCB && function(code) {
-        errorCB(new ContactError(code));
-    };
-    var success = function(result) {
-        if (result) {
-            if (successCB) {
-                var fullContact = require('cordova/plugin/contacts').create(result);
-                successCB(convertIn(fullContact));
-            }
-        }
-        else {
-            // no Entry object returned
-            fail(ContactError.UNKNOWN_ERROR);
-        }
-    };
-    var dupContact = convertOut(utils.clone(this));
-    exec(success, fail, "Contacts", "save", [dupContact]);
-};
-
-
-module.exports = Contact;
-
-});
-
-// file: lib/common/plugin/ContactAddress.js
-define("cordova/plugin/ContactAddress", function(require, exports, module) {
-
-/**
-* Contact address.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code
-* @param formatted // NOTE: not a W3C standard
-* @param streetAddress
-* @param locality
-* @param region
-* @param postalCode
-* @param country
-*/
-
-var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
-    this.id = null;
-    this.pref = (typeof pref != 'undefined' ? pref : false);
-    this.type = type || null;
-    this.formatted = formatted || null;
-    this.streetAddress = streetAddress || null;
-    this.locality = locality || null;
-    this.region = region || null;
-    this.postalCode = postalCode || null;
-    this.country = country || null;
-};
-
-module.exports = ContactAddress;
-
-});
-
-// file: lib/common/plugin/ContactError.js
-define("cordova/plugin/ContactError", function(require, exports, module) {
-
-/**
- *  ContactError.
- *  An error code assigned by an implementation when an error has occurred
- * @constructor
- */
-var ContactError = function(err) {
-    this.code = (typeof err != 'undefined' ? err : null);
-};
-
-/**
- * Error codes
- */
-ContactError.UNKNOWN_ERROR = 0;
-ContactError.INVALID_ARGUMENT_ERROR = 1;
-ContactError.TIMEOUT_ERROR = 2;
-ContactError.PENDING_OPERATION_ERROR = 3;
-ContactError.IO_ERROR = 4;
-ContactError.NOT_SUPPORTED_ERROR = 5;
-ContactError.PERMISSION_DENIED_ERROR = 20;
-
-module.exports = ContactError;
-
-});
-
-// file: lib/common/plugin/ContactField.js
-define("cordova/plugin/ContactField", function(require, exports, module) {
-
-/**
-* Generic contact field.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param type
-* @param value
-* @param pref
-*/
-var ContactField = function(type, value, pref) {
-    this.id = null;
-    this.type = (type && type.toString()) || null;
-    this.value = (value && value.toString()) || null;
-    this.pref = (typeof pref != 'undefined' ? pref : false);
-};
-
-module.exports = ContactField;
-
-});
-
-// file: lib/common/plugin/ContactFindOptions.js
-define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
-
-/**
- * ContactFindOptions.
- * @constructor
- * @param filter used to match contacts against
- * @param multiple boolean used to determine if more than one contact should be returned
- */
-
-var ContactFindOptions = function(filter, multiple) {
-    this.filter = filter || '';
-    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
-};
-
-module.exports = ContactFindOptions;
-
-});
-
-// file: lib/common/plugin/ContactName.js
-define("cordova/plugin/ContactName", function(require, exports, module) {
-
-/**
-* Contact name.
-* @constructor
-* @param formatted // NOTE: not part of W3C standard
-* @param familyName
-* @param givenName
-* @param middle
-* @param prefix
-* @param suffix
-*/
-var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
-    this.formatted = formatted || null;
-    this.familyName = familyName || null;
-    this.givenName = givenName || null;
-    this.middleName = middle || null;
-    this.honorificPrefix = prefix || null;
-    this.honorificSuffix = suffix || null;
-};
-
-module.exports = ContactName;
-
-});
-
-// file: lib/common/plugin/ContactOrganization.js
-define("cordova/plugin/ContactOrganization", function(require, exports, module) {
-
-/**
-* Contact organization.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param name
-* @param dept
-* @param title
-* @param startDate
-* @param endDate
-* @param location
-* @param desc
-*/
-
-var ContactOrganization = function(pref, type, name, dept, title) {
-    this.id = null;
-    this.pref = (typeof pref != 'undefined' ? pref : false);
-    this.type = type || null;
-    this.name = name || null;
-    this.department = dept || null;
-    this.title = title || null;
-};
-
-module.exports = ContactOrganization;
-
-});
-
-// file: lib/common/plugin/Coordinates.js
-define("cordova/plugin/Coordinates", function(require, exports, module) {
-
-/**
- * This class contains position information.
- * @param {Object} lat
- * @param {Object} lng
- * @param {Object} alt
- * @param {Object} acc
- * @param {Object} head
- * @param {Object} vel
- * @param {Object} altacc
- * @constructor
- */
-var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
-    /**
-     * The latitude of the position.
-     */
-    this.latitude = lat;
-    /**
-     * The longitude of the position,
-     */
-    this.longitude = lng;
-    /**
-     * The accuracy of the position.
-     */
-    this.accuracy = acc;
-    /**
-     * The altitude of the position.
-     */
-    this.altitude = (alt !== undefined ? alt : null);
-    /**
-     * The direction the device is moving at the position.
-     */
-    this.heading = (head !== undefined ? head : null);
-    /**
-     * The velocity with which the device is moving at the position.
-     */
-    this.speed = (vel !== undefined ? vel : null);
-
-    if (this.speed === 0 || this.speed === null) {
-        this.heading = NaN;
-    }
-
-    /**
-     * The altitude accuracy of the position.
-     */
-    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
-};
-
-module.exports = Coordinates;
-
-});
-
-// file: lib/common/plugin/DirectoryEntry.js
-define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    Entry = require('cordova/plugin/Entry'),
-    FileError = require('cordova/plugin/FileError'),
-    DirectoryReader = require('cordova/plugin/DirectoryReader');
-
-/**
- * An interface representing a directory on the file system.
- *
- * {boolean} isFile always false (readonly)
- * {boolean} isDirectory always true (readonly)
- * {DOMString} name of the directory, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the directory (readonly)
- * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
- */
-var DirectoryEntry = function(name, fullPath) {
-     DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);
-};
-
-utils.extend(DirectoryEntry, Entry);
-
-/**
- * Creates a new DirectoryReader to read entries from this directory
- */
-DirectoryEntry.prototype.createReader = function() {
-    return new DirectoryReader(this.fullPath);
-};
-
-/**
- * Creates or looks up a directory
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
- * @param {Flags} options to create or exclusively create the directory
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
-    argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);
-    var win = successCallback && function(result) {
-        var entry = new DirectoryEntry(result.name, result.fullPath);
-        successCallback(entry);
-    };
-    var fail = errorCallback && 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) {
-    argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
-};
-
-/**
- * Creates or looks up a file
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
- * @param {Flags} options to create or exclusively create the file
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
-    argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);
-    var win = successCallback && function(result) {
-        var FileEntry = require('cordova/plugin/FileEntry');
-        var entry = new FileEntry(result.name, result.fullPath);
-        successCallback(entry);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
-};
-
-module.exports = DirectoryEntry;
-
-});
-
-// file: lib/common/plugin/DirectoryReader.js
-define("cordova/plugin/DirectoryReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    FileError = require('cordova/plugin/FileError') ;
-
-/**
- * An interface that lists the files and directories in a directory.
- */
-function DirectoryReader(path) {
-    this.path = path || null;
-}
-
-/**
- * Returns a list of entries from a directory.
- *
- * @param {Function} successCallback is called with a list of entries
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
-    var win = typeof successCallback !== 'function' ? null : function(result) {
-        var retVal = [];
-        for (var i=0; i<result.length; i++) {
-            var entry = null;
-            if (result[i].isDirectory) {
-                entry = new (require('cordova/plugin/DirectoryEntry'))();
-            }
-            else if (result[i].isFile) {
-                entry = new (require('cordova/plugin/FileEntry'))();
-            }
-            entry.isDirectory = result[i].isDirectory;
-            entry.isFile = result[i].isFile;
-            entry.name = result[i].name;
-            entry.fullPath = result[i].fullPath;
-            retVal.push(entry);
-        }
-        successCallback(retVal);
-    };
-    var fail = typeof errorCallback !== 'function' ? null : function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "readEntries", [this.path]);
-};
-
-module.exports = DirectoryReader;
-
-});
-
-// file: lib/common/plugin/Entry.js
-define("cordova/plugin/Entry", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    FileError = require('cordova/plugin/FileError'),
-    Metadata = require('cordova/plugin/Metadata');
-
-/**
- * Represents a file or directory on the local file system.
- *
- * @param isFile
- *            {boolean} true if Entry is a file (readonly)
- * @param isDirectory
- *            {boolean} true if Entry is a directory (readonly)
- * @param name
- *            {DOMString} name of the file or directory, excluding the path
- *            leading to it (readonly)
- * @param fullPath
- *            {DOMString} the absolute full path to the file or directory
- *            (readonly)
- */
-function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
-    this.isFile = !!isFile;
-    this.isDirectory = !!isDirectory;
-    this.name = name || '';
-    this.fullPath = fullPath || '';
-    this.filesystem = fileSystem || null;
-}
-
-/**
- * Look up the metadata of the entry.
- *
- * @param successCallback
- *            {Function} is called with a Metadata object
- * @param errorCallback
- *            {Function} is called with a FileError
- */
-Entry.prototype.getMetadata = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);
-    var success = successCallback && function(lastModified) {
-        var metadata = new Metadata(lastModified);
-        successCallback(metadata);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-
-    exec(success, fail, "File", "getMetadata", [this.fullPath]);
-};
-
-/**
- * Set the metadata of the entry.
- *
- * @param successCallback
- *            {Function} is called with a Metadata object
- * @param errorCallback
- *            {Function} is called with a FileError
- * @param metadataObject
- *            {Object} keys and values to set
- */
-Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
-    argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);
-    exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
-};
-
-/**
- * Move a file or directory to a new location.
- *
- * @param parent
- *            {DirectoryEntry} the directory to which to move this entry
- * @param newName
- *            {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- *            {Function} called with the new DirectoryEntry object
- * @param errorCallback
- *            {Function} called with a FileError
- */
-Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
-    argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    // source path
-    var srcPath = this.fullPath,
-        // entry name
-        name = newName || this.name,
-        success = function(entry) {
-            if (entry) {
-                if (successCallback) {
-                    // create appropriate Entry object
-                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
-                    successCallback(result);
-                }
-            }
-            else {
-                // no Entry object returned
-                fail && fail(FileError.NOT_FOUND_ERR);
-            }
-        };
-
-    // copy
-    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Copy a directory to a different location.
- *
- * @param parent
- *            {DirectoryEntry} the directory to which to copy the entry
- * @param newName
- *            {DOMString} new name of the entry, defaults to the current name
- * @param successCallback
- *            {Function} called with the new Entry object
- * @param errorCallback
- *            {Function} called with a FileError
- */
-Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
-    argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-
-        // source path
-    var srcPath = this.fullPath,
-        // entry name
-        name = newName || this.name,
-        // success callback
-        success = function(entry) {
-            if (entry) {
-                if (successCallback) {
-                    // create appropriate Entry object
-                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
-                    successCallback(result);
-                }
-            }
-            else {
-                // no Entry object returned
-                fail && fail(FileError.NOT_FOUND_ERR);
-            }
-        };
-
-    // copy
-    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
-};
-
-/**
- * Return a URL that can be used to identify this entry.
- */
-Entry.prototype.toURL = function() {
-    // fullPath attribute contains the full URL
-    return this.fullPath;
-};
-
-/**
- * Returns a URI that can be used to identify this entry.
- *
- * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
- * @return uri
- */
-Entry.prototype.toURI = function(mimeType) {
-    console.log("DEPRECATED: Update your code to use 'toURL'");
-    // fullPath attribute contains the full URI
-    return this.toURL();
-};
-
-/**
- * Remove a file or directory. It is an error to attempt to delete a
- * directory that is not empty. It is an error to attempt to delete a
- * root directory of a file system.
- *
- * @param successCallback {Function} called with no parameters
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.remove = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'Entry.remove', arguments);
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(successCallback, fail, "File", "remove", [this.fullPath]);
-};
-
-/**
- * Look up the parent DirectoryEntry of this entry.
- *
- * @param successCallback {Function} called with the parent DirectoryEntry object
- * @param errorCallback {Function} called with a FileError
- */
-Entry.prototype.getParent = function(successCallback, errorCallback) {
-    argscheck.checkArgs('FF', 'Entry.getParent', arguments);
-    var win = successCallback && function(result) {
-        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-        var entry = new DirectoryEntry(result.name, result.fullPath);
-        successCallback(entry);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getParent", [this.fullPath]);
-};
-
-module.exports = Entry;
-
-});
-
-// file: lib/common/plugin/File.js
-define("cordova/plugin/File", function(require, exports, module) {
-
-/**
- * Constructor.
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-
-var File = function(name, fullPath, type, lastModifiedDate, size){
-    this.name = name || '';
-    this.fullPath = fullPath || null;
-    this.type = type || null;
-    this.lastModifiedDate = lastModifiedDate || null;
-    this.size = size || 0;
-
-    // These store the absolute start and end for slicing the file.
-    this.start = 0;
-    this.end = this.size;
-};
-
-/**
- * Returns a "slice" of the file. Since Cordova Files don't contain the actual
- * content, this really returns a File with adjusted start and end.
- * Slices of slices are supported.
- * start {Number} The index at which to start the slice (inclusive).
- * end {Number} The index at which to end the slice (exclusive).
- */
-File.prototype.slice = function(start, end) {
-    var size = this.end - this.start;
-    var newStart = 0;
-    var newEnd = size;
-    if (arguments.length) {
-        if (start < 0) {
-            newStart = Math.max(size + start, 0);
-        } else {
-            newStart = Math.min(size, start);
-        }
-    }
-
-    if (arguments.length >= 2) {
-        if (end < 0) {
-            newEnd = Math.max(size + end, 0);
-        } else {
-            newEnd = Math.min(end, size);
-        }
-    }
-
-    var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);
-    newFile.start = this.start + newStart;
-    newFile.end = this.start + newEnd;
-    return newFile;
-};
-
-
-module.exports = File;
-
-});
-
-// file: lib/common/plugin/FileEntry.js
-define("cordova/plugin/FileEntry", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    Entry = require('cordova/plugin/Entry'),
-    FileWriter = require('cordova/plugin/FileWriter'),
-    File = require('cordova/plugin/File'),
-    FileError = require('cordova/plugin/FileError');
-
-/**
- * An interface representing a file on the file system.
- *
- * {boolean} isFile always true (readonly)
- * {boolean} isDirectory always false (readonly)
- * {DOMString} name of the file, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the file (readonly)
- * {FileSystem} filesystem on which the file resides (readonly)
- */
-var FileEntry = function(name, fullPath) {
-     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
-};
-
-utils.extend(FileEntry, Entry);
-
-/**
- * Creates a new FileWriter associated with the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new FileWriter
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
-    this.file(function(filePointer) {
-        var writer = new FileWriter(filePointer);
-
-        if (writer.fileName === null || writer.fileName === "") {
-            errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));
-        } else {
-            successCallback && successCallback(writer);
-        }
-    }, errorCallback);
-};
-
-/**
- * Returns a File that represents the current state of the file that this FileEntry represents.
- *
- * @param {Function} successCallback is called with the new File object
- * @param {Function} errorCallback is called with a FileError
- */
-FileEntry.prototype.file = function(successCallback, errorCallback) {
-    var win = successCallback && function(f) {
-        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
-        successCallback(file);
-    };
-    var fail = errorCallback && function(code) {
-        errorCallback(new FileError(code));
-    };
-    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
-};
-
-
-module.exports = FileEntry;
-
-});
-
-// file: lib/common/plugin/FileError.js
-define("cordova/plugin/FileError", function(require, exports, module) {
-
-/**
- * FileError
- */
-function FileError(error) {
-  this.code = error || null;
-}
-
-// File error codes
-// Found in DOMException
-FileError.NOT_FOUND_ERR = 1;
-FileError.SECURITY_ERR = 2;
-FileError.ABORT_ERR = 3;
-
-// Added by File API specification
-FileError.NOT_READABLE_ERR = 4;
-FileError.ENCODING_ERR = 5;
-FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
-FileError.INVALID_STATE_ERR = 7;
-FileError.SYNTAX_ERR = 8;
-FileError.INVALID_MODIFICATION_ERR = 9;
-FileError.QUOTA_EXCEEDED_ERR = 10;
-FileError.TYPE_MISMATCH_ERR = 11;
-FileError.PATH_EXISTS_ERR = 12;
-
-module.exports = FileError;
-
-});
-
-// file: lib/common/plugin/FileReader.js
-define("cordova/plugin/FileReader", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    modulemapper = require('cordova/modulemapper'),
-    utils = require('cordova/utils'),
-    File = require('cordova/plugin/File'),
-    FileError = require('cordova/plugin/FileError'),
-    ProgressEvent = require('cordova/plugin/ProgressEvent'),
-    origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');
-
-/**
- * This class reads the mobile device file system.
- *
- * For Android:
- *      The root directory is the root of the file system.
- *      To read from the SD card, the file name is "sdcard/my_file.txt"
- * @constructor
- */
-var FileReader = function() {
-    this._readyState = 0;
-    this._error = null;
-    this._result = null;
-    this._fileName = '';
-    this._realReader = origFileReader ? new origFileReader() : {};
-};
-
-// States
-FileReader.EMPTY = 0;
-FileReader.LOADING = 1;
-FileReader.DONE = 2;
-
-utils.defineGetter(FileReader.prototype, 'readyState', function() {
-    return this._fileName ? this._readyState : this._realReader.readyState;
-});
-
-utils.defineGetter(FileReader.prototype, 'error', function() {
-    return this._fileName ? this._error: this._realReader.error;
-});
-
-utils.defineGetter(FileReader.prototype, 'result', function() {
-    return this._fileName ? this._result: this._realReader.result;
-});
-
-function defineEvent(eventName) {
-    utils.defineGetterSetter(FileReader.prototype, eventName, function() {
-        return this._realReader[eventName] || null;
-    }, function(value) {
-        this._realReader[eventName] = value;
-    });
-}
-defineEvent('onloadstart');    // When the read starts.
-defineEvent('onprogress');     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
-defineEvent('onload');         // When the read has successfully completed.
-defineEvent('onerror');        // When the read has failed (see errors).
-defineEvent('onloadend');      // When the request has completed (either in success or failure).
-defineEvent('onabort');        // When the read has been aborted. For instance, by invoking the abort() method.
-
-function initRead(reader, file) {
-    // Already loading something
-    if (reader.readyState == FileReader.LOADING) {
-      throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    reader._result = null;
-    reader._error = null;
-    reader._readyState = FileReader.LOADING;
-
-    if (typeof file.fullPath == 'string') {
-        reader._fileName = file.fullPath;
-    } else {
-        reader._fileName = '';
-        return true;
-    }
-
-    reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));
-}
-
-/**
- * Abort reading file.
- */
-FileReader.prototype.abort = function() {
-    if (origFileReader && !this._fileName) {
-        return this._realReader.abort();
-    }
-    this._result = null;
-
-    if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {
-      return;
-    }
-
-    this._readyState = FileReader.DONE;
-
-    // If abort callback
-    if (typeof this.onabort === 'function') {
-        this.onabort(new ProgressEvent('abort', {target:this}));
-    }
-    // If load end callback
-    if (typeof this.onloadend === 'function') {
-        this.onloadend(new ProgressEvent('loadend', {target:this}));
-    }
-};
-
-/**
- * Read text file.
- *
- * @param file          {File} File object containing file properties
- * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
- */
-FileReader.prototype.readAsText = function(file, encoding) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsText(file, encoding);
-    }
-
-    // Default encoding is UTF-8
-    var enc = encoding ? encoding : "UTF-8";
-    var me = this;
-    var execArgs = [this._fileName, enc, file.start, file.end];
-
-    // Read file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // Save result
-            me._result = r;
-
-            // If onload callback
-            if (typeof me.onload === "function") {
-                me.onload(new ProgressEvent("load", {target:me}));
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me._readyState === FileReader.DONE) {
-                return;
-            }
-
-            // DONE state
-            me._readyState = FileReader.DONE;
-
-            // null result
-            me._result = null;
-
-            // Save error
-            me._error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {target:me}));
-            }
-
-            // If onloadend callback
-            if (typeof me.onloadend === "function") {
-                me.onloadend(new ProgressEvent("loadend", {target:me}));
-            }
-        }, "File", "readAsText", execArgs);
-};
-
-
-/**
- * Read file and return data as a base64 encoded data url.
- * A data url is of the form:
- *      data:[<mediatype>][;base64],<data>
- *
- * @param file          {File} File object containing file properties
- */
-FileReader.prototype.readAsDataURL = function(file) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsDataURL(file);
-    }
-
-    var me = this;
-    var execArgs = [this._fileName, file.start, file.end];
-
-    // 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", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file          {File} File object containing file properties
- */
-FileReader.prototype.readAsBinaryString = function(file) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsBinaryString(file);
-    }
-
-    var me = this;
-    var execArgs = [this._fileName, file.start, file.end];
-
-    // 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;
-
-            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", "readAsBinaryString", execArgs);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file          {File} File object containing file properties
- */
-FileReader.prototype.readAsArrayBuffer = function(file) {
-    if (initRead(this, file)) {
-        return this._realReader.readAsArrayBuffer(file);
-    }
-
-    var me = this;
-    var execArgs = [this._fileName, file.start, file.end];
-
-    // 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;
-
-            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", "readAsArrayBuffer", execArgs);
-};
-
-module.exports = FileReader;
-
-});
-
-// file: lib/common/plugin/FileSystem.js
-define("cordova/plugin/FileSystem", function(require, exports, module) {
-
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-
-/**
- * An interface representing a file system
- *
- * @constructor
- * {DOMString} name the unique name of the file system (readonly)
- * {DirectoryEntry} root directory of the file system (readonly)
- */
-var FileSystem = function(name, root) {
-    this.name = name || null;
-    if (root) {
-        this.root = new DirectoryEntry(root.name, root.fullPath);
-    }
-};
-
-module.exports = FileSystem;
-
-});
-
-// file: lib/common/plugin/FileTransfer.js
-define("cordova/plugin/FileTransfer", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    FileTransferError = require('cordova/plugin/FileTransferError'),
-    ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-function newProgressEvent(result) {
-    var pe = new ProgressEvent();
-    pe.lengthComputable = result.lengthComputable;
-    pe.loaded = result.loaded;
-    pe.total = result.total;
-    return pe;
-}
-
-function getBasicAuthHeader(urlString) {
-    var header =  null;
-
-    if (window.btoa) {
-        // parse the url using the Location object
-        var url = document.createElement('a');
-        url.href = urlString;
-
-        var credentials = null;
-        var protocol = url.protocol + "//";
-        var origin = protocol + url.host;
-
-        // check whether there are the username:password credentials in the url
-        if (url.href.indexOf(origin) !== 0) { // credentials found
-            var atIndex = url.href.indexOf("@");
-            credentials = url.href.substring(protocol.length, atIndex);
-        }
-
-        if (credentials) {
-            var authHeader = "Authorization";
-            var authHeaderValue = "Basic " + window.btoa(credentials);
-
-            header = {
-                name : authHeader,
-                value : authHeaderValue
-            };
-        }
-    }
-
-    return header;
-}
-
-var idCounter = 0;
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {
-    this._id = ++idCounter;
-    this.onprogress = null; // optional callback
-};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String}           Full path of the file on the device
-* @param server {String}             URL of the server to receive the file
-* @param successCallback (Function}  Callback to be invoked when upload has completed
-* @param errorCallback {Function}    Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
-    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
-    // check for options
-    var fileKey = null;
-    var fileName = null;
-    var mimeType = null;
-    var params = null;
-    var chunkedMode = true;
-    var headers = null;
-    var httpMethod = null;
-    var basicAuthHeader = getBasicAuthHeader(server);
-    if (basicAuthHeader) {
-        options = options || {};
-        options.headers = options.headers || {};
-        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
-    }
-
-    if (options) {
-        fileKey = options.fileKey;
-        fileName = options.fileName;
-        mimeType = options.mimeType;
-        headers = options.headers;
-        httpMethod = options.httpMethod || "POST";
-        if (httpMethod.toUpperCase() == "PUT"){
-            httpMethod = "PUT";
-        } else {
-            httpMethod = "POST";
-        }
-        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
-            chunkedMode = options.chunkedMode;
-        }
-        if (options.params) {
-            params = options.params;
-        }
-        else {
-            params = {};
-        }
-    }
-
-    var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
-        errorCallback(error);
-    };
-
-    var self = this;
-    var win = function(result) {
-        if (typeof result.lengthComputable != "undefined") {
-            if (self.onprogress) {
-                self.onprogress(newProgressEvent(result));
-            }
-        } else {
-            successCallback && successCallback(result);
-        }
-    };
-    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String}          URL of the server to receive the file
- * @param target {String}         Full path of the file on the device
- * @param successCallback (Function}  Callback to be invoked when upload has completed
- * @param errorCallback {Function}    Callback to be invoked upon error
- * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
- * @param options {FileDownloadOptions} Optional parameters such as headers
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
-    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
-    var self = this;
-
-    var basicAuthHeader = getBasicAuthHeader(source);
-    if (basicAuthHeader) {
-        options = options || {};
-        options.headers = options.headers || {};
-        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
-    }
-
-    var headers = null;
-    if (options) {
-        headers = options.headers || null;
-    }
-
-    var win = function(result) {
-        if (typeof result.lengthComputable != "undefined") {
-            if (self.onprogress) {
-                return self.onprogress(newProgressEvent(result));
-            }
-        } else if (successCallback) {
-            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 = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
-        errorCallback(error);
-    };
-
-    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
-};
-
-/**
- * Aborts the ongoing file transfer on this object. The original error
- * callback for the file transfer will be called if necessary.
- */
-FileTransfer.prototype.abort = function() {
-    exec(null, null, 'FileTransfer', 'abort', [this._id]);
-};
-
-module.exports = FileTransfer;
-
-});
-
-// file: lib/common/plugin/FileTransferError.js
-define("cordova/plugin/FileTransferError", function(require, exports, module) {
-
-/**
- * FileTransferError
- * @constructor
- */
-var FileTransferError = function(code, source, target, status, body) {
-    this.code = code || null;
-    this.source = source || null;
-    this.target = target || null;
-    this.http_status = status || null;
-    this.body = body || null;
-};
-
-FileTransferError.FILE_NOT_FOUND_ERR = 1;
-FileTransferError.INVALID_URL_ERR = 2;
-FileTransferError.CONNECTION_ERR = 3;
-FileTransferError.ABORT_ERR = 4;
-
-module.exports = FileTransferError;
-
-});
-
-// file: lib/common/plugin/FileUploadOptions.js
-define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
-
-/**
- * Options to customize the HTTP request used to upload files.
- * @constructor
- * @param fileKey {String}   Name of file request parameter.
- * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
- * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
- * @param params {Object}    Object with key: value params to send to the server.
- * @param headers {Object}   Keys are header names, values are header values. Multiple
- *                           headers of the same name are not supported.
- */
-var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) {
-    this.fileKey = fileKey || null;
-    this.fileName = fileName || null;
-    this.mimeType = mimeType || null;
-    this.params = params || null;
-    this.headers = headers || null;
-    this.httpMethod = httpMethod || 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 data text or blob to be written
- */
-FileWriter.prototype.write = function(data) {
-
-    var isBinary = false;
-
-    // If we don't have Blob or ArrayBuffer support, don't bother.
-    if (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined') {
-
-        // Check to see if the incoming data is a blob
-        if (data instanceof Blob) {
-            var that=this;
-            var fileReader = new FileReader();
-            fileReader.onload = function() {
-                // Call this method again, with the arraybuffer as argument
-                FileWriter.prototype.write.call(that, this.result);
-            };
-            fileReader.readAsArrayBuffer(data);
-            return;
-        }
-
-        // Mark data type for safer transport over the binary bridge
-        isBinary = (data instanceof ArrayBuffer);
-    }
-
-    // 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, data, this.position, isBinary]);
-};
-
-/**
- * Moves the file pointer to the location specified.
- *
- * If the offset is a negative number the position of the file
- * pointer is rewound.  If the offset is greater than the file
- * size the position is set to the end of the file.
- *
- * @param offset is the location to move the file pointer to.
- */
-FileWriter.prototype.seek = function(offset) {
-    // Throw an exception if we are already writing a file
-    if (this.readyState === FileWriter.WRITING) {
-        throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    if (!offset && offset !== 0) {
-        return;
-    }
-
-    // See back from end of file.
-    if (offset < 0) {
-        this.position = Math.max(offset + this.length, 0);
-    }
-    // Offset is bigger than file size so set position
-    // to the end of the file.
-    else if (offset > this.length) {
-        this.position = this.length;
-    }
-    // Offset is between 0 and file size so set the position
-    // to start writing.
-    else {
-        this.position = offset;
-    }
-};
-
-/**
- * Truncates the file to the size specified.
- *
- * @param size to chop the file at.
- */
-FileWriter.prototype.truncate = function(size) {
-    // Throw an exception if we are already writing a file
-    if (this.readyState === FileWriter.WRITING) {
-        throw new FileError(FileError.INVALID_STATE_ERR);
-    }
-
-    // WRITING state
-    this.readyState = FileWriter.WRITING;
-
-    var me = this;
-
-    // If onwritestart callback
-    if (typeof me.onwritestart === "function") {
-        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
-    }
-
-    // Write file
-    exec(
-        // Success callback
-        function(r) {
-            // If DONE (cancelled), then don't do anything
-            if (me.readyState === FileWriter.DONE) {
-                return;
-            }
-
-            // DONE state
-            me.readyState = FileWriter.DONE;
-
-            // Update the length of the file
-            me.length = r;
-            me.position = Math.min(me.position, r);
-
-            // If onwrite callback
-            if (typeof me.onwrite === "function") {
-                me.onwrite(new ProgressEvent("write", {"target":me}));
-            }
-
-            // If onwriteend callback
-            if (typeof me.onwriteend === "function") {
-                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
-            }
-        },
-        // Error callback
-        function(e) {
-            // If DONE (cancelled), then don't do anything
-            if (me.readyState === FileWriter.DONE) {
-                return;
-            }
-
-            // DONE state
-            me.readyState = FileWriter.DONE;
-
-            // Save error
-            me.error = new FileError(e);
-
-            // If onerror callback
-            if (typeof me.onerror === "function") {
-                me.onerror(new ProgressEvent("error", {"target":me}));
-            }
-
-            // If onwriteend callback
-            if (typeof me.onwriteend === "function") {
-                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
-            }
-        }, "File", "truncate", [this.fileName, size]);
-};
-
-module.exports = FileWriter;
-
-});
-
-// file: lib/common/plugin/Flags.js
-define("cordova/plugin/Flags", function(require, exports, module) {
-
-/**
- * Supplies arguments to methods that lookup or create files and directories.
- *
- * @param create
- *            {boolean} file or directory if it doesn't exist
- * @param exclusive
- *            {boolean} used with create; if true the command will fail if
- *            target path exists
- */
-function Flags(create, exclusive) {
-    this.create = create || false;
-    this.exclusive = exclusive || false;
-}
-
-module.exports = Flags;
-
-});
-
-// file: lib/common/plugin/GlobalizationError.js
-define("cordova/plugin/GlobalizationError", function(require, exports, module) {
-
-
-/**
- * Globalization error object
- *
- * @constructor
- * @param code
- * @param message
- */
-var GlobalizationError = function(code, message) {
-    this.code = code || null;
-    this.message = message || '';
-};
-
-// Globalization error codes
-GlobalizationError.UNKNOWN_ERROR = 0;
-GlobalizationError.FORMATTING_ERROR = 1;
-GlobalizationError.PARSING_ERROR = 2;
-GlobalizationError.PATTERN_ERROR = 3;
-
-module.exports = GlobalizationError;
-
-});
-
-// file: lib/common/plugin/InAppBrowser.js
-define("cordova/plugin/InAppBrowser", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var channel = require('cordova/channel');
-var modulemapper = require('cordova/modulemapper');
-
-function InAppBrowser() {
-   this.channels = {
-        'loadstart': channel.create('loadstart'),
-        'loadstop' : channel.create('loadstop'),
-        'loaderror' : channel.create('loaderror'),
-        'exit' : channel.create('exit')
-   };
-}
-
-InAppBrowser.prototype = {
-    _eventHandler: function (event) {
-        if (event.type in this.channels) {
-            this.channels[event.type].fire(event);
-        }
-    },
-    close: function (eventname) {
-        exec(null, null, "InAppBrowser", "close", []);
-    },
-    show: function (eventname) {
-      exec(null, null, "InAppBrowser", "show", []);
-    },
-    addEventListener: function (eventname,f) {
-        if (eventname in this.channels) {
-            this.channels[eventname].subscribe(f);
-        }
-    },
-    removeEventListener: function(eventname, f) {
-        if (eventname in this.channels) {
-            this.channels[eventname].unsubscribe(f);
-        }
-    },
-
-    executeScript: function(injectDetails, cb) {
-        if (injectDetails.code) {
-            exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
-        } else if (injectDetails.file) {
-            exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
-        } else {
-            throw new Error('executeScript requires exactly one of code or file to be specified');
-        }
-    },
-
-    insertCSS: function(injectDetails, cb) {
-        if (injectDetails.code) {
-            exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
-        } else if (injectDetails.file) {
-            exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
-        } else {
-            throw new Error('insertCSS requires exactly one of code or file to be specified');
-        }
-    }
-};
-
-module.exports = function(strUrl, strWindowName, strWindowFeatures) {
-    var iab = new InAppBrowser();
-    var cb = function(eventname) {
-       iab._eventHandler(eventname);
-    };
-
-    // Don't catch calls that write to existing frames (e.g. named iframes).
-    if (window.frames && window.frames[strWindowName]) {
-        var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
-        return origOpenFunc.apply(window, arguments);
-    }
-
-    exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
-    return iab;
-};
-
-
-});
-
-// 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 argscheck = require('cordova/argscheck'),
-    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) {
-    argscheck.checkArgs('SFFF', 'Media', arguments);
-    this.id = utils.createUUID();
-    mediaObjects[this.id] = this;
-    this.src = src;
-    this.successCallback = successCallback;
-    this.errorCallback = errorCallback;
-    this.statusCallback = statusCallback;
-    this._duration = -1;
-    this._position = -1;
-    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
-};
-
-// Media messages
-Media.MEDIA_STATE = 1;
-Media.MEDIA_DURATION = 2;
-Media.MEDIA_POSITION = 3;
-Media.MEDIA_ERROR = 9;
-
-// Media states
-Media.MEDIA_NONE = 0;
-Media.MEDIA_STARTING = 1;
-Media.MEDIA_RUNNING = 2;
-Media.MEDIA_PAUSED = 3;
-Media.MEDIA_STOPPED = 4;
-Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
-
-// "static" function to return existing objs.
-Media.get = function(id) {
-    return mediaObjects[id];
-};
-
-/**
- * Start or resume playing audio file.
- */
-Media.prototype.play = function(options) {
-    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
-};
-
-/**
- * Stop playing audio file.
- */
-Media.prototype.stop = function() {
-    var me = this;
-    exec(function() {
-        me._position = 0;
-    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
-};
-
-/**
- * Seek or jump to a new time in the track..
- */
-Media.prototype.seekTo = function(milliseconds) {
-    var me = this;
-    exec(function(p) {
-        me._position = p;
-    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
-};
-
-/**
- * Pause playing audio file.
- */
-Media.prototype.pause = function() {
-    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
-};
-
-/**
- * Get duration of an audio file.
- * The duration is only set for audio that is playing, paused or stopped.
- *
- * @return      duration or -1 if not known.
- */
-Media.prototype.getDuration = function() {
-    return this._duration;
-};
-
-/**
- * Get position of audio.
- */
-Media.prototype.getCurrentPosition = function(success, fail) {
-    var me = this;
-    exec(function(p) {
-        me._position = p;
-        success(p);
-    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
-};
-
-/**
- * Start recording audio file.
- */
-Media.prototype.startRecord = function() {
-    exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
-};
-
-/**
- * Stop recording audio file.
- */
-Media.prototype.stopRecord = function() {
-    exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
-};
-
-/**
- * Release the resources.
- */
-Media.prototype.release = function() {
-    exec(null, this.errorCallback, "Media", "release", [this.id]);
-};
-
-/**
- * Adjust the volume.
- */
-Media.prototype.setVolume = function(volume) {
-    exec(null, null, "Media", "setVolume", [this.id, volume]);
-};
-
-/**
- * Audio has status update.
- * PRIVATE
- *
- * @param id            The media object id (string)
- * @param msgType       The 'type' of update this is
- * @param value         Use of value is determined by the msgType
- */
-Media.onStatus = function(id, msgType, value) {
-
-    var media = mediaObjects[id];
-
-    if(media) {
-        switch(msgType) {
-            case Media.MEDIA_STATE :
-                media.statusCallback && media.statusCallback(value);
-                if(value == Media.MEDIA_STOPPED) {
-                    media.successCallback && media.successCallback();
-                }
-                break;
-            case Media.MEDIA_DURATION :
-                media._duration = value;
-                break;
-            case Media.MEDIA_ERROR :
-                media.errorCallback && media.errorCallback(value);
-                break;
-            case Media.MEDIA_POSITION :
-                media._position = Number(value);
-                break;
-            default :
-                console.error && console.error("Unhandled Media.onStatus :: " + msgType);
-                break;
-        }
-    }
-    else {
-         console.error && console.error("Received Media.onStatus callback for unknown media :: " + id);
-    }
-
-};
-
-module.exports = Media;
-
-});
-
-// file: lib/common/plugin/MediaError.js
-define("cordova/plugin/MediaError", function(require, exports, module) {
-
-/**
- * This class contains information about any Media errors.
-*/
-/*
- According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror
- We should never be creating these objects, we should just implement the interface
- which has 1 property for an instance, 'code'
-
- instead of doing :
-    errorCallbackFunction( new MediaError(3,'msg') );
-we should simply use a literal :
-    errorCallbackFunction( {'code':3} );
- */
-
- var _MediaError = window.MediaError;
-
-
-if(!_MediaError) {
-    window.MediaError = _MediaError = function(code, msg) {
-        this.code = (typeof code != 'undefined') ? code : null;
-        this.message = msg || ""; // message is NON-standard! do not use!
-    };
-}
-
-_MediaError.MEDIA_ERR_NONE_ACTIVE    = _MediaError.MEDIA_ERR_NONE_ACTIVE    || 0;
-_MediaError.MEDIA_ERR_ABORTED        = _MediaError.MEDIA_ERR_ABORTED        || 1;
-_MediaError.MEDIA_ERR_NETWORK        = _MediaError.MEDIA_ERR_NETWORK        || 2;
-_MediaError.MEDIA_ERR_DECODE         = _MediaError.MEDIA_ERR_DECODE         || 3;
-_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;
-// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.
-// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes
-_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;
-
-module.exports = _MediaError;
-
-});
-
-// file: lib/common/plugin/MediaFile.js
-define("cordova/plugin/MediaFile", function(require, exports, module) {
-
-var utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    File = require('cordova/plugin/File'),
-    CaptureError = require('cordova/plugin/CaptureError');
-/**
- * Represents a single file.
- *
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
-    MediaFile.__super__.constructor.apply(this, arguments);
-};
-
-utils.extend(MediaFile, File);
-
-/**
- * Request capture format data for a specific file and type
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- */
-MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
-    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
-        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
-    } else {
-        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
-    }
-};
-
-module.exports = MediaFile;
-
-});
-
-// file: lib/common/plugin/MediaFileData.js
-define("cordova/plugin/MediaFileData", function(require, exports, module) {
-
-/**
- * MediaFileData encapsulates format information of a media file.
- *
- * @param {DOMString} codecs
- * @param {long} bitrate
- * @param {long} height
- * @param {long} width
- * @param {float} duration
- */
-var MediaFileData = function(codecs, bitrate, height, width, duration){
-    this.codecs = codecs || null;
-    this.bitrate = bitrate || 0;
-    this.height = height || 0;
-    this.width = width || 0;
-    this.duration = duration || 0;
-};
-
-module.exports = MediaFileData;
-
-});
-
-// file: lib/common/plugin/Metadata.js
-define("cordova/plugin/Metadata", function(require, exports, module) {
-
-/**
- * Information about the state of the file or directory
- *
- * {Date} modificationTime (readonly)
- */
-var Metadata = function(time) {
-    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
-};
-
-module.exports = Metadata;
-
-});
-
-// file: lib/common/plugin/Position.js
-define("cordova/plugin/Position", function(require, exports, module) {
-
-var Coordinates = require('cordova/plugin/Coordinates');
-
-var Position = function(coords, timestamp) {
-    if (coords) {
-        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
-    } else {
-        this.coords = new Coordinates();
-    }
-    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
-};
-
-module.exports = Position;
-
-});
-
-// file: lib/common/plugin/PositionError.js
-define("cordova/plugin/PositionError", function(require, exports, module) {
-
-/**
- * Position error object
- *
- * @constructor
- * @param code
- * @param message
- */
-var PositionError = function(code, message) {
-    this.code = code || null;
-    this.message = message || '';
-};
-
-PositionError.PERMISSION_DENIED = 1;
-PositionError.POSITION_UNAVAILABLE = 2;
-PositionError.TIMEOUT = 3;
-
-module.exports = PositionError;
-
-});
-
-// file: lib/common/plugin/ProgressEvent.js
-define("cordova/plugin/ProgressEvent", function(require, exports, module) {
-
-// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
-// Feature test: See if we can instantiate a native ProgressEvent;
-// if so, use that approach,
-// otherwise fill-in with our own implementation.
-//
-// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
-var ProgressEvent = (function() {
-    /*
-    var createEvent = function(data) {
-        var event = document.createEvent('Events');
-        event.initEvent('ProgressEvent', false, false);
-        if (data) {
-            for (var i in data) {
-                if (data.hasOwnProperty(i)) {
-                    event[i] = data[i];
-                }
-            }
-            if (data.target) {
-                // TODO: cannot call <some_custom_object>.dispatchEvent
-                // need to first figure out how to implement EventTarget
-            }
-        }
-        return event;
-    };
-    try {
-        var ev = createEvent({type:"abort",target:document});
-        return function ProgressEvent(type, data) {
-            data.type = type;
-            return createEvent(data);
-        };
-    } catch(e){
-    */
-        return function ProgressEvent(type, dict) {
-            this.type = type;
-            this.bubbles = false;
-            this.cancelBubble = false;
-            this.cancelable = false;
-            this.lengthComputable = false;
-            this.loaded = dict && dict.loaded ? dict.loaded : 0;
-            this.total = dict && dict.total ? dict.total : 0;
-            this.target = dict && dict.target ? dict.target : null;
-        };
-    //}
-})();
-
-module.exports = ProgressEvent;
-
-});
-
-// file: lib/common/plugin/accelerometer.js
-define("cordova/plugin/accelerometer", function(require, exports, module) {
-
-/**
- * This class provides access to device accelerometer data.
- * @constructor
- */
-var argscheck = require('cordova/argscheck'),
-    utils = require("cordova/utils"),
-    exec = require("cordova/exec"),
-    Acceleration = require('cordova/plugin/Acceleration');
-
-// Is the accel sensor running?
-var running = false;
-
-// Keeps reference to watchAcceleration calls.
-var timers = {};
-
-// Array of listeners; used to keep track of when we should call start and stop.
-var listeners = [];
-
-// Last returned acceleration object from native
-var accel = null;
-
-// Tells native to start.
-function start() {
-    exec(function(a) {
-        var tempListeners = listeners.slice(0);
-        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
-        for (var i = 0, l = tempListeners.length; i < l; i++) {
-            tempListeners[i].win(accel);
-        }
-    }, function(e) {
-        var tempListeners = listeners.slice(0);
-        for (var i = 0, l = tempListeners.length; i < l; i++) {
-            tempListeners[i].fail(e);
-        }
-    }, "Accelerometer", "start", []);
-    running = true;
-}
-
-// Tells native to stop.
-function stop() {
-    exec(null, null, "Accelerometer", "stop", []);
-    running = false;
-}
-
-// Adds a callback pair to the listeners array
-function createCallbackPair(win, fail) {
-    return {win:win, fail:fail};
-}
-
-// Removes a win/fail listener pair from the listeners array
-function removeListeners(l) {
-    var idx = listeners.indexOf(l);
-    if (idx > -1) {
-        listeners.splice(idx, 1);
-        if (listeners.length === 0) {
-            stop();
-        }
-    }
-}
-
-var accelerometer = {
-    /**
-     * Asynchronously acquires the current acceleration.
-     *
-     * @param {Function} successCallback    The function to call when the acceleration data is available
-     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
-     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
-     */
-    getCurrentAcceleration: function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'accelerometer.getCurrentAcceleration', arguments);
-
-        var p;
-        var win = function(a) {
-            removeListeners(p);
-            successCallback(a);
-        };
-        var fail = function(e) {
-            removeListeners(p);
-            errorCallback && errorCallback(e);
-        };
-
-        p = createCallbackPair(win, fail);
-        listeners.push(p);
-
-        if (!running) {
-            start();
-        }
-    },
-
-    /**
-     * Asynchronously acquires the acceleration repeatedly at a given interval.
-     *
-     * @param {Function} successCallback    The function to call each time the acceleration data is available
-     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
-     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
-     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
-     */
-    watchAcceleration: function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'accelerometer.watchAcceleration', arguments);
-        // Default interval (10 sec)
-        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
-
-        // Keep reference to watch id, and report accel readings as often as defined in frequency
-        var id = utils.createUUID();
-
-        var p = createCallbackPair(function(){}, function(e) {
-            removeListeners(p);
-            errorCallback && errorCallback(e);
-        });
-        listeners.push(p);
-
-        timers[id] = {
-            timer:window.setInterval(function() {
-                if (accel) {
-                    successCallback(accel);
-                }
-            }, frequency),
-            listeners:p
-        };
-
-        if (running) {
-            // If we're already running then immediately invoke the success callback
-            // but only if we have retrieved a value, sample code does not check for null ...
-            if (accel) {
-                successCallback(accel);
-            }
-        } else {
-            start();
-        }
-
-        return id;
-    },
-
-    /**
-     * Clears the specified accelerometer watch.
-     *
-     * @param {String} id       The id of the watch returned from #watchAcceleration.
-     */
-    clearWatch: function(id) {
-        // Stop javascript timer & remove from timer list
-        if (id && timers[id]) {
-            window.clearInterval(timers[id].timer);
-            removeListeners(timers[id].listeners);
-            delete timers[id];
-        }
-    }
-};
-
-module.exports = accelerometer;
-
-});
-
-// file: lib/common/plugin/accelerometer/symbols.js
-define("cordova/plugin/accelerometer/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/Acceleration', 'Acceleration');
-modulemapper.defaults('cordova/plugin/accelerometer', 'navigator.accelerometer');
-
-});
-
-// file: lib/common/plugin/battery.js
-define("cordova/plugin/battery", function(require, exports, module) {
-
-/**
- * This class contains information about the current battery status.
- * @constructor
- */
-var cordova = require('cordova'),
-    exec = require('cordova/exec');
-
-function handlers() {
-  return battery.channels.batterystatus.numHandlers +
-         battery.channels.batterylow.numHandlers +
-         battery.channels.batterycritical.numHandlers;
-}
-
-var Battery = function() {
-    this._level = null;
-    this._isPlugged = null;
-    // Create new event handlers on the window (returns a channel instance)
-    this.channels = {
-      batterystatus:cordova.addWindowEventHandler("batterystatus"),
-      batterylow:cordova.addWindowEventHandler("batterylow"),
-      batterycritical:cordova.addWindowEventHandler("batterycritical")
-    };
-    for (var key in this.channels) {
-        this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange;
-    }
-};
-/**
- * Event handlers for when callbacks get registered for the battery.
- * Keep track of how many handlers we have so we can start and stop the native battery listener
- * appropriately (and hopefully save on battery life!).
- */
-Battery.onHasSubscribersChange = function() {
-  // If we just registered the first handler, make sure native listener is started.
-  if (this.numHandlers === 1 && handlers() === 1) {
-      exec(battery._status, battery._error, "Battery", "start", []);
-  } else if (handlers() === 0) {
-      exec(null, null, "Battery", "stop", []);
-  }
-};
-
-/**
- * Callback for battery status
- *
- * @param {Object} info            keys: level, isPlugged
- */
-Battery.prototype._status = function(info) {
-    if (info) {
-        var me = battery;
-    var level = info.level;
-        if (me._level !== level || me._isPlugged !== info.isPlugged) {
-            // Fire batterystatus event
-            cordova.fireWindowEvent("batterystatus", info);
-
-            // Fire low battery event
-            if (level === 20 || level === 5) {
-                if (level === 20) {
-                    cordova.fireWindowEvent("batterylow", info);
-                }
-                else {
-                    cordova.fireWindowEvent("batterycritical", info);
-                }
-            }
-        }
-        me._level = level;
-        me._isPlugged = info.isPlugged;
-    }
-};
-
-/**
- * Error callback for battery start
- */
-Battery.prototype._error = function(e) {
-    console.log("Error initializing Battery: " + e);
-};
-
-var battery = new Battery();
-
-module.exports = battery;
-
-});
-
-// file: lib/common/plugin/battery/symbols.js
-define("cordova/plugin/battery/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/battery', 'navigator.battery');
-
-});
-
-// file: lib/common/plugin/camera/symbols.js
-define("cordova/plugin/camera/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/Camera', 'navigator.camera');
-modulemapper.defaults('cordova/plugin/CameraConstants', 'Camera');
-modulemapper.defaults('cordova/plugin/CameraPopoverOptions', 'CameraPopoverOptions');
-
-});
-
-// 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/capture/symbols.js
-define("cordova/plugin/capture/symbols", function(require, exports, module) {
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/CaptureError', 'CaptureError');
-modulemapper.clobbers('cordova/plugin/CaptureAudioOptions', 'CaptureAudioOptions');
-modulemapper.clobbers('cordova/plugin/CaptureImageOptions', 'CaptureImageOptions');
-modulemapper.clobbers('cordova/plugin/CaptureVideoOptions', 'CaptureVideoOptions');
-modulemapper.clobbers('cordova/plugin/ConfigurationData', 'ConfigurationData');
-modulemapper.clobbers('cordova/plugin/MediaFile', 'MediaFile');
-modulemapper.clobbers('cordova/plugin/MediaFileData', 'MediaFileData');
-modulemapper.clobbers('cordova/plugin/capture', 'navigator.device.capture');
-
-});
-
-// file: lib/common/plugin/compass.js
-define("cordova/plugin/compass", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    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) {
-            argscheck.checkArgs('fFO', 'compass.getCurrentHeading', arguments);
-
-            var win = function(result) {
-                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
-                successCallback(ch);
-            };
-            var fail = errorCallback && 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) {
-            argscheck.checkArgs('fFO', 'compass.watchHeading', arguments);
-            // Default interval (100 msec)
-            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
-            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
-
-            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/compass/symbols.js
-define("cordova/plugin/compass/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/CompassHeading', 'CompassHeading');
-modulemapper.clobbers('cordova/plugin/CompassError', 'CompassError');
-modulemapper.clobbers('cordova/plugin/compass', 'navigator.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 = logger.format.apply(logger.format, [].slice.call(arguments, 1));
-    console.log("ASSERT: " + message);
-};
-
-//------------------------------------------------------------------------------
-console.clear = function() {};
-
-//------------------------------------------------------------------------------
-console.dir = function(object) {
-    console.log("%o", object);
-};
-
-//------------------------------------------------------------------------------
-console.dirxml = function(node) {
-    console.log(node.innerHTML);
-};
-
-//------------------------------------------------------------------------------
-console.trace = noop;
-
-//------------------------------------------------------------------------------
-console.group = console.log;
-
-//------------------------------------------------------------------------------
-console.groupCollapsed = console.log;
-
-//------------------------------------------------------------------------------
-console.groupEnd = noop;
-
-//------------------------------------------------------------------------------
-console.time = function(name) {
-    Timers[name] = new Date().valueOf();
-};
-
-//------------------------------------------------------------------------------
-console.timeEnd = function(name) {
-    var timeStart = Timers[name];
-    if (!timeStart) {
-        console.warn("unknown timer: " + name);
-        return;
-    }
-
-    var timeElapsed = new Date().valueOf() - timeStart;
-    console.log(name + ": " + timeElapsed + "ms");
-};
-
-//------------------------------------------------------------------------------
-console.timeStamp = noop;
-
-//------------------------------------------------------------------------------
-console.profile = noop;
-
-//------------------------------------------------------------------------------
-console.profileEnd = noop;
-
-//------------------------------------------------------------------------------
-console.count = noop;
-
-//------------------------------------------------------------------------------
-console.exception = console.log;
-
-//------------------------------------------------------------------------------
-console.table = function(data, columns) {
-    console.log("%o", data);
-};
-
-//------------------------------------------------------------------------------
-// return a new function that calls both functions passed as args
-//------------------------------------------------------------------------------
-function wrappedOrigCall(orgFunc, newFunc) {
-    return function() {
-        var args = [].slice.call(arguments);
-        try { orgFunc.apply(WinConsole, args); } catch (e) {}
-        try { newFunc.apply(console,    args); } catch (e) {}
-    };
-}
-
-//------------------------------------------------------------------------------
-// For every function that exists in the original console object, that
-// also exists in the new console object, wrap the new console method
-// with one that calls both
-//------------------------------------------------------------------------------
-for (var key in console) {
-    if (typeof WinConsole[key] == "function") {
-        console[key] = wrappedOrigCall(WinConsole[key], console[key]);
-    }
-}
-
-});
-
-// file: lib/common/plugin/contacts.js
-define("cordova/plugin/contacts", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    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) {
-        argscheck.checkArgs('afFO', 'contacts.find', arguments);
-        if (!fields.length) {
-            errorCB && errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
-        } else {
-            var win = function(result) {
-                var cs = [];
-                for (var i = 0, l = result.length; i < l; i++) {
-                    cs.push(contacts.create(result[i]));
-                }
-                successCB(cs);
-            };
-            exec(win, errorCB, "Contacts", "search", [fields, options]);
-        }
-    },
-
-    /**
-     * This function creates a new contact, but it does not persist the contact
-     * to device storage. To persist the contact to device storage, invoke
-     * contact.save().
-     * @param properties an object whose properties will be examined to create a new Contact
-     * @returns new Contact object
-     */
-    create:function(properties) {
-        argscheck.checkArgs('O', 'contacts.create', arguments);
-        var contact = new Contact();
-        for (var i in properties) {
-            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
-                contact[i] = properties[i];
-            }
-        }
-        return contact;
-    }
-};
-
-module.exports = contacts;
-
-});
-
-// file: lib/common/plugin/contacts/symbols.js
-define("cordova/plugin/contacts/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/contacts', 'navigator.contacts');
-modulemapper.clobbers('cordova/plugin/Contact', 'Contact');
-modulemapper.clobbers('cordova/plugin/ContactAddress', 'ContactAddress');
-modulemapper.clobbers('cordova/plugin/ContactError', 'ContactError');
-modulemapper.clobbers('cordova/plugin/ContactField', 'ContactField');
-modulemapper.clobbers('cordova/plugin/ContactFindOptions', 'ContactFindOptions');
-modulemapper.clobbers('cordova/plugin/ContactName', 'ContactName');
-modulemapper.clobbers('cordova/plugin/ContactOrganization', 'ContactOrganization');
-
-});
-
-// file: lib/common/plugin/device.js
-define("cordova/plugin/device", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    channel = require('cordova/channel'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec');
-
-// Tell cordova channel to wait on the CordovaInfoReady event
-channel.waitForInitialization('onCordovaInfoReady');
-
-/**
- * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
- * phone, etc.
- * @constructor
- */
-function Device() {
-    this.available = false;
-    this.platform = null;
-    this.version = null;
-    this.uuid = null;
-    this.cordova = null;
-    this.model = null;
-
-    var me = this;
-
-    channel.onCordovaReady.subscribe(function() {
-        me.getInfo(function(info) {
-            var buildLabel = info.cordova;
-            if (buildLabel != CORDOVA_JS_BUILD_LABEL) {
-                buildLabel += ' JS=' + CORDOVA_JS_BUILD_LABEL;
-            }
-            me.available = true;
-            me.platform = info.platform;
-            me.version = info.version;
-            me.uuid = info.uuid;
-            me.cordova = buildLabel;
-            me.model = info.model;
-            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) {
-    argscheck.checkArgs('fF', 'Device.getInfo', arguments);
-    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
-};
-
-module.exports = new Device();
-
-});
-
-// file: lib/common/plugin/device/symbols.js
-define("cordova/plugin/device/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/device', 'device');
-
-});
-
-// file: lib/common/plugin/echo.js
-define("cordova/plugin/echo", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    utils = require('cordova/utils');
-
-/**
- * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.
- * @param successCallback  invoked with a FileSystem object
- * @param errorCallback  invoked if error occurs retrieving file system
- * @param message  The string to be echoed.
- * @param forceAsync  Whether to force an async return value (for testing native->js bridge).
- */
-module.exports = function(successCallback, errorCallback, message, forceAsync) {
-    var action = 'echo';
-    var messageIsMultipart = (utils.typeName(message) == "Array");
-    var args = messageIsMultipart ? message : [message];
-
-    if (utils.typeName(message) == 'ArrayBuffer') {
-        if (forceAsync) {
-            console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');
-        }
-        action += 'ArrayBuffer';
-    } else if (messageIsMultipart) {
-        if (forceAsync) {
-            console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');
-        }
-        action += 'MultiPart';
-    } else if (forceAsync) {
-        action += 'Async';
-    }
-
-    exec(successCallback, errorCallback, "Echo", action, args);
-};
-
-
-});
-
-// file: lib/windowsphone/plugin/file/symbols.js
-define("cordova/plugin/file/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper'),
-    symbolshelper = require('cordova/plugin/file/symbolshelper');
-
-symbolshelper(modulemapper.defaults);
-
-});
-
-// file: lib/common/plugin/file/symbolshelper.js
-define("cordova/plugin/file/symbolshelper", function(require, exports, module) {
-
-module.exports = function(exportFunc) {
-    exportFunc('cordova/plugin/DirectoryEntry', 'DirectoryEntry');
-    exportFunc('cordova/plugin/DirectoryReader', 'DirectoryReader');
-    exportFunc('cordova/plugin/Entry', 'Entry');
-    exportFunc('cordova/plugin/File', 'File');
-    exportFunc('cordova/plugin/FileEntry', 'FileEntry');
-    exportFunc('cordova/plugin/FileError', 'FileError');
-    exportFunc('cordova/plugin/FileReader', 'FileReader');
-    exportFunc('cordova/plugin/FileSystem', 'FileSystem');
-    exportFunc('cordova/plugin/FileUploadOptions', 'FileUploadOptions');
-    exportFunc('cordova/plugin/FileUploadResult', 'FileUploadResult');
-    exportFunc('cordova/plugin/FileWriter', 'FileWriter');
-    exportFunc('cordova/plugin/Flags', 'Flags');
-    exportFunc('cordova/plugin/LocalFileSystem', 'LocalFileSystem');
-    exportFunc('cordova/plugin/Metadata', 'Metadata');
-    exportFunc('cordova/plugin/ProgressEvent', 'ProgressEvent');
-    exportFunc('cordova/plugin/requestFileSystem', 'requestFileSystem');
-    exportFunc('cordova/plugin/resolveLocalFileSystemURI', 'resolveLocalFileSystemURI');
-};
-
-});
-
-// file: lib/windowsphone/plugin/filetransfer/symbols.js
-define("cordova/plugin/filetransfer/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/windowsphone/FileTransfer', 'FileTransfer');
-modulemapper.clobbers('cordova/plugin/FileTransferError', 'FileTransferError');
-
-});
-
-// file: lib/common/plugin/geolocation.js
-define("cordova/plugin/geolocation", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec'),
-    PositionError = require('cordova/plugin/PositionError'),
-    Position = require('cordova/plugin/Position');
-
-var timers = {};   // list of timers in use
-
-// Returns default params, overrides if provided with values
-function parseParameters(options) {
-    var opt = {
-        maximumAge: 0,
-        enableHighAccuracy: false,
-        timeout: Infinity
-    };
-
-    if (options) {
-        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
-            opt.maximumAge = options.maximumAge;
-        }
-        if (options.enableHighAccuracy !== undefined) {
-            opt.enableHighAccuracy = options.enableHighAccuracy;
-        }
-        if (options.timeout !== undefined && !isNaN(options.timeout)) {
-            if (options.timeout < 0) {
-                opt.timeout = 0;
-            } else {
-                opt.timeout = options.timeout;
-            }
-        }
-    }
-
-    return opt;
-}
-
-// Returns a timeout failure, closed over a specified timeout value and error callback.
-function createTimeout(errorCallback, timeout) {
-    var t = setTimeout(function() {
-        clearTimeout(t);
-        t = null;
-        errorCallback({
-            code:PositionError.TIMEOUT,
-            message:"Position retrieval timed out."
-        });
-    }, timeout);
-    return t;
-}
-
-var geolocation = {
-    lastPosition:null, // reference to last known (cached) position returned
-    /**
-   * Asynchronously acquires the current position.
-   *
-   * @param {Function} successCallback    The function to call when the position data is available
-   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
-   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
-   */
-    getCurrentPosition:function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments);
-        options = parseParameters(options);
-
-        // Timer var that will fire an error callback if no position is retrieved from native
-        // before the "timeout" param provided expires
-        var timeoutTimer = {timer:null};
-
-        var win = function(p) {
-            clearTimeout(timeoutTimer.timer);
-            if (!(timeoutTimer.timer)) {
-                // Timeout already happened, or native fired error callback for
-                // this geo request.
-                // Don't continue with success callback.
-                return;
-            }
-            var pos = new Position(
-                {
-                    latitude:p.latitude,
-                    longitude:p.longitude,
-                    altitude:p.altitude,
-                    accuracy:p.accuracy,
-                    heading:p.heading,
-                    velocity:p.velocity,
-                    altitudeAccuracy:p.altitudeAccuracy
-                },
-                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
-            );
-            geolocation.lastPosition = pos;
-            successCallback(pos);
-        };
-        var fail = function(e) {
-            clearTimeout(timeoutTimer.timer);
-            timeoutTimer.timer = null;
-            var err = new PositionError(e.code, e.message);
-            if (errorCallback) {
-                errorCallback(err);
-            }
-        };
-
-        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
-        // fire the success callback with the cached position.
-        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
-            successCallback(geolocation.lastPosition);
-        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
-        } else if (options.timeout === 0) {
-            fail({
-                code:PositionError.TIMEOUT,
-                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."
-            });
-        // Otherwise we have to call into native to retrieve a position.
-        } else {
-            if (options.timeout !== Infinity) {
-                // If the timeout value was not set to Infinity (default), then
-                // set up a timeout function that will fire the error callback
-                // if no successful position was retrieved before timeout expired.
-                timeoutTimer.timer = createTimeout(fail, options.timeout);
-            } else {
-                // This is here so the check in the win function doesn't mess stuff up
-                // may seem weird but this guarantees timeoutTimer is
-                // always truthy before we call into native
-                timeoutTimer.timer = true;
-            }
-            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
-        }
-        return timeoutTimer;
-    },
-    /**
-     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
-     * the successCallback is called with the new location.
-     *
-     * @param {Function} successCallback    The function to call each time the location data is available
-     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
-     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
-     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
-     */
-    watchPosition:function(successCallback, errorCallback, options) {
-        argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments);
-        options = parseParameters(options);
-
-        var id = utils.createUUID();
-
-        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
-        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
-
-        var fail = function(e) {
-            clearTimeout(timers[id].timer);
-            var err = new PositionError(e.code, e.message);
-            if (errorCallback) {
-                errorCallback(err);
-            }
-        };
-
-        var win = function(p) {
-            clearTimeout(timers[id].timer);
-            if (options.timeout !== Infinity) {
-                timers[id].timer = createTimeout(fail, options.timeout);
-            }
-            var pos = new Position(
-                {
-                    latitude:p.latitude,
-                    longitude:p.longitude,
-                    altitude:p.altitude,
-                    accuracy:p.accuracy,
-                    heading:p.heading,
-                    velocity:p.velocity,
-                    altitudeAccuracy:p.altitudeAccuracy
-                },
-                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
-            );
-            geolocation.lastPosition = pos;
-            successCallback(pos);
-        };
-
-        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
-
-        return id;
-    },
-    /**
-     * Clears the specified heading watch.
-     *
-     * @param {String} id       The ID of the watch returned from #watchPosition
-     */
-    clearWatch:function(id) {
-        if (id && timers[id] !== undefined) {
-            clearTimeout(timers[id].timer);
-            timers[id].timer = false;
-            exec(null, null, "Geolocation", "clearWatch", [id]);
-        }
-    }
-};
-
-module.exports = geolocation;
-
-});
-
-// file: lib/common/plugin/geolocation/symbols.js
-define("cordova/plugin/geolocation/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/geolocation', 'navigator.geolocation');
-modulemapper.clobbers('cordova/plugin/PositionError', 'PositionError');
-modulemapper.clobbers('cordova/plugin/Position', 'Position');
-modulemapper.clobbers('cordova/plugin/Coordinates', 'Coordinates');
-
-});
-
-// file: lib/common/plugin/globalization.js
-define("cordova/plugin/globalization", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    GlobalizationError = require('cordova/plugin/GlobalizationError');
-
-var globalization = {
-
-/**
-* Returns the string identifier for the client's current language.
-* It returns the language identifier string to the successCB callback with a
-* properties object as a parameter. If there is an error getting the language,
-* then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {String}: The language identifier
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},
-*                                function () {});
-*/
-getPreferredLanguage:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getPreferredLanguage', arguments);
-    exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);
-},
-
-/**
-* Returns the string identifier for the client's current locale setting.
-* It returns the locale identifier string to the successCB callback with a
-* properties object as a parameter. If there is an error getting the locale,
-* then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {String}: The locale identifier
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},
-*                                function () {});
-*/
-getLocaleName:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getLocaleName', arguments);
-    exec(successCB, failureCB, "Globalization","getLocaleName", []);
-},
-
-
-/**
-* Returns a date formatted as a string according to the client's user preferences and
-* calendar using the time zone of the client. It returns the formatted date string to the
-* successCB callback with a properties object as a parameter. If there is an error
-* formatting the date, then the errorCB callback is invoked.
-*
-* The defaults are: formatLenght="short" and selector="date and time"
-*
-* @param {Date} date
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return Object.value {String}: The localized date string
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.dateToString(new Date(),
-*                function (date) {alert('date:' + date.value + '\n');},
-*                function (errorCode) {alert(errorCode);},
-*                {formatLength:'short'});
-*/
-dateToString:function(date, successCB, failureCB, options) {
-    argscheck.checkArgs('dfFO', 'Globalization.dateToString', arguments);
-    var dateValue = date.valueOf();
-    exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);
-},
-
-
-/**
-* Parses a date formatted as a string according to the client's user
-* preferences and calendar using the time zone of the client and returns
-* the corresponding date object. It returns the date to the successCB
-* callback with a properties object as a parameter. If there is an error
-* parsing the date string, then the errorCB callback is invoked.
-*
-* The defaults are: formatLength="short" and selector="date and time"
-*
-* @param {String} dateString
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return    Object.year {Number}: The four digit year
-*            Object.month {Number}: The month from (0 - 11)
-*            Object.day {Number}: The day from (1 - 31)
-*            Object.hour {Number}: The hour from (0 - 23)
-*            Object.minute {Number}: The minute from (0 - 59)
-*            Object.second {Number}: The second from (0 - 59)
-*            Object.millisecond {Number}: The milliseconds (from 0 - 999),
-*                                        not available on all platforms
-*
-* @error GlobalizationError.PARSING_ERROR
-*
-* Example
-*    globalization.stringToDate('4/11/2011',
-*                function (date) { alert('Month:' + date.month + '\n' +
-*                    'Day:' + date.day + '\n' +
-*                    'Year:' + date.year + '\n');},
-*                function (errorCode) {alert(errorCode);},
-*                {selector:'date'});
-*/
-stringToDate:function(dateString, successCB, failureCB, options) {
-    argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);
-    exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);
-},
-
-
-/**
-* Returns a pattern string for formatting and parsing dates according to the client's
-* user preferences. It returns the pattern to the successCB callback with a
-* properties object as a parameter. If there is an error obtaining the pattern,
-* then the errorCB callback is invoked.
-*
-* The defaults are: formatLength="short" and selector="date and time"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.
-*                                    The patterns follow Unicode Technical Standard #35
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.timezone {String}: The abbreviated name of the time zone on the client
-*            Object.utc_offset {Number}: The current difference in seconds between the client's
-*                                        time zone and coordinated universal time.
-*            Object.dst_offset {Number}: The current daylight saving time offset in seconds
-*                                        between the client's non-daylight saving's time zone
-*                                        and the client's daylight saving's time zone.
-*
-* @error GlobalizationError.PATTERN_ERROR
-*
-* Example
-*    globalization.getDatePattern(
-*                function (date) {alert('pattern:' + date.pattern + '\n');},
-*                function () {},
-*                {formatLength:'short'});
-*/
-getDatePattern:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getDatePattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);
-},
-
-
-/**
-* Returns an array of either the names of the months or days of the week
-* according to the client's user preferences and calendar. It returns the array of names to the
-* successCB callback with a properties object as a parameter. If there is an error obtaining the
-* names, then the errorCB callback is invoked.
-*
-* The defaults are: type="wide" and item="months"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'narrow' or 'wide'
-*            item {String}: 'months', or 'days'
-*
-* @return Object.value {Array{String}}: The array of names starting from either
-*                                        the first month in the year or the
-*                                        first day of the week.
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getDateNames(function (names) {
-*        for(var i = 0; i < names.value.length; i++) {
-*            alert('Month:' + names.value[i] + '\n');}},
-*        function () {});
-*/
-getDateNames:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);
-    exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);
-},
-
-/**
-* Returns whether daylight savings time is in effect for a given date using the client's
-* time zone and calendar. It returns whether or not daylight savings time is in effect
-* to the successCB callback with a properties object as a parameter. If there is an error
-* reading the date, then the errorCB callback is invoked.
-*
-* @param {Date} date
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is
-*                                in effect for the given date and "false" indicate that it is not.
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.isDayLightSavingsTime(new Date(),
-*                function (date) {alert('dst:' + date.dst + '\n');}
-*                function () {});
-*/
-isDayLightSavingsTime:function(date, successCB, failureCB) {
-    argscheck.checkArgs('dfF', 'Globalization.isDayLightSavingsTime', arguments);
-    var dateValue = date.valueOf();
-    exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);
-},
-
-/**
-* Returns the first day of the week according to the client's user preferences and calendar.
-* The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-* It returns the day to the successCB callback with a properties object as a parameter.
-* If there is an error obtaining the pattern, then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {Number}: The number of the first day of the week.
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getFirstDayOfWeek(function (day)
-*                { alert('Day:' + day.value + '\n');},
-*                function () {});
-*/
-getFirstDayOfWeek:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments);
-    exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);
-},
-
-
-/**
-* Returns a number formatted as a string according to the client's user preferences.
-* It returns the formatted number string to the successCB callback with a properties object as a
-* parameter. If there is an error formatting the number, then the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {Number} number
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return Object.value {String}: The formatted number string.
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.numberToString(3.25,
-*                function (number) {alert('number:' + number.value + '\n');},
-*                function () {},
-*                {type:'decimal'});
-*/
-numberToString:function(number, successCB, failureCB, options) {
-    argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);
-    exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);
-},
-
-/**
-* Parses a number formatted as a string according to the client's user preferences and
-* returns the corresponding number. It returns the number to the successCB callback with a
-* properties object as a parameter. If there is an error parsing the number string, then
-* the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {String} numberString
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return Object.value {Number}: The parsed number.
-*
-* @error GlobalizationError.PARSING_ERROR
-*
-* Example
-*    globalization.stringToNumber('1234.56',
-*                function (number) {alert('Number:' + number.value + '\n');},
-*                function () { alert('Error parsing number');});
-*/
-stringToNumber:function(numberString, successCB, failureCB, options) {
-    argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);
-    exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);
-},
-
-/**
-* Returns a pattern string for formatting and parsing numbers according to the client's user
-* preferences. It returns the pattern to the successCB callback with a properties object as a
-* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.
-*                                    The patterns follow Unicode Technical Standard #35.
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.symbol {String}: The symbol to be used when formatting and parsing
-*                                    e.g., percent or currency symbol.
-*            Object.fraction {Number}: The number of fractional digits to use when parsing and
-*                                    formatting numbers.
-*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-*            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
-*            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
-*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-*
-* @error GlobalizationError.PATTERN_ERROR
-*
-* Example
-*    globalization.getNumberPattern(
-*                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},
-*                function () {});
-*/
-getNumberPattern:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);
-},
-
-/**
-* Returns a pattern string for formatting and parsing currency values according to the client's
-* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
-* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
-* callback is invoked.
-*
-* @param {String} currencyCode
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.
-*                                    The patterns follow Unicode Technical Standard #35
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.code {String}: The ISO 4217 currency code for the pattern.
-*            Object.fraction {Number}: The number of fractional digits to use when parsing and
-*                                    formatting currency.
-*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.getCurrencyPattern('EUR',
-*                function (currency) {alert('Pattern:' + currency.pattern + '\n');}
-*                function () {});
-*/
-getCurrencyPattern:function(currencyCode, successCB, failureCB) {
-    argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);
-}
-
-};
-
-module.exports = globalization;
-
-});
-
-// file: lib/common/plugin/globalization/symbols.js
-define("cordova/plugin/globalization/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/globalization', 'navigator.globalization');
-modulemapper.clobbers('cordova/plugin/GlobalizationError', 'GlobalizationError');
-
-});
-
-// file: lib/windowsphone/plugin/inappbrowser/symbols.js
-define("cordova/plugin/inappbrowser/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/InAppBrowser', 'open');
-
-});
-
-// 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 UseLogger    = true;
-var Queued       = [];
-var DeviceReady  = false;
-var CurrentLevel;
-
-var originalConsole = console;
-
-/**
- * Logging levels
- */
-
-var Levels = [
-    "LOG",
-    "ERROR",
-    "WARN",
-    "INFO",
-    "DEBUG"
-];
-
-/*
- * add the logging levels to the logger object and
- * to a separate levelsMap object for testing
- */
-
-var LevelsMap = {};
-for (var i=0; i<Levels.length; i++) {
-    var level = Levels[i];
-    LevelsMap[level] = i;
-    logger[level]    = level;
-}
-
-CurrentLevel = LevelsMap.WARN;
-
-/**
- * Getter/Setter for the logging level
- *
- * Returns the current logging level.
- *
- * When a value is passed, sets the logging level to that value.
- * The values should be one of the following constants:
- *    logger.LOG
- *    logger.ERROR
- *    logger.WARN
- *    logger.INFO
- *    logger.DEBUG
- *
- * The value used determines which messages get printed.  The logging
- * values above are in order, and only messages logged at the logging
- * level or above will actually be displayed to the user.  E.g., the
- * default level is WARN, so only messages logged with LOG, ERROR, or
- * WARN will be displayed; INFO and DEBUG messages will be ignored.
- */
-logger.level = function (value) {
-    if (arguments.length) {
-        if (LevelsMap[value] === null) {
-            throw new Error("invalid logging level: " + value);
-        }
-        CurrentLevel = LevelsMap[value];
-    }
-
-    return Levels[CurrentLevel];
-};
-
-/**
- * Getter/Setter for the useConsole functionality
- *
- * When useConsole is true, the logger will log via the
- * browser 'console' object.
- */
-logger.useConsole = function (value) {
-    if (arguments.length) UseConsole = !!value;
-
-    if (UseConsole) {
-        if (typeof console == "undefined") {
-            throw new Error("global console object is not defined");
-        }
-
-        if (typeof console.log != "function") {
-            throw new Error("global console object does not have a log function");
-        }
-
-        if (typeof console.useLogger == "function") {
-            if (console.useLogger()) {
-                throw new Error("console and logger are too intertwingly");
-            }
-        }
-    }
-
-    return UseConsole;
-};
-
-/**
- * Getter/Setter for the useLogger functionality
- *
- * When useLogger is true, the logger will log via the
- * native Logger plugin.
- */
-logger.useLogger = function (value) {
-    // Enforce boolean
-    if (arguments.length) UseLogger = !!value;
-    return UseLogger;
-};
-
-/**
- * Logs a message at the LOG level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.log   = function(message) { logWithArgs("LOG",   arguments); };
-
-/**
- * Logs a message at the ERROR level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.error = function(message) { logWithArgs("ERROR", arguments); };
-
-/**
- * Logs a message at the WARN level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
-
-/**
- * Logs a message at the INFO level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.info  = function(message) { logWithArgs("INFO",  arguments); };
-
-/**
- * Logs a message at the DEBUG level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
-
-// log at the specified level with args
-function logWithArgs(level, args) {
-    args = [level].concat([].slice.call(args));
-    logger.logLevel.apply(logger, args);
-}
-
-/**
- * Logs a message at the specified level.
- *
- * Parameters passed after message are used applied to
- * the message with utils.format()
- */
-logger.logLevel = function(level /* , ... */) {
-    // format the message with the parameters
-    var formatArgs = [].slice.call(arguments, 1);
-    var message    = logger.format.apply(logger.format, formatArgs);
-
-    if (LevelsMap[level] === null) {
-        throw new Error("invalid logging level: " + level);
-    }
-
-    if (LevelsMap[level] > CurrentLevel) return;
-
-    // queue the message if not yet at deviceready
-    if (!DeviceReady && !UseConsole) {
-        Queued.push([level, message]);
-        return;
-    }
-
-    // Log using the native logger if that is enabled
-    if (UseLogger) {
-        exec(null, null, "Logger", "logLevel", [level, message]);
-    }
-
-    // Log using the console if that is enabled
-    if (UseConsole) {
-        // 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:   originalConsole.log(message); break;
-            case logger.ERROR: originalConsole.log("ERROR: " + message); break;
-            case logger.WARN:  originalConsole.log("WARN: "  + message); break;
-            case logger.INFO:  originalConsole.log("INFO: "  + message); break;
-            case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;
-        }
-    }
-};
-
-
-/**
- * Formats a string and arguments following it ala console.log()
- *
- * Any remaining arguments will be appended to the formatted string.
- *
- * for rationale, see FireBug's Console API:
- *    http://getfirebug.com/wiki/index.php/Console_API
- */
-logger.format = function(formatString, args) {
-    return __format(arguments[0], [].slice.call(arguments,1)).join(' ');
-};
-
-
-//------------------------------------------------------------------------------
-/**
- * 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().
- *
- * Returns an array containing the formatted string and any remaining
- * arguments.
- */
-function __format(formatString, args) {
-    if (formatString === null || formatString === undefined) return [""];
-    if (arguments.length == 1) return [formatString.toString()];
-
-    if (typeof formatString != "string")
-        formatString = formatString.toString();
-
-    var pattern = /(.*?)%(.)(.*)/;
-    var rest    = formatString;
-    var result  = [];
-
-    while (args.length) {
-        var match = pattern.exec(rest);
-        if (!match) break;
-
-        var arg   = args.shift();
-        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);
-
-    var remainingArgs = [].slice.call(args);
-    remainingArgs.unshift(result.join(''));
-    return remainingArgs;
-}
-
-function __formatted(object, formatChar) {
-
-    try {
-        switch(formatChar) {
-            case 'j':
-            case 'o': return JSON.stringify(object);
-            case 'c': return '';
-        }
-    }
-    catch (e) {
-        return "error JSON.stringify()ing argument: " + e;
-    }
-
-    if ((object === null) || (object === undefined)) {
-        return Object.prototype.toString.call(object);
-    }
-
-    return object.toString();
-}
-
-
-//------------------------------------------------------------------------------
-// when deviceready fires, log queued messages
-logger.__onDeviceReady = function() {
-    if (DeviceReady) return;
-
-    DeviceReady = true;
-
-    for (var i=0; i<Queued.length; i++) {
-        var messageArgs = Queued[i];
-        logger.logLevel(messageArgs[0], messageArgs[1]);
-    }
-
-    Queued = null;
-};
-
-// add a deviceready event to log queued messages
-document.addEventListener("deviceready", logger.__onDeviceReady, false);
-
-});
-
-// file: lib/common/plugin/logger/symbols.js
-define("cordova/plugin/logger/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/logger', 'cordova.logger');
-
-});
-
-// file: lib/windowsphone/plugin/media/symbols.js
-define("cordova/plugin/media/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/Media', 'Media');
-modulemapper.defaults('cordova/plugin/MediaError', 'MediaError');
-
-});
-
-// file: lib/common/plugin/network.js
-define("cordova/plugin/network", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    cordova = require('cordova'),
-    channel = require('cordova/channel'),
-    utils = require('cordova/utils');
-
-// Link the onLine property with the Cordova-supplied network info.
-// This works because we clobber the naviagtor object with our own
-// object in bootstrap.js.
-if (typeof navigator != 'undefined') {
-    utils.defineGetter(navigator, 'onLine', function() {
-        return this.connection.type != 'none';
-    });
-}
-
-function NetworkConnection() {
-    this.type = 'unknown';
-}
-
-/**
- * Get connection info
- *
- * @param {Function} successCallback The function to call when the Connection data is available
- * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
- */
-NetworkConnection.prototype.getInfo = function(successCallback, errorCallback) {
-    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
-};
-
-var me = new NetworkConnection();
-var timerId = null;
-var timeout = 500;
-
-channel.onCordovaReady.subscribe(function() {
-    me.getInfo(function(info) {
-        me.type = info;
-        if (info === "none") {
-            // set a timer if still offline at the end of timer send the offline event
-            timerId = setTimeout(function(){
-                cordova.fireDocumentEvent("offline");
-                timerId = null;
-            }, timeout);
-        } else {
-            // If there is a current offline event pending clear it
-            if (timerId !== null) {
-                clearTimeout(timerId);
-                timerId = null;
-            }
-            cordova.fireDocumentEvent("online");
-        }
-
-        // should only fire this once
-        if (channel.onCordovaConnectionReady.state !== 2) {
-            channel.onCordovaConnectionReady.fire();
-        }
-    },
-    function (e) {
-        // If we can't get the network info we should still tell Cordova
-        // to fire the deviceready event.
-        if (channel.onCordovaConnectionReady.state !== 2) {
-            channel.onCordovaConnectionReady.fire();
-        }
-        console.log("Error initializing Network Connection: " + e);
-    });
-});
-
-module.exports = me;
-
-});
-
-// file: lib/common/plugin/networkstatus/symbols.js
-define("cordova/plugin/networkstatus/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/network', 'navigator.network.connection', 'navigator.network.connection is deprecated. Use navigator.connection instead.');
-modulemapper.clobbers('cordova/plugin/network', 'navigator.connection');
-modulemapper.defaults('cordova/plugin/Connection', 'Connection');
-
-});
-
-// file: lib/common/plugin/notification.js
-define("cordova/plugin/notification", function(require, exports, module) {
-
-var exec = require('cordova/exec');
-var platform = require('cordova/platform');
-
-/**
- * Provides access to notifications on the device.
- */
-
-module.exports = {
-
-    /**
-     * Open a native alert dialog, with a customizable title and button text.
-     *
-     * @param {String} message              Message to print in the body of the alert
-     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
-     * @param {String} title                Title of the alert dialog (default: Alert)
-     * @param {String} buttonLabel          Label of the close button (default: OK)
-     */
-    alert: function(message, completeCallback, title, buttonLabel) {
-        var _title = (title || "Alert");
-        var _buttonLabel = (buttonLabel || "OK");
-        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
-    },
-
-    /**
-     * Open a native confirm dialog, with a customizable title and button text.
-     * The result that the user selects is returned to the result callback.
-     *
-     * @param {String} message              Message to print in the body of the alert
-     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
-     * @param {String} title                Title of the alert dialog (default: Confirm)
-     * @param {Array} buttonLabels          Array of the labels of the buttons (default: ['OK', 'Cancel'])
-     */
-    confirm: function(message, resultCallback, title, buttonLabels) {
-        var _title = (title || "Confirm");
-        var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);
-
-        // Strings are deprecated!
-        if (typeof _buttonLabels === 'string') {
-            console.log("Notification.confirm(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).");
-        }
-
-        // Some platforms take an array of button label names.
-        // Other platforms take a comma separated list.
-        // For compatibility, we convert to the desired type based on the platform.
-        if (platform.id == "android" || platform.id == "ios" || platform.id == "windowsphone" || platform.id == "blackberry10") {
-            if (typeof _buttonLabels === 'string') {
-                var buttonLabelString = _buttonLabels;
-                _buttonLabels = _buttonLabels.split(","); // not crazy about changing the var type here
-            }
-        } else {
-            if (Array.isArray(_buttonLabels)) {
-                var buttonLabelArray = _buttonLabels;
-                _buttonLabels = buttonLabelArray.toString();
-            }
-        }
-        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
-    },
-
-    /**
-     * Open a native prompt dialog, with a customizable title and button text.
-     * The following results are returned to the result callback:
-     *  buttonIndex     Index number of the button selected.
-     *  input1          The text entered in the prompt dialog box.
-     *
-     * @param {String} message              Dialog message to display (default: "Prompt message")
-     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
-     * @param {String} title                Title of the dialog (default: "Prompt")
-     * @param {Array} buttonLabels          Array of strings for the button labels (default: ["OK","Cancel"])
-     * @param {String} defaultText          Textbox input value (default: "Default text")
-     */
-    prompt: function(message, resultCallback, title, buttonLabels, defaultText) {
-        var _message = (message || "Prompt message");
-        var _title = (title || "Prompt");
-        var _buttonLabels = (buttonLabels || ["OK","Cancel"]);
-        var _defaultText = (defaultText || "Default text");
-        exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels, _defaultText]);
-    },
-
-    /**
-     * Causes the device to vibrate.
-     *
-     * @param {Integer} mills       The number of milliseconds to vibrate for.
-     */
-    vibrate: function(mills) {
-        exec(null, null, "Notification", "vibrate", [mills]);
-    },
-
-    /**
-     * Causes the device to beep.
-     * On Android, the default notification ringtone is played "count" times.
-     *
-     * @param {Integer} count       The number of beeps.
-     */
-    beep: function(count) {
-        exec(null, null, "Notification", "beep", [count]);
-    }
-};
-
-});
-
-// file: lib/common/plugin/notification/symbols.js
-define("cordova/plugin/notification/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.defaults('cordova/plugin/notification', 'navigator.notification');
-
-});
-
-// file: lib/common/plugin/requestFileSystem.js
-define("cordova/plugin/requestFileSystem", function(require, exports, module) {
-
-var argscheck = require('cordova/argscheck'),
-    FileError = require('cordova/plugin/FileError'),
-    FileSystem = require('cordova/plugin/FileSystem'),
-    exec = require('cordova/exec');
-
-/**
- * Request a file system in which to store application data.
- * @param type  local file system type
- * @param size  indicates how much storage space, in bytes, the application expects to need
- * @param successCallback  invoked with a FileSystem object
- * @param errorCallback  invoked if error occurs retrieving file system
- */
-var requestFileSystem = function(type, size, successCallback, errorCallback) {
-    argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);
-    var fail = function(code) {
-        errorCallback && errorCallback(new FileError(code));
-    };
-
-    if (type < 0 || type > 3) {
-        fail(FileError.SYNTAX_ERR);
-    } else {
-        // if successful, return a FileSystem object
-        var success = function(file_system) {
-            if (file_system) {
-                if (successCallback) {
-                    // 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 argscheck = require('cordova/argscheck'),
-    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) {
-    argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments);
-    // error callback
-    var fail = function(error) {
-        errorCallback && 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 (successCallback) {
-                // create appropriate Entry object
-                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
-                successCallback(result);
-            }
-        }
-        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/plugin/splashscreen/symbols.js
-define("cordova/plugin/splashscreen/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/splashscreen', 'navigator.splashscreen');
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/DOMStorage/plugininit.js
-define("cordova/plugin/windowsphone/DOMStorage/plugininit", function(require, exports, module) {
-
-(function(win,doc) {
-
-var docDomain = null;
-try {
-    docDomain = doc.domain;
-} catch (err) {
-    //console.log("caught exception trying to access document.domain");
-}
-
-// conditionally patch the window.localStorage and window.sessionStorage objects
-if (!docDomain || docDomain.length === 0) {
-
-    var DOMStorage = function(type) {
-        // default type is local
-        if(type == "sessionStorage") {
-            this._type = type;
-        }
-        Object.defineProperty( this, "length", {
-            configurable: true,
-            get: function(){ return this.getLength(); }
-        });
-    };
-
-    DOMStorage.prototype = {
-        _type:"localStorage",
-        _result:null,
-        keys:null,
-
-        onResult:function(key,valueStr) {
-            if(!this.keys) {
-                this.keys = [];
-            }
-            this._result = valueStr;
-        },
-
-        onKeysChanged:function(jsonKeys) {
-            this.keys = JSON.parse(jsonKeys);
-
-            var key;
-            for(var n = 0,len = this.keys.length; n < len; n++) {
-                key = this.keys[n];
-                if(!this.hasOwnProperty(key)) {
-                    Object.defineProperty( this, key, {
-                        configurable: true,
-                        get: function(){ return this.getItem(key); },
-                        set: function(val){ return this.setItem(key,val); }
-                    });
-                }
-            }
-
-        },
-
-        initialize:function() {
-            window.external.Notify("DOMStorage/" + this._type + "/load/keys");
-        },
-
-    /*
-        The length attribute must return the number of key/value pairs currently present
-        in the list associated with the object.
-    */
-        getLength:function() {
-            if(!this.keys) {
-                this.initialize();
-            }
-            return this.keys.length;
-        },
-
-    /*
-        The key(n) method must return the name of the nth key in the list.
-        The order of keys is user-agent defined, but must be consistent within an object so long as the number of keys doesn't change.
-        (Thus, adding or removing a key may change the order of the keys, but merely changing the value of an existing key must not.)
-        If n is greater than or equal to the number of key/value pairs in the object, then this method must return null.
-    */
-        key:function(n) {
-            if(!this.keys) {
-                this.initialize();
-            }
-
-            if(n >= this.keys.length) {
-                return null;
-            } else {
-                return this.keys[n];
-            }
-        },
-
-    /*
-        The getItem(key) method must return the current value associated with the given key.
-        If the given key does not exist in the list associated with the object then this method must return null.
-    */
-        getItem:function(key) {
-            if(!this.keys) {
-                this.initialize();
-            }
-
-            var retVal = null;
-            if(this.keys.indexOf(key) > -1) {
-                window.external.Notify("DOMStorage/" + this._type + "/get/" + key);
-                retVal = window.unescape(decodeURIComponent(this._result));
-                this._result = null;
-            }
-            return retVal;
-        },
-    /*
-        The setItem(key, value) method must first check if a key/value pair with the given key already exists
-        in the list associated with the object.
-        If it does not, then a new key/value pair must be added to the list, with the given key and with its value set to value.
-        If the given key does exist in the list, then it must have its value updated to value.
-        If it couldn't set the new value, the method must raise an QUOTA_EXCEEDED_ERR exception.
-        (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)
-    */
-        setItem:function(key,value) {
-            if(!this.keys) {
-                this.initialize();
-            }
-            window.external.Notify("DOMStorage/" + this._type + "/set/" + key + "/" + encodeURIComponent(window.escape(value)));
-        },
-
-    /*
-        The removeItem(key) method must cause the key/value pair with the given key to be removed from the list
-        associated with the object, if it exists.
-        If no item with that key exists, the method must do nothing.
-    */
-        removeItem:function(key) {
-            if(!this.keys) {
-                this.initialize();
-            }
-            var index = this.keys.indexOf(key);
-            if(index > -1) {
-                this.keys.splice(index,1);
-                // TODO: need sanity check for keys ? like 'clear','setItem', ...
-                window.external.Notify("DOMStorage/" + this._type + "/remove/" + key);
-                delete this[key];
-            }
-        },
-
-    /*
-        The clear() method must atomically cause the list associated with the object to be emptied of all
-        key/value pairs, if there are any.
-        If there are none, then the method must do nothing.
-    */
-        clear:function() {
-            if(!this.keys) {
-                this.initialize();
-            }
-
-            for(var n=0,len=this.keys.length; n < len;n++) {
-                // TODO: do we need a sanity check for keys ? like 'clear','setItem', ...
-                delete this[this.keys[n]];
-            }
-            this.keys = [];
-            window.external.Notify("DOMStorage/" + this._type + "/clear/");
-        }
-    };
-
-    // initialize DOMStorage
-
-    if (typeof window.localStorage === "undefined") {
-
-        Object.defineProperty(window, "localStorage", {
-            writable: false,
-            configurable: false,
-            value: new DOMStorage("localStorage")
-        });
-        window.localStorage.initialize();
-    }
-
-    if (typeof window.sessionStorage === "undefined") {
-        Object.defineProperty(window, "sessionStorage", {
-            writable: false,
-            configurable: false,
-            value: new DOMStorage("sessionStorage")
-        });
-        window.sessionStorage.initialize();
-    }
-}
-
-})(window, document);
-
-module.exports = null;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/FileTransfer.js
-define("cordova/plugin/windowsphone/FileTransfer", function(require, exports, module) {
-
-var exec = require('cordova/exec'),
-    FileTransferError = require('cordova/plugin/FileTransferError');
-
-// Note that the only difference between this and the default implementation is the
-// object literal passed to exec() in upload - jm
-
-/**
- * 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 are specified, and NOT a string already, we will stringify it.
-        if(options.params && typeof options.params != typeof "") {
-            var arrParams = [];
-            for(var v in options.params) {
-                arrParams.push(v + "=" + options.params[v]);
-            }
-            params = encodeURI(arrParams.join("&"));
-        }
-    }
-
-    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":filePath,
-                                                              "server":server,
-                                                              "fileKey":fileKey,
-                                                              "fileName":fileName,
-                                                              "mimeType":mimeType,
-                                                              "params":params,
-                                                              "trustAllHosts":trustAllHosts,
-                                                              "chunkedMode":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/windowsphone/plugin/windowsphone/FileUploadOptions.js
-define("cordova/plugin/windowsphone/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;
-
-    if(params && typeof params != typeof "") {
-        var arrParams = [];
-        for(var v in params) {
-            arrParams.push(v + "=" + params[v]);
-        }
-        this.params = encodeURIComponent(arrParams.join("&"));
-    }
-    else {
-        this.params = params || null;
-    }
-};
-
-module.exports = FileUploadOptions;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/XHRPatch/plugininit.js
-define("cordova/plugin/windowsphone/XHRPatch/plugininit", function(require, exports, module) {
-
-// TODO: the build process will implicitly wrap this in a define() call
-// with a closure of its own; do you need this extra closure?
-
-var LocalFileSystem = require('cordova/plugin/LocalFileSystem');
-
-(function (win, doc) {
-
-var docDomain = null;
-try {
-    docDomain = doc.domain;
-} catch (err) {
-    //console.log("caught exception trying to access document.domain");
-}
-
-if (!docDomain || docDomain.length === 0) {
-
-    var aliasXHR = win.XMLHttpRequest;
-
-    win.XMLHttpRequest = function () { };
-    win.XMLHttpRequest.noConflict = aliasXHR;
-    win.XMLHttpRequest.UNSENT = 0;
-    win.XMLHttpRequest.OPENED = 1;
-    win.XMLHttpRequest.HEADERS_RECEIVED = 2;
-    win.XMLHttpRequest.LOADING = 3;
-    win.XMLHttpRequest.DONE = 4;
-
-    win.XMLHttpRequest.prototype = {
-        UNSENT: 0,
-        OPENED: 1,
-        HEADERS_RECEIVED: 2,
-        LOADING: 3,
-        DONE: 4,
-
-        isAsync: false,
-        onreadystatechange: null,
-        readyState: 0,
-        _url: "",
-        timeout: 0,
-        withCredentials: false,
-        _requestHeaders: null,
-        open: function (reqType, uri, isAsync, user, password) {
-
-            if (uri && uri.indexOf("http") === 0) {
-                if (!this.wrappedXHR) {
-                    this.wrappedXHR = new aliasXHR();
-                    var self = this;
-
-                    // timeout
-                    if (this.timeout > 0) {
-                        this.wrappedXHR.timeout = this.timeout;
-                    }
-                    Object.defineProperty(this, "timeout", {
-                        set: function (val) {
-                            this.wrappedXHR.timeout = val;
-                        },
-                        get: function () {
-                            return this.wrappedXHR.timeout;
-                        }
-                    });
-
-
-
-                    if (this.withCredentials) {
-                        this.wrappedXHR.withCredentials = this.withCredentials;
-                    }
-                    Object.defineProperty(this, "withCredentials", {
-                        set: function (val) {
-                            this.wrappedXHR.withCredentials = val;
-                        },
-                        get: function () {
-                            return this.wrappedXHR.withCredentials;
-                        }
-                    });
-
-
-                    Object.defineProperty(this, "status", { get: function () {
-                        return this.wrappedXHR.status;
-                    }
-                    });
-                    Object.defineProperty(this, "responseText", { get: function () {
-                        return this.wrappedXHR.responseText;
-                    }
-                    });
-                    Object.defineProperty(this, "statusText", { get: function () {
-                        return this.wrappedXHR.statusText;
-                    }
-                    });
-
-                    Object.defineProperty(this, "responseXML", { get: function () {
-                        return this.wrappedXHR.responseXML;
-                    }
-                    });
-
-                    this.getResponseHeader = function (header) {
-                        return this.wrappedXHR.getResponseHeader(header);
-                    };
-                    this.getAllResponseHeaders = function () {
-                        return this.wrappedXHR.getAllResponseHeaders();
-                    };
-
-                    this.wrappedXHR.onreadystatechange = function () {
-                        self.changeReadyState(self.wrappedXHR.readyState);
-                    };
-                }
-                return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
-            }
-            else {
-                // x-wmapp1://app/www/page2.html
-                // need to work some magic on the actual url/filepath
-                var newUrl = uri;
-                if (newUrl.indexOf(":/") > -1) {
-                    newUrl = newUrl.split(":/")[1];
-                }
-                // prefix relative urls to our physical root
-                if(newUrl.indexOf("app/www/") < 0 && this.getContentLocation() == this.contentLocation.ISOLATED_STORAGE)
-                {
-                    newUrl = "app/www/" + newUrl;
-                }
-
-                if (newUrl.lastIndexOf("/") === newUrl.length - 1) {
-                    newUrl += "index.html"; // default page is index.html, when call is to a dir/ ( why not ...? )
-                }
-                this._url = newUrl;
-            }
-        },
-        statusText: "",
-        changeReadyState: function (newState) {
-            this.readyState = newState;
-            if (this.onreadystatechange) {
-                this.onreadystatechange();
-            }
-        },
-        setRequestHeader: function (header, value) {
-            if (this.wrappedXHR) {
-                this.wrappedXHR.setRequestHeader(header, value);
-            }
-        },
-        getResponseHeader: function (header) {
-            return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : "";
-        },
-        getAllResponseHeaders: function () {
-            return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : "";
-        },
-        responseText: "",
-        responseXML: "",
-        onResult: function (res) {
-            this.status = 200;
-            if(typeof res == "object")
-            {   // callback result handler may have already parsed this from a string-> a JSON object,
-                // if so, we need to restore its stringyness, as handlers are expecting string data.
-                // especially if used with jQ -> $.getJSON
-                res = JSON.stringify(res);
-            }
-            this.responseText = res;
-            this.responseXML = res;
-            this.changeReadyState(this.DONE);
-        },
-        onError: function (err) {
-            this.status = 404;
-            this.changeReadyState(this.DONE);
-        },
-
-        abort: function () {
-            if (this.wrappedXHR) {
-                return this.wrappedXHR.abort();
-            }
-        },
-
-        send: function (data) {
-            if (this.wrappedXHR) {
-                return this.wrappedXHR.send(data);
-            }
-            else {
-                this.changeReadyState(this.OPENED);
-
-                var alias = this;
-
-                var fail = function fail(evt) {
-                    alias.onError(evt.code);
-                };
-
-                if (alias.getContentLocation() == this.contentLocation.RESOURCES) {
-                    var exec = require('cordova/exec');
-                    exec(function(result) {
-                            alias.onResult.apply(alias, [result]);
-                        },
-                        fail,
-                        "File", "readResourceAsText", [alias._url]
-                    );
-                }
-                else {
-                    var gotFile = function gotFile(file) {
-                        var reader = new FileReader();
-                        reader.onloadend = function (evt) {
-                            alias.onResult.apply(alias,[evt.target.result]);
-                        };
-                        reader.readAsText(file);
-                    };
-
-                    var gotEntry = function gotEntry(entry) {
-                        entry.file(gotFile, fail);
-                    };
-
-                    var gotFS = function gotFS(fs) {
-                        fs.root.getFile(alias._url, null, gotEntry, fail);
-                    };
-
-                    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
-                }
-            }
-        },
-
-        getContentLocation: function () {
-            if (window.contentLocation === undefined) {
-                window.contentLocation = (navigator.userAgent.toUpperCase().indexOf('MSIE 10') > -1) ?
-                    this.contentLocation.RESOURCES : this.contentLocation.ISOLATED_STORAGE;
-            }
-
-            return window.contentLocation;
-        },
-
-        contentLocation:{
-            ISOLATED_STORAGE: 0,
-            RESOURCES: 1
-        },
-
-        status: 404
-    };
-} // if doc domain
-
-// end closure wrap
-})(window, document);
-
-module.exports = null;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/console.js
-define("cordova/plugin/windowsphone/console", function(require, exports, module) {
-
-
-var exec = require('cordova/exec'),
-    channel = require('cordova/channel');
-var cordova = require("cordova");
-
-var debugConsole = {
-    log:function(msg){
-        exec(null,null,"DebugConsole","log",msg);
-    },
-    warn:function(msg){
-        exec(null,null,"DebugConsole","warn",msg);
-    },
-    error:function(msg){
-        exec(null,null,"DebugConsole","error",msg);
-    }
-};
-
-var oldOnError = window.onerror;
-window.onerror = function(msg,fileName,line) {
-    oldOnError && oldOnError(msg,fileName,line);
-    debugConsole.error(msg + " file:" + fileName + " Line:" + line);
-};
-
-module.exports = debugConsole;
-
-});
-
-// file: lib/windowsphone/plugin/windowsphone/console/symbols.js
-define("cordova/plugin/windowsphone/console/symbols", function(require, exports, module) {
-
-
-var modulemapper = require('cordova/modulemapper');
-
-modulemapper.clobbers('cordova/plugin/windowsphone/console', 'navigator.console');
-modulemapper.clobbers('cordova/plugin/windowsphone/console', 'console');
-
-});
-
-// file: lib/common/symbols.js
-define("cordova/symbols", function(require, exports, module) {
-
-var modulemapper = require('cordova/modulemapper');
-
-// Use merges here in case others symbols files depend on this running first,
-// but fail to declare the dependency with a require().
-modulemapper.merges('cordova', 'cordova');
-modulemapper.clobbers('cordova/exec', 'cordova.exec');
-modulemapper.clobbers('cordova/exec', 'Cordova.exec');
-
-});
-
-// file: lib/common/utils.js
-define("cordova/utils", function(require, exports, module) {
-
-var utils = exports;
-
-/**
- * Defines a property getter / setter for obj[key].
- */
-utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
-    if (Object.defineProperty) {
-        var desc = {
-            get: getFunc,
-            configurable: true
-        };
-        if (opt_setFunc) {
-            desc.set = opt_setFunc;
-        }
-        Object.defineProperty(obj, key, desc);
-    } else {
-        obj.__defineGetter__(key, getFunc);
-        if (opt_setFunc) {
-            obj.__defineSetter__(key, opt_setFunc);
-        }
-    }
-};
-
-/**
- * Defines a property getter for obj[key].
- */
-utils.defineGetter = utils.defineGetterSetter;
-
-utils.arrayIndexOf = function(a, item) {
-    if (a.indexOf) {
-        return a.indexOf(item);
-    }
-    var len = a.length;
-    for (var i = 0; i < len; ++i) {
-        if (a[i] == item) {
-            return i;
-        }
-    }
-    return -1;
-};
-
-/**
- * Returns whether the item was found in the array.
- */
-utils.arrayRemove = function(a, item) {
-    var index = utils.arrayIndexOf(a, item);
-    if (index != -1) {
-        a.splice(index, 1);
-    }
-    return index != -1;
-};
-
-utils.typeName = function(val) {
-    return Object.prototype.toString.call(val).slice(8, -1);
-};
-
-/**
- * Returns an indication of whether the argument is an array or not
- */
-utils.isArray = function(a) {
-    return utils.typeName(a) == 'Array';
-};
-
-/**
- * Returns an indication of whether the argument is a Date or not
- */
-utils.isDate = function(d) {
-    return utils.typeName(d) == 'Date';
-};
-
-/**
- * Does a deep clone of the object.
- */
-utils.clone = function(obj) {
-    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
-        return obj;
-    }
-
-    var retVal, i;
-
-    if(utils.isArray(obj)){
-        retVal = [];
-        for(i = 0; i < obj.length; ++i){
-            retVal.push(utils.clone(obj[i]));
-        }
-        return retVal;
-    }
-
-    retVal = {};
-    for(i in obj){
-        if(!(i in retVal) || retVal[i] != obj[i]) {
-            retVal[i] = utils.clone(obj[i]);
-        }
-    }
-    return retVal;
-};
-
-/**
- * Returns a wrapped version of the function
- */
-utils.close = function(context, func, params) {
-    if (typeof params == 'undefined') {
-        return function() {
-            return func.apply(context, arguments);
-        };
-    } else {
-        return function() {
-            return func.apply(context, params);
-        };
-    }
-};
-
-/**
- * Create a UUID
- */
-utils.createUUID = function() {
-    return UUIDcreatePart(4) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(2) + '-' +
-        UUIDcreatePart(6);
-};
-
-/**
- * Extends a child object from a parent object using classical inheritance
- * pattern.
- */
-utils.extend = (function() {
-    // proxy used to establish prototype chain
-    var F = function() {};
-    // extend Child from Parent
-    return function(Child, Parent) {
-        F.prototype = Parent.prototype;
-        Child.prototype = new F();
-        Child.__super__ = Parent.prototype;
-        Child.prototype.constructor = Child;
-    };
-}());
-
-/**
- * Alerts a message in any available way: alert or console.log.
- */
-utils.alert = function(msg) {
-    if (window.alert) {
-        window.alert(msg);
-    } else if (console && console.log) {
-        console.log(msg);
-    }
-};
-
-
-//------------------------------------------------------------------------------
-function UUIDcreatePart(length) {
-    var uuidpart = "";
-    for (var i=0; i<length; i++) {
-        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
-        if (uuidchar.length == 1) {
-            uuidchar = "0" + uuidchar;
-        }
-        uuidpart += uuidchar;
-    }
-    return uuidpart;
-}
-
-
-});
-
-window.cordova = require('cordova');
-// file: lib/scripts/bootstrap.js
-
-(function (context) {
-    if (context._cordovaJsLoaded) {
-        throw new Error('cordova.js included multiple times.');
-    }
-    context._cordovaJsLoaded = true;
-
-    var channel = require('cordova/channel');
-    var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
-
-    function logUnfiredChannels(arr) {
-        for (var i = 0; i < arr.length; ++i) {
-            if (arr[i].state != 2) {
-                console.log('Channel not fired: ' + arr[i].type);
-            }
-        }
-    }
-
-    window.setTimeout(function() {
-        if (channel.onDeviceReady.state != 2) {
-            console.log('deviceready has not fired after 5 seconds.');
-            logUnfiredChannels(platformInitChannelsArray);
-            logUnfiredChannels(channel.deviceReadyChannelsArray);
-        }
-    }, 5000);
-
-    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
-    // We replace it so that properties that can't be clobbered can instead be overridden.
-    function replaceNavigator(origNavigator) {
-        var CordovaNavigator = function() {};
-        CordovaNavigator.prototype = origNavigator;
-        var newNavigator = new CordovaNavigator();
-        // This work-around really only applies to new APIs that are newer than Function.bind.
-        // Without it, APIs such as getGamepads() break.
-        if (CordovaNavigator.bind) {
-            for (var key in origNavigator) {
-                if (typeof origNavigator[key] == 'function') {
-                    newNavigator[key] = origNavigator[key].bind(origNavigator);
-                }
-            }
-        }
-        return newNavigator;
-    }
-    if (context.navigator) {
-        context.navigator = replaceNavigator(context.navigator);
-    }
-
-    // _nativeReady is global variable that the native side can set
-    // to signify that the native code is ready. It is a global since
-    // it may be called before any cordova JS is ready.
-    if (window._nativeReady) {
-        channel.onNativeReady.fire();
-    }
-
-    /**
-     * Create all cordova objects once native side is ready.
-     */
-    channel.join(function() {
-        // Call the platform-specific initialization
-        require('cordova/platform').initialize();
-
-        // Fire event to notify that all objects are created
-        channel.onCordovaReady.fire();
-
-        // Fire onDeviceReady event once page has fully loaded, all
-        // constructors have run and cordova info has been received from native
-        // side.
-        // This join call is deliberately made after platform.initialize() in
-        // order that plugins may manipulate channel.deviceReadyChannelsArray
-        // if necessary.
-        channel.join(function() {
-            require('cordova').fireDocumentEvent('deviceready');
-        }, channel.deviceReadyChannelsArray);
-
-    }, platformInitChannelsArray);
-
-}(window));
-
-// file: lib/scripts/plugin_loader.js
-
-// Tries to load all plugins' js-modules.
-// This is an async process, but onDeviceReady is blocked on onPluginsReady.
-// onPluginsReady is fired when there are no plugins to load, or they are all done.
-(function (context) {
-    // To be populated with the handler by handlePluginsObject.
-    var onScriptLoadingComplete;
-
-    var scriptCounter = 0;
-    function scriptLoadedCallback() {
-        scriptCounter--;
-        if (scriptCounter === 0) {
-            onScriptLoadingComplete && onScriptLoadingComplete();
-        }
-    }
-
-    function scriptErrorCallback(err) {
-        // Open Question: If a script path specified in cordova_plugins.js does not exist, do we fail for all?
-        // this is currently just continuing.
-        scriptCounter--;
-        if (scriptCounter === 0) {
-            onScriptLoadingComplete && onScriptLoadingComplete();
-        }
-    }
-
-    // Helper function to inject a <script> tag.
-    function injectScript(path) {
-        scriptCounter++;
-        var script = document.createElement("script");
-        script.onload = scriptLoadedCallback;
-        script.onerror = scriptErrorCallback;
-        script.src = path;
-        document.head.appendChild(script);
-    }
-
-    // Called when:
-    // * There are plugins defined and all plugins are finished loading.
-    // * There are no plugins to load.
-    function finishPluginLoading() {
-        context.cordova.require('cordova/channel').onPluginsReady.fire();
-    }
-
-    // Handler for the cordova_plugins.js content.
-    // See plugman's plugin_loader.js for the details of this object.
-    // This function is only called if the really is a plugins array that isn't empty.
-    // Otherwise the onerror response handler will just call finishPluginLoading().
-    function handlePluginsObject(modules, path) {
-        // First create the callback for when all plugins are loaded.
-        var mapper = context.cordova.require('cordova/modulemapper');
-        onScriptLoadingComplete = function() {
-            // Loop through all the plugins and then through their clobbers and merges.
-            for (var i = 0; i < modules.length; i++) {
-                var module = modules[i];
-                if (module) {
-                    try { 
-                        if (module.clobbers && module.clobbers.length) {
-                            for (var j = 0; j < module.clobbers.length; j++) {
-                                mapper.clobbers(module.id, module.clobbers[j]);
-                            }
-                        }
-
-                        if (module.merges && module.merges.length) {
-                            for (var k = 0; k < module.merges.length; k++) {
-                                mapper.merges(module.id, module.merges[k]);
-                            }
-                        }
-
-                        // Finally, if runs is truthy we want to simply require() the module.
-                        // This can be skipped if it had any merges or clobbers, though,
-                        // since the mapper will already have required the module.
-                        if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
-                            context.cordova.require(module.id);
-                        }
-                    }
-                    catch(err) {
-                        // error with module, most likely clobbers, should we continue?
-                    }
-                }
-            }
-
-            finishPluginLoading();
-        };
-
-        // Now inject the scripts.
-        for (var i = 0; i < modules.length; i++) {
-            injectScript(path + modules[i].file);
-        }
-    }
-
-    // Find the root of the app
-    var path = '';
-    var scripts = document.getElementsByTagName('script');
-    var term = 'cordova.js';
-    for (var n = scripts.length-1; n>-1; n--) {
-        var src = scripts[n].src;
-        if (src.indexOf(term) == (src.length - term.length)) {
-            path = src.substring(0, src.length - term.length);
-            break;
-        }
-    }
-
-    var plugins_json = path + 'cordova_plugins.json';
-    var plugins_js = path + 'cordova_plugins.js';
-
-    // One some phones (Windows) this xhr.open throws an Access Denied exception
-    // So lets keep trying, but with a script tag injection technique instead of XHR
-    var injectPluginScript = function injectPluginScript() {
-        try {
-            var script = document.createElement("script");
-            script.onload = function(){
-                var list = cordova.require("cordova/plugin_list");
-                handlePluginsObject(list,path);
-            };
-            script.onerror = function() {
-                // Error loading cordova_plugins.js, file not found or something
-                // this is an acceptable error, pre-3.0.0, so we just move on.
-                finishPluginLoading();
-            };
-            script.src = plugins_js;
-            document.head.appendChild(script);
-
-        } catch(err){
-            finishPluginLoading();
-        }
-    } 
-
-
-    // Try to XHR the cordova_plugins.json file asynchronously.
-    var xhr = new XMLHttpRequest();
-    xhr.onload = function() {
-        // If the response is a JSON string which composes an array, call handlePluginsObject.
-        // If the request fails, or the response is not a JSON array, just call finishPluginLoading.
-        var obj;
-        try {
-            obj = (this.status == 0 || this.status == 200) && this.responseText && JSON.parse(this.responseText);
-        } catch (err) {
-            // obj will be undefined.
-        }
-        if (Array.isArray(obj) && obj.length > 0) {
-            handlePluginsObject(obj, path);
-        } else {
-            finishPluginLoading();
-        }
-    };
-    xhr.onerror = function() {
-        // In this case, the json file was not present, but XHR was allowed, 
-        // so we should still try the script injection technique with the js file
-        // in case that is there.
-        injectPluginScript();
-    };
-    try { // we commented we were going to try, so let us actually try and catch
-        xhr.open('GET', plugins_json, true); // Async
-        xhr.send();
-    } catch(err){
-        injectPluginScript();
-    }
-}(window));
-
-
+// Platform: windowsphone

+// 2.9.1

+/*

+ 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() {

+var CORDOVA_JS_BUILD_LABEL = '2.9.1';

+// file: lib/scripts/require.js

+

+var require,

+    define;

+

+(function () {

+    var modules = {},

+    // Stack of moduleIds currently being built.

+        requireStack = [],

+    // Map of module ID -> index into requireStack of modules currently being built.

+        inProgressModules = {},

+        SEPERATOR = ".";

+

+

+

+    function build(module) {

+        var factory = module.factory,

+            localRequire = function (id) {

+                var resultantId = id;

+                //Its a relative path, so lop off the last portion and add the id (minus "./")

+                if (id.charAt(0) === ".") {

+                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);

+                }

+                return require(resultantId);

+            };

+        module.exports = {};

+        delete module.factory;

+        factory(localRequire, module.exports, module);

+        return module.exports;

+    }

+

+    require = function (id) {

+        if (!modules[id]) {

+            throw "module " + id + " not found";

+        } else if (id in inProgressModules) {

+            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;

+            throw "Cycle in require graph: " + cycle;

+        }

+        if (modules[id].factory) {

+            try {

+                inProgressModules[id] = requireStack.length;

+                requireStack.push(id);

+                return build(modules[id]);

+            } finally {

+                delete inProgressModules[id];

+                requireStack.pop();

+            }

+        }

+        return modules[id].exports;

+    };

+

+    define = function (id, factory) {

+        if (modules[id]) {

+            throw "module " + id + " already defined";

+        }

+

+        modules[id] = {

+            id: id,

+            factory: factory

+        };

+    };

+

+    define.remove = function (id) {

+        delete modules[id];

+    };

+

+    define.moduleMap = modules;

+})();

+

+//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');

+var platform = require('cordova/platform');

+

+/**

+ * Listen for DOMContentLoaded and notify our channel subscribers.

+ */

+document.addEventListener('DOMContentLoaded', function() {

+    channel.onDOMContentLoaded.fire();

+}, false);

+if (document.readyState == 'complete' || document.readyState == 'interactive') {

+    channel.onDOMContentLoaded.fire();

+}

+

+/**

+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,

+ * resume, and pause events.

+ */

+var m_document_addEventListener = document.addEventListener;

+var m_document_removeEventListener = document.removeEventListener;

+var m_window_addEventListener = window.addEventListener;

+var m_window_removeEventListener = window.removeEventListener;

+

+/**

+ * Houses custom event handlers to intercept on document + window event listeners.

+ */

+var documentEventHandlers = {},

+    windowEventHandlers = {};

+

+document.addEventListener = function(evt, handler, capture) {

+    var e = evt.toLowerCase();

+    if (typeof documentEventHandlers[e] != 'undefined') {

+        documentEventHandlers[e].subscribe(handler);

+    } else {

+        m_document_addEventListener.call(document, evt, handler, capture);

+    }

+};

+

+window.addEventListener = function(evt, handler, capture) {

+    var e = evt.toLowerCase();

+    if (typeof windowEventHandlers[e] != 'undefined') {

+        windowEventHandlers[e].subscribe(handler);

+    } else {

+        m_window_addEventListener.call(window, evt, handler, capture);

+    }

+};

+

+document.removeEventListener = function(evt, handler, capture) {

+    var e = evt.toLowerCase();

+    // If unsubscribing from an event that is handled by a plugin

+    if (typeof documentEventHandlers[e] != "undefined") {

+        documentEventHandlers[e].unsubscribe(handler);

+    } else {

+        m_document_removeEventListener.call(document, evt, handler, capture);

+    }

+};

+

+window.removeEventListener = function(evt, handler, capture) {

+    var e = evt.toLowerCase();

+    // If unsubscribing from an event that is handled by a plugin

+    if (typeof windowEventHandlers[e] != "undefined") {

+        windowEventHandlers[e].unsubscribe(handler);

+    } else {

+        m_window_removeEventListener.call(window, evt, handler, capture);

+    }

+};

+

+function createEvent(type, data) {

+    var event = document.createEvent('Events');

+    event.initEvent(type, false, false);

+    if (data) {

+        for (var i in data) {

+            if (data.hasOwnProperty(i)) {

+                event[i] = data[i];

+            }

+        }

+    }

+    return event;

+}

+

+if(typeof window.console === "undefined") {

+    window.console = {

+        log:function(){}

+    };

+}

+// there are places in the framework where we call `warn` also, so we should make sure it exists

+if(typeof window.console.warn === "undefined") {

+    window.console.warn = function(msg) {

+        this.log("warn: " + msg);

+    };

+}

+

+var cordova = {

+    define:define,

+    require:require,

+    version:CORDOVA_JS_BUILD_LABEL,

+    platformId:platform.id,

+    /**

+     * Methods to add/remove your own addEventListener hijacking on document + window.

+     */

+    addWindowEventHandler:function(event) {

+        return (windowEventHandlers[event] = channel.create(event));

+    },

+    addStickyDocumentEventHandler:function(event) {

+        return (documentEventHandlers[event] = channel.createSticky(event));

+    },

+    addDocumentEventHandler:function(event) {

+        return (documentEventHandlers[event] = channel.create(event));

+    },

+    removeWindowEventHandler:function(event) {

+        delete windowEventHandlers[event];

+    },

+    removeDocumentEventHandler:function(event) {

+        delete documentEventHandlers[event];

+    },

+    /**

+     * Retrieve original event handlers that were replaced by Cordova

+     *

+     * @return object

+     */

+    getOriginalHandlers: function() {

+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},

+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};

+    },

+    /**

+     * Method to fire event from native code

+     * bNoDetach is required for events which cause an exception which needs to be caught in native code

+     */

+    fireDocumentEvent: function(type, data, bNoDetach) {

+        var evt = createEvent(type, data);

+        if (typeof documentEventHandlers[type] != 'undefined') {

+            if( bNoDetach ) {

+                documentEventHandlers[type].fire(evt);

+            }

+            else {

+                setTimeout(function() {

+                    // Fire deviceready on listeners that were registered before cordova.js was loaded.

+                    if (type == 'deviceready') {

+                        document.dispatchEvent(evt);

+                    }

+                    documentEventHandlers[type].fire(evt);

+                }, 0);

+            }

+        } else {

+            document.dispatchEvent(evt);

+        }

+    },

+    fireWindowEvent: function(type, data) {

+        var evt = createEvent(type,data);

+        if (typeof windowEventHandlers[type] != 'undefined') {

+            setTimeout(function() {

+                windowEventHandlers[type].fire(evt);

+            }, 0);

+        } else {

+            window.dispatchEvent(evt);

+        }

+    },

+

+    /**

+     * Plugin callback mechanism.

+     */

+    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.

+    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.

+    callbackId: Math.floor(Math.random() * 2000000000),

+    callbacks:  {},

+    callbackStatus: {

+        NO_RESULT: 0,

+        OK: 1,

+        CLASS_NOT_FOUND_EXCEPTION: 2,

+        ILLEGAL_ACCESS_EXCEPTION: 3,

+        INSTANTIATION_EXCEPTION: 4,

+        MALFORMED_URL_EXCEPTION: 5,

+        IO_EXCEPTION: 6,

+        INVALID_ACTION: 7,

+        JSON_EXCEPTION: 8,

+        ERROR: 9

+    },

+

+    /**

+     * Called by native code when returning successful result from an action.

+     */

+    callbackSuccess: function(callbackId, args) {

+        try {

+            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);

+        } catch (e) {

+            console.log("Error in error callback: " + callbackId + " = "+e);

+        }

+    },

+

+    /**

+     * Called by native code when returning error result from an action.

+     */

+    callbackError: function(callbackId, args) {

+        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.

+        // Derive success from status.

+        try {

+            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);

+        } catch (e) {

+            console.log("Error in error callback: " + callbackId + " = "+e);

+        }

+    },

+

+    /**

+     * Called by native code when returning the result from an action.

+     */

+    callbackFromNative: function(callbackId, success, status, args, keepCallback) {

+        var callback = cordova.callbacks[callbackId];

+        if (callback) {

+            if (success && status == cordova.callbackStatus.OK) {

+                callback.success && callback.success.apply(null, args);

+            } else if (!success) {

+                callback.fail && callback.fail.apply(null, args);

+            }

+

+            // Clear callback if not expecting any more results

+            if (!keepCallback) {

+                delete cordova.callbacks[callbackId];

+            }

+        }

+    },

+    addConstructor: function(func) {

+        channel.onCordovaReady.subscribe(function() {

+            try {

+                func();

+            } catch(e) {

+                console.log("Failed to run constructor: " + e);

+            }

+        });

+    }

+};

+

+// Register pause, resume and deviceready channels as events on document.

+channel.onPause = cordova.addDocumentEventHandler('pause');

+channel.onResume = cordova.addDocumentEventHandler('resume');

+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');

+

+module.exports = cordova;

+

+});

+

+// file: lib/common/argscheck.js

+define("cordova/argscheck", function(require, exports, module) {

+

+var exec = require('cordova/exec');

+var utils = require('cordova/utils');

+

+var moduleExports = module.exports;

+

+var typeMap = {

+    'A': 'Array',

+    'D': 'Date',

+    'N': 'Number',

+    'S': 'String',

+    'F': 'Function',

+    'O': 'Object'

+};

+

+function extractParamName(callee, argIndex) {

+    return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];

+}

+

+function checkArgs(spec, functionName, args, opt_callee) {

+    if (!moduleExports.enableChecks) {

+        return;

+    }

+    var errMsg = null;

+    var typeName;

+    for (var i = 0; i < spec.length; ++i) {

+        var c = spec.charAt(i),

+            cUpper = c.toUpperCase(),

+            arg = args[i];

+        // Asterix means allow anything.

+        if (c == '*') {

+            continue;

+        }

+        typeName = utils.typeName(arg);

+        if ((arg === null || arg === undefined) && c == cUpper) {

+            continue;

+        }

+        if (typeName != typeMap[cUpper]) {

+            errMsg = 'Expected ' + typeMap[cUpper];

+            break;

+        }

+    }

+    if (errMsg) {

+        errMsg += ', but got ' + typeName + '.';

+        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;

+        // Don't log when running unit tests.

+        if (typeof jasmine == 'undefined') {

+            console.error(errMsg);

+        }

+        throw TypeError(errMsg);

+    }

+}

+

+function getValue(value, defaultValue) {

+    return value === undefined ? defaultValue : value;

+}

+

+moduleExports.checkArgs = checkArgs;

+moduleExports.getValue = getValue;

+moduleExports.enableChecks = true;

+

+

+});

+

+// file: lib/common/base64.js

+define("cordova/base64", function(require, exports, module) {

+

+var base64 = exports;

+

+base64.fromArrayBuffer = function(arrayBuffer) {

+    var array = new Uint8Array(arrayBuffer);

+    return uint8ToBase64(array);

+};

+

+//------------------------------------------------------------------------------

+

+/* This code is based on the performance tests at http://jsperf.com/b64tests

+ * This 12-bit-at-a-time algorithm was the best performing version on all

+ * platforms tested.

+ */

+

+var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

+var b64_12bit;

+

+var b64_12bitTable = function() {

+    b64_12bit = [];

+    for (var i=0; i<64; i++) {

+        for (var j=0; j<64; j++) {

+            b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];

+        }

+    }

+    b64_12bitTable = function() { return b64_12bit; };

+    return b64_12bit;

+};

+

+function uint8ToBase64(rawData) {

+    var numBytes = rawData.byteLength;

+    var output="";

+    var segment;

+    var table = b64_12bitTable();

+    for (var i=0;i<numBytes-2;i+=3) {

+        segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];

+        output += table[segment >> 12];

+        output += table[segment & 0xfff];

+    }

+    if (numBytes - i == 2) {

+        segment = (rawData[i] << 16) + (rawData[i+1] << 8);

+        output += table[segment >> 12];

+        output += b64_6bit[(segment & 0xfff) >> 6];

+        output += '=';

+    } else if (numBytes - i == 1) {

+        segment = (rawData[i] << 16);

+        output += table[segment >> 12];

+        output += '==';

+    }

+    return output;

+}

+

+});

+

+// 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 clobber(obj, key, value) {

+    exports.replaceHookForTesting(obj, key);

+    obj[key] = value;

+    // Getters can only be overridden by getters.

+    if (obj[key] !== value) {

+        utils.defineGetter(obj, key, function() {

+            return value;

+        });

+    }

+}

+

+function assignOrWrapInDeprecateGetter(obj, key, value, message) {

+    if (message) {

+        utils.defineGetter(obj, key, function() {

+            console.log(message);

+            delete obj[key];

+            clobber(obj, key, value);

+            return value;

+        });

+    } else {

+        clobber(obj, key, value);

+    }

+}

+

+function include(parent, objects, clobber, merge) {

+    each(objects, function (obj, key) {

+        try {

+            var result = obj.path ? require(obj.path) : {};

+

+            if (clobber) {

+                // Clobber if it doesn't exist.

+                if (typeof parent[key] === 'undefined') {

+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);

+                } else if (typeof obj.path !== 'undefined') {

+                    // If merging, merge properties onto parent, otherwise, clobber.

+                    if (merge) {

+                        recursiveMerge(parent[key], result);

+                    } else {

+                        assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);

+                    }

+                }

+                result = parent[key];

+            } else {

+                // Overwrite if not currently defined.

+                if (typeof parent[key] == 'undefined') {

+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);

+                } else {

+                    // 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 (target.prototype && target.prototype.constructor === target) {

+                // If the target object is a constructor override off prototype.

+                clobber(target.prototype, prop, src[prop]);

+            } else {

+                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {

+                    recursiveMerge(target[prop], src[prop]);

+                } else {

+                    clobber(target, prop, src[prop]);

+                }

+            }

+        }

+    }

+}

+

+exports.buildIntoButDoNotClobber = function(objects, target) {

+    include(target, objects, false, false);

+};

+exports.buildIntoAndClobber = function(objects, target) {

+    include(target, objects, true, false);

+};

+exports.buildIntoAndMerge = function(objects, target) {

+    include(target, objects, true, true);

+};

+exports.recursiveMerge = recursiveMerge;

+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;

+exports.replaceHookForTesting = function() {};

+

+});

+

+// file: lib/common/channel.js

+define("cordova/channel", function(require, exports, module) {

+

+var utils = require('cordova/utils'),

+    nextGuid = 1;

+

+/**

+ * Custom pub-sub "channel" that can have functions subscribed to it

+ * This object is used to define and control firing of events for

+ * cordova initialization, as well as for custom events thereafter.

+ *

+ * The order of events during page load and Cordova startup is as follows:

+ *

+ * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.

+ * onNativeReady*              Internal event that indicates the Cordova native side is ready.

+ * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.

+ * onCordovaInfoReady*         Internal event fired when device properties are available.

+ * onCordovaConnectionReady*   Internal event fired when the connection property has been set.

+ * onDeviceReady*              User event fired to indicate that Cordova is ready

+ * onResume                    User event fired to indicate a start/resume lifecycle event

+ * onPause                     User event fired to indicate a pause lifecycle event

+ * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).

+ *

+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.

+ * All listeners that subscribe after the event is fired will be executed right away.

+ *

+ * The only Cordova events that user code should register for are:

+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript

+ *      pause                 App has moved to background

+ *      resume                App has returned to foreground

+ *

+ * Listeners can be registered as:

+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);

+ *      document.addEventListener("resume", myResumeListener, false);

+ *      document.addEventListener("pause", myPauseListener, false);

+ *

+ * The DOM lifecycle events should be used for saving and restoring state

+ *      window.onload

+ *      window.onunload

+ *

+ */

+

+/**

+ * Channel

+ * @constructor

+ * @param type  String the channel name

+ */

+var Channel = function(type, sticky) {

+    this.type = type;

+    // Map of guid -> function.

+    this.handlers = {};

+    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.

+    this.state = sticky ? 1 : 0;

+    // Used in sticky mode to remember args passed to fire().

+    this.fireArgs = null;

+    // Used by onHasSubscribersChange to know if there are any listeners.

+    this.numHandlers = 0;

+    // Function that is called when the first listener is subscribed, or when

+    // the last listener is unsubscribed.

+    this.onHasSubscribersChange = null;

+},

+    channel = {

+        /**

+         * Calls the provided function only after all of the channels specified

+         * have been fired. All channels must be sticky channels.

+         */

+        join: function(h, c) {

+            var len = c.length,

+                i = len,

+                f = function() {

+                    if (!(--i)) h();

+                };

+            for (var j=0; j<len; j++) {

+                if (c[j].state === 0) {

+                    throw Error('Can only use join with sticky channels.');

+                }

+                c[j].subscribe(f);

+            }

+            if (!len) h();

+        },

+        create: function(type) {

+            return channel[type] = new Channel(type, false);

+        },

+        createSticky: function(type) {

+            return channel[type] = new Channel(type, true);

+        },

+

+        /**

+         * cordova Channels that must fire before "deviceready" is fired.

+         */

+        deviceReadyChannelsArray: [],

+        deviceReadyChannelsMap: {},

+

+        /**

+         * Indicate that a feature needs to be initialized before it is ready to be used.

+         * This holds up Cordova's "deviceready" event until the feature has been initialized

+         * and Cordova.initComplete(feature) is called.

+         *

+         * @param feature {String}     The unique feature name

+         */

+        waitForInitialization: function(feature) {

+            if (feature) {

+                var c = channel[feature] || this.createSticky(feature);

+                this.deviceReadyChannelsMap[feature] = c;

+                this.deviceReadyChannelsArray.push(c);

+            }

+        },

+

+        /**

+         * Indicate that initialization code has completed and the feature is ready to be used.

+         *

+         * @param feature {String}     The unique feature name

+         */

+        initializationComplete: function(feature) {

+            var c = this.deviceReadyChannelsMap[feature];

+            if (c) {

+                c.fire();

+            }

+        }

+    };

+

+function forceFunction(f) {

+    if (typeof f != 'function') throw "Function required as first argument!";

+}

+

+/**

+ * Subscribes the given function to the channel. Any time that

+ * Channel.fire is called so too will the function.

+ * Optionally specify an execution context for the function

+ * and a guid that can be used to stop subscribing to the channel.

+ * Returns the guid.

+ */

+Channel.prototype.subscribe = function(f, c) {

+    // need a function to call

+    forceFunction(f);

+    if (this.state == 2) {

+        f.apply(c || this, this.fireArgs);

+        return;

+    }

+

+    var func = f,

+        guid = f.observer_guid;

+    if (typeof c == "object") { func = utils.close(c, f); }

+

+    if (!guid) {

+        // first time any channel has seen this subscriber

+        guid = '' + nextGuid++;

+    }

+    func.observer_guid = guid;

+    f.observer_guid = guid;

+

+    // Don't add the same handler more than once.

+    if (!this.handlers[guid]) {

+        this.handlers[guid] = func;

+        this.numHandlers++;

+        if (this.numHandlers == 1) {

+            this.onHasSubscribersChange && this.onHasSubscribersChange();

+        }

+    }

+};

+

+/**

+ * Unsubscribes the function with the given guid from the channel.

+ */

+Channel.prototype.unsubscribe = function(f) {

+    // need a function to unsubscribe

+    forceFunction(f);

+

+    var guid = f.observer_guid,

+        handler = this.handlers[guid];

+    if (handler) {

+        delete this.handlers[guid];

+        this.numHandlers--;

+        if (this.numHandlers === 0) {

+            this.onHasSubscribersChange && this.onHasSubscribersChange();

+        }

+    }

+};

+

+/**

+ * Calls all functions subscribed to this channel.

+ */

+Channel.prototype.fire = function(e) {

+    var fail = false,

+        fireArgs = Array.prototype.slice.call(arguments);

+    // Apply stickiness.

+    if (this.state == 1) {

+        this.state = 2;

+        this.fireArgs = fireArgs;

+    }

+    if (this.numHandlers) {

+        // Copy the values first so that it is safe to modify it from within

+        // callbacks.

+        var toCall = [];

+        for (var item in this.handlers) {

+            toCall.push(this.handlers[item]);

+        }

+        for (var i = 0; i < toCall.length; ++i) {

+            toCall[i].apply(this, fireArgs);

+        }

+        if (this.state == 2 && this.numHandlers) {

+            this.numHandlers = 0;

+            this.handlers = {};

+            this.onHasSubscribersChange && this.onHasSubscribersChange();

+        }

+    }

+};

+

+

+// defining them here so they are ready super fast!

+// DOM event that is received when the web page is loaded and parsed.

+channel.createSticky('onDOMContentLoaded');

+

+// Event to indicate the Cordova native side is ready.

+channel.createSticky('onNativeReady');

+

+// Event to indicate that all Cordova JavaScript objects have been created

+// and it's time to run plugin constructors.

+channel.createSticky('onCordovaReady');

+

+// Event to indicate that device properties are available

+channel.createSticky('onCordovaInfoReady');

+

+// Event to indicate that the connection property has been set.

+channel.createSticky('onCordovaConnectionReady');

+

+// Event to indicate that all automatically loaded JS plugins are loaded and ready.

+channel.createSticky('onPluginsReady');

+

+// Event to indicate that Cordova is ready

+channel.createSticky('onDeviceReady');

+

+// Event to indicate a resume lifecycle event

+channel.create('onResume');

+

+// Event to indicate a pause lifecycle event

+channel.create('onPause');

+

+// Event to indicate a destroy lifecycle event

+channel.createSticky('onDestroy');

+

+// Channels that must fire before "deviceready" is fired.

+channel.waitForInitialization('onCordovaReady');

+channel.waitForInitialization('onCordovaConnectionReady');

+channel.waitForInitialization('onDOMContentLoaded');

+

+module.exports = channel;

+

+});

+

+// file: lib/common/commandProxy.js

+define("cordova/commandProxy", function(require, exports, module) {

+

+

+// internal map of proxy function

+var CommandProxyMap = {};

+

+module.exports = {

+

+    // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);

+    add:function(id,proxyObj) {

+        console.log("adding proxy for " + id);

+        CommandProxyMap[id] = proxyObj;

+        return proxyObj;

+    },

+

+    // cordova.commandProxy.remove("Accelerometer");

+    remove:function(id) {

+        var proxy = CommandProxyMap[id];

+        delete CommandProxyMap[id];

+        CommandProxyMap[id] = null;

+        return proxy;

+    },

+

+    get:function(service,action) {

+        return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );

+    }

+};

+});

+

+// file: lib/windowsphone/exec.js

+define("cordova/exec", function(require, exports, module) {

+

+var cordova = require('cordova');

+

+/**

+ * Execute a cordova command.  It is up to the native side whether this action

+ * is synchronous or asynchronous.  The native side can return:

+ *      Synchronous: PluginResult object as a JSON string

+ *      Asynchronous: Empty string ""

+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,

+ * depending upon the result of the action.

+ *

+ * @param {Function} success    The success callback

+ * @param {Function} fail       The fail callback

+ * @param {String} service      The name of the service to use

+ * @param {String} action       Action to be run in cordova

+ * @param {String[]} [args]     Zero or more arguments to pass to the method

+

+ */

+

+module.exports = function(success, fail, service, action, args) {

+

+    var callbackId = service + cordova.callbackId++;

+    if (typeof success == "function" || typeof fail == "function") {

+        cordova.callbacks[callbackId] = {success:success, fail:fail};

+    }

+    // generate a new command string, ex. DebugConsole/log/DebugConsole23/["wtf dude?"]

+    for(var n = 0; n < args.length; n++)

+    {

+        if(typeof args[n] !== "string")

+        {

+            args[n] = JSON.stringify(args[n]);

+        }

+    }

+    var command = service + "/" + action + "/" + callbackId + "/" + JSON.stringify(args);

+    // pass it on to Notify

+    try {

+        if(window.external) {

+            window.external.Notify(command);

+        }

+        else {

+            console.log("window.external not available :: command=" + command);

+        }

+    }

+    catch(e) {

+        console.log("Exception calling native with command :: " + command + " :: exception=" + e);

+    }

+};

+

+

+});

+

+// file: lib/common/modulemapper.js

+define("cordova/modulemapper", function(require, exports, module) {

+

+var builder = require('cordova/builder'),

+    moduleMap = define.moduleMap,

+    symbolList,

+    deprecationMap;

+

+exports.reset = function() {

+    symbolList = [];

+    deprecationMap = {};

+};

+

+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {

+    if (!(moduleName in moduleMap)) {

+        throw new Error('Module ' + moduleName + ' does not exist.');

+    }

+    symbolList.push(strategy, moduleName, symbolPath);

+    if (opt_deprecationMessage) {

+        deprecationMap[symbolPath] = opt_deprecationMessage;

+    }

+}

+

+// Note: Android 2.3 does have Function.bind().

+exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {

+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);

+};

+

+exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {

+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);

+};

+

+exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {

+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);

+};

+

+exports.runs = function(moduleName) {

+    addEntry('r', moduleName, null);

+};

+

+function prepareNamespace(symbolPath, context) {

+    if (!symbolPath) {

+        return context;

+    }

+    var parts = symbolPath.split('.');

+    var cur = context;

+    for (var i = 0, part; part = parts[i]; ++i) {

+        cur = cur[part] = cur[part] || {};

+    }

+    return cur;

+}

+

+exports.mapModules = function(context) {

+    var origSymbols = {};

+    context.CDV_origSymbols = origSymbols;

+    for (var i = 0, len = symbolList.length; i < len; i += 3) {

+        var strategy = symbolList[i];

+        var moduleName = symbolList[i + 1];

+        var module = require(moduleName);

+        // <runs/>

+        if (strategy == 'r') {

+            continue;

+        }

+        var symbolPath = symbolList[i + 2];

+        var lastDot = symbolPath.lastIndexOf('.');

+        var namespace = symbolPath.substr(0, lastDot);

+        var lastName = symbolPath.substr(lastDot + 1);

+

+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;

+        var parentObj = prepareNamespace(namespace, context);

+        var target = parentObj[lastName];

+

+        if (strategy == 'm' && target) {

+            builder.recursiveMerge(target, module);

+        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {

+            if (!(symbolPath in origSymbols)) {

+                origSymbols[symbolPath] = target;

+            }

+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);

+        }

+    }

+};

+

+exports.getOriginalSymbol = function(context, symbolPath) {

+    var origSymbols = context.CDV_origSymbols;

+    if (origSymbols && (symbolPath in origSymbols)) {

+        return origSymbols[symbolPath];

+    }

+    var parts = symbolPath.split('.');

+    var obj = context;

+    for (var i = 0; i < parts.length; ++i) {

+        obj = obj && obj[parts[i]];

+    }

+    return obj;

+};

+

+exports.loadMatchingModules = function(matchingRegExp) {

+    for (var k in moduleMap) {

+        if (matchingRegExp.exec(k)) {

+            require(k);

+        }

+    }

+};

+

+exports.reset();

+

+

+});

+

+// file: lib/windowsphone/platform.js

+define("cordova/platform", function(require, exports, module) {

+

+

+

+module.exports = {

+    id: "windowsphone",

+    initialize:function() {

+        var cordova = require('cordova'),

+            exec = require('cordova/exec');

+

+        var modulemapper = require('cordova/modulemapper');

+

+        modulemapper.loadMatchingModules(/cordova.*\/plugininit$/);

+

+        modulemapper.loadMatchingModules(/cordova.*\/symbols$/);

+

+        modulemapper.mapModules(window);

+

+        window.File = require("cordova/plugin/File");

+

+        // Inject a listener for the backbutton, and tell native to override the flag (true/false) when we have 1 or more, or 0, listeners

+        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');

+        backButtonChannel.onHasSubscribersChange = function() {

+            exec(null, null, "CoreEvents", "overridebackbutton", [this.numHandlers == 1]);

+        };

+    }

+};

+

+});

+

+// 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 argscheck = require('cordova/argscheck'),

+    exec = require('cordova/exec'),

+    Camera = require('cordova/plugin/CameraConstants'),

+    CameraPopoverHandle = require('cordova/plugin/CameraPopoverHandle');

+

+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) {

+    argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);

+    options = options || {};

+    var getValue = argscheck.getValue;

+

+    var quality = getValue(options.quality, 50);

+    var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);

+    var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);

+    var targetWidth = getValue(options.targetWidth, -1);

+    var targetHeight = getValue(options.targetHeight, -1);

+    var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);

+    var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);

+    var allowEdit = !!options.allowEdit;

+    var correctOrientation = !!options.correctOrientation;

+    var saveToPhotoAlbum = !!options.saveToPhotoAlbum;

+    var popoverOptions = getValue(options.popoverOptions, null);

+    var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);

+

+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,

+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];

+

+    exec(successCallback, errorCallback, "Camera", "takePicture", args);

+    return new CameraPopoverHandle();

+};

+

+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)

+    NATIVE_URI: 2        // Return native uri (eg. asset-library://... for iOS)

+  },

+  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

+  },

+  Direction:{

+      BACK: 0,

+      FRONT: 1

+  }

+};

+

+});

+

+// file: lib/common/plugin/CameraPopoverHandle.js

+define("cordova/plugin/CameraPopoverHandle", function(require, exports, module) {

+

+var exec = require('cordova/exec');

+

+/**

+ * A handle to an image picker popover.

+ */

+var CameraPopoverHandle = function() {

+    this.setPosition = function(popoverOptions) {

+        console.log('CameraPopoverHandle.setPosition is only supported on iOS.');

+    };

+};

+

+module.exports = CameraPopoverHandle;

+

+});

+

+// 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;

+};

+

+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;

+};

+

+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;

+};

+

+module.exports = CaptureVideoOptions;

+

+});

+

+// file: lib/common/plugin/CompassError.js

+define("cordova/plugin/CompassError", function(require, exports, module) {

+

+/**

+ *  CompassError.

+ *  An error code assigned by an implementation when an error has occurred

+ * @constructor

+ */

+var CompassError = function(err) {

+    this.code = (err !== undefined ? err : null);

+};

+

+CompassError.COMPASS_INTERNAL_ERR = 0;

+CompassError.COMPASS_NOT_SUPPORTED = 20;

+

+module.exports = CompassError;

+

+});

+

+// file: lib/common/plugin/CompassHeading.js

+define("cordova/plugin/CompassHeading", function(require, exports, module) {

+

+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {

+  this.magneticHeading = magneticHeading;

+  this.trueHeading = trueHeading;

+  this.headingAccuracy = headingAccuracy;

+  this.timestamp = 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",

+        CELL:"cellular",

+        NONE: "none"

+};

+

+});

+

+// file: lib/common/plugin/Contact.js

+define("cordova/plugin/Contact", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    exec = require('cordova/exec'),

+    ContactError = require('cordova/plugin/ContactError'),

+    utils = require('cordova/utils');

+

+/**

+* Converts primitives into Complex Object

+* Currently only used for Date fields

+*/

+function convertIn(contact) {

+    var value = contact.birthday;

+    try {

+      contact.birthday = new Date(parseFloat(value));

+    } catch (exception){

+      console.log("Cordova Contact convertIn error: exception creating date.");

+    }

+    return contact;

+}

+

+/**

+* Converts Complex objects into primitives

+* Only conversion at present is for Dates.

+**/

+

+function convertOut(contact) {

+    var value = contact.birthday;

+    if (value !== null) {

+        // try to make it a Date object if it is not already

+        if (!utils.isDate(value)){

+            try {

+                value = new Date(value);

+            } catch(exception){

+                value = null;

+            }

+        }

+        if (utils.isDate(value)){

+            value = value.valueOf(); // convert to milliseconds

+        }

+        contact.birthday = value;

+    }

+    return contact;

+}

+

+/**

+* Contains information about a single contact.

+* @constructor

+* @param {DOMString} id unique identifier

+* @param {DOMString} displayName

+* @param {ContactName} name

+* @param {DOMString} nickname

+* @param {Array.<ContactField>} phoneNumbers array of phone numbers

+* @param {Array.<ContactField>} emails array of email addresses

+* @param {Array.<ContactAddress>} addresses array of addresses

+* @param {Array.<ContactField>} ims instant messaging user ids

+* @param {Array.<ContactOrganization>} organizations

+* @param {DOMString} birthday contact's birthday

+* @param {DOMString} note user notes about contact

+* @param {Array.<ContactField>} photos

+* @param {Array.<ContactField>} categories

+* @param {Array.<ContactField>} urls contact's web sites

+*/

+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,

+    ims, organizations, birthday, note, photos, categories, urls) {

+    this.id = id || null;

+    this.rawId = null;

+    this.displayName = displayName || null;

+    this.name = name || null; // ContactName

+    this.nickname = nickname || null;

+    this.phoneNumbers = phoneNumbers || null; // ContactField[]

+    this.emails = emails || null; // ContactField[]

+    this.addresses = addresses || null; // ContactAddress[]

+    this.ims = ims || null; // ContactField[]

+    this.organizations = organizations || null; // ContactOrganization[]

+    this.birthday = birthday || null;

+    this.note = note || null;

+    this.photos = photos || null; // ContactField[]

+    this.categories = categories || null; // ContactField[]

+    this.urls = urls || null; // ContactField[]

+};

+

+/**

+* Removes contact from device storage.

+* @param successCB success callback

+* @param errorCB error callback

+*/

+Contact.prototype.remove = function(successCB, errorCB) {

+    argscheck.checkArgs('FF', 'Contact.remove', arguments);

+    var fail = errorCB && 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);

+    clonedContact.id = null;

+    clonedContact.rawId = null;

+

+    function nullIds(arr) {

+        if (arr) {

+            for (var i = 0; i < arr.length; ++i) {

+                arr[i].id = null;

+            }

+        }

+    }

+

+    // Loop through and clear out any id's in phones, emails, etc.

+    nullIds(clonedContact.phoneNumbers);

+    nullIds(clonedContact.emails);

+    nullIds(clonedContact.addresses);

+    nullIds(clonedContact.ims);

+    nullIds(clonedContact.organizations);

+    nullIds(clonedContact.categories);

+    nullIds(clonedContact.photos);

+    nullIds(clonedContact.urls);

+    return clonedContact;

+};

+

+/**

+* Persists contact to device storage.

+* @param successCB success callback

+* @param errorCB error callback

+*/

+Contact.prototype.save = function(successCB, errorCB) {

+    argscheck.checkArgs('FFO', 'Contact.save', arguments);

+    var fail = errorCB && function(code) {

+        errorCB(new ContactError(code));

+    };

+    var success = function(result) {

+        if (result) {

+            if (successCB) {

+                var fullContact = require('cordova/plugin/contacts').create(result);

+                successCB(convertIn(fullContact));

+            }

+        }

+        else {

+            // no Entry object returned

+            fail(ContactError.UNKNOWN_ERROR);

+        }

+    };

+    var dupContact = convertOut(utils.clone(this));

+    exec(success, fail, "Contacts", "save", [dupContact]);

+};

+

+

+module.exports = Contact;

+

+});

+

+// file: lib/common/plugin/ContactAddress.js

+define("cordova/plugin/ContactAddress", function(require, exports, module) {

+

+/**

+* Contact address.

+* @constructor

+* @param {DOMString} id unique identifier, should only be set by native code

+* @param formatted // NOTE: not a W3C standard

+* @param streetAddress

+* @param locality

+* @param region

+* @param postalCode

+* @param country

+*/

+

+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {

+    this.id = null;

+    this.pref = (typeof pref != 'undefined' ? pref : false);

+    this.type = type || null;

+    this.formatted = formatted || null;

+    this.streetAddress = streetAddress || null;

+    this.locality = locality || null;

+    this.region = region || null;

+    this.postalCode = postalCode || null;

+    this.country = country || null;

+};

+

+module.exports = ContactAddress;

+

+});

+

+// file: lib/common/plugin/ContactError.js

+define("cordova/plugin/ContactError", function(require, exports, module) {

+

+/**

+ *  ContactError.

+ *  An error code assigned by an implementation when an error has occurred

+ * @constructor

+ */

+var ContactError = function(err) {

+    this.code = (typeof err != 'undefined' ? err : null);

+};

+

+/**

+ * Error codes

+ */

+ContactError.UNKNOWN_ERROR = 0;

+ContactError.INVALID_ARGUMENT_ERROR = 1;

+ContactError.TIMEOUT_ERROR = 2;

+ContactError.PENDING_OPERATION_ERROR = 3;

+ContactError.IO_ERROR = 4;

+ContactError.NOT_SUPPORTED_ERROR = 5;

+ContactError.PERMISSION_DENIED_ERROR = 20;

+

+module.exports = ContactError;

+

+});

+

+// file: lib/common/plugin/ContactField.js

+define("cordova/plugin/ContactField", function(require, exports, module) {

+

+/**

+* Generic contact field.

+* @constructor

+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard

+* @param type

+* @param value

+* @param pref

+*/

+var ContactField = function(type, value, pref) {

+    this.id = null;

+    this.type = (type && type.toString()) || null;

+    this.value = (value && value.toString()) || null;

+    this.pref = (typeof pref != 'undefined' ? pref : false);

+};

+

+module.exports = ContactField;

+

+});

+

+// file: lib/common/plugin/ContactFindOptions.js

+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {

+

+/**

+ * ContactFindOptions.

+ * @constructor

+ * @param filter used to match contacts against

+ * @param multiple boolean used to determine if more than one contact should be returned

+ */

+

+var ContactFindOptions = function(filter, multiple) {

+    this.filter = filter || '';

+    this.multiple = (typeof multiple != 'undefined' ? multiple : false);

+};

+

+module.exports = ContactFindOptions;

+

+});

+

+// file: lib/common/plugin/ContactName.js

+define("cordova/plugin/ContactName", function(require, exports, module) {

+

+/**

+* Contact name.

+* @constructor

+* @param formatted // NOTE: not part of W3C standard

+* @param familyName

+* @param givenName

+* @param middle

+* @param prefix

+* @param suffix

+*/

+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {

+    this.formatted = formatted || null;

+    this.familyName = familyName || null;

+    this.givenName = givenName || null;

+    this.middleName = middle || null;

+    this.honorificPrefix = prefix || null;

+    this.honorificSuffix = suffix || null;

+};

+

+module.exports = ContactName;

+

+});

+

+// file: lib/common/plugin/ContactOrganization.js

+define("cordova/plugin/ContactOrganization", function(require, exports, module) {

+

+/**

+* Contact organization.

+* @constructor

+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard

+* @param name

+* @param dept

+* @param title

+* @param startDate

+* @param endDate

+* @param location

+* @param desc

+*/

+

+var ContactOrganization = function(pref, type, name, dept, title) {

+    this.id = null;

+    this.pref = (typeof pref != 'undefined' ? pref : false);

+    this.type = type || null;

+    this.name = name || null;

+    this.department = dept || null;

+    this.title = title || null;

+};

+

+module.exports = ContactOrganization;

+

+});

+

+// file: lib/common/plugin/Coordinates.js

+define("cordova/plugin/Coordinates", function(require, exports, module) {

+

+/**

+ * This class contains position information.

+ * @param {Object} lat

+ * @param {Object} lng

+ * @param {Object} alt

+ * @param {Object} acc

+ * @param {Object} head

+ * @param {Object} vel

+ * @param {Object} altacc

+ * @constructor

+ */

+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {

+    /**

+     * The latitude of the position.

+     */

+    this.latitude = lat;

+    /**

+     * The longitude of the position,

+     */

+    this.longitude = lng;

+    /**

+     * The accuracy of the position.

+     */

+    this.accuracy = acc;

+    /**

+     * The altitude of the position.

+     */

+    this.altitude = (alt !== undefined ? alt : null);

+    /**

+     * The direction the device is moving at the position.

+     */

+    this.heading = (head !== undefined ? head : null);

+    /**

+     * The velocity with which the device is moving at the position.

+     */

+    this.speed = (vel !== undefined ? vel : null);

+

+    if (this.speed === 0 || this.speed === null) {

+        this.heading = NaN;

+    }

+

+    /**

+     * The altitude accuracy of the position.

+     */

+    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;

+};

+

+module.exports = Coordinates;

+

+});

+

+// file: lib/common/plugin/DirectoryEntry.js

+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    utils = require('cordova/utils'),

+    exec = require('cordova/exec'),

+    Entry = require('cordova/plugin/Entry'),

+    FileError = require('cordova/plugin/FileError'),

+    DirectoryReader = require('cordova/plugin/DirectoryReader');

+

+/**

+ * An interface representing a directory on the file system.

+ *

+ * {boolean} isFile always false (readonly)

+ * {boolean} isDirectory always true (readonly)

+ * {DOMString} name of the directory, excluding the path leading to it (readonly)

+ * {DOMString} fullPath the absolute full path to the directory (readonly)

+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)

+ */

+var DirectoryEntry = function(name, fullPath) {

+     DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath);

+};

+

+utils.extend(DirectoryEntry, Entry);

+

+/**

+ * Creates a new DirectoryReader to read entries from this directory

+ */

+DirectoryEntry.prototype.createReader = function() {

+    return new DirectoryReader(this.fullPath);

+};

+

+/**

+ * Creates or looks up a directory

+ *

+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory

+ * @param {Flags} options to create or exclusively create the directory

+ * @param {Function} successCallback is called with the new entry

+ * @param {Function} errorCallback is called with a FileError

+ */

+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {

+    argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);

+    var win = successCallback && function(result) {

+        var entry = new DirectoryEntry(result.name, result.fullPath);

+        successCallback(entry);

+    };

+    var fail = errorCallback && 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) {

+    argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);

+};

+

+/**

+ * Creates or looks up a file

+ *

+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file

+ * @param {Flags} options to create or exclusively create the file

+ * @param {Function} successCallback is called with the new entry

+ * @param {Function} errorCallback is called with a FileError

+ */

+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {

+    argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);

+    var win = successCallback && function(result) {

+        var FileEntry = require('cordova/plugin/FileEntry');

+        var entry = new FileEntry(result.name, result.fullPath);

+        successCallback(entry);

+    };

+    var fail = errorCallback && 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;

+    this.hasReadEntries = false;

+}

+

+/**

+ * 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) {

+    // If we've already read and passed on this directory's entries, return an empty list.

+    if (this.hasReadEntries) {

+        successCallback([]);

+        return;

+    }

+    var reader = this;

+    var win = typeof successCallback !== 'function' ? null : function(result) {

+        var retVal = [];

+        for (var i=0; i<result.length; i++) {

+            var entry = null;

+            if (result[i].isDirectory) {

+                entry = new (require('cordova/plugin/DirectoryEntry'))();

+            }

+            else if (result[i].isFile) {

+                entry = new (require('cordova/plugin/FileEntry'))();

+            }

+            entry.isDirectory = result[i].isDirectory;

+            entry.isFile = result[i].isFile;

+            entry.name = result[i].name;

+            entry.fullPath = result[i].fullPath;

+            retVal.push(entry);

+        }

+        reader.hasReadEntries = true;

+        successCallback(retVal);

+    };

+    var fail = typeof errorCallback !== 'function' ? null : function(code) {

+        errorCallback(new FileError(code));

+    };

+    exec(win, fail, "File", "readEntries", [this.path]);

+};

+

+module.exports = DirectoryReader;

+

+});

+

+// file: lib/common/plugin/Entry.js

+define("cordova/plugin/Entry", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    exec = require('cordova/exec'),

+    FileError = require('cordova/plugin/FileError'),

+    Metadata = require('cordova/plugin/Metadata');

+

+/**

+ * Represents a file or directory on the local file system.

+ *

+ * @param isFile

+ *            {boolean} true if Entry is a file (readonly)

+ * @param isDirectory

+ *            {boolean} true if Entry is a directory (readonly)

+ * @param name

+ *            {DOMString} name of the file or directory, excluding the path

+ *            leading to it (readonly)

+ * @param fullPath

+ *            {DOMString} the absolute full path to the file or directory

+ *            (readonly)

+ */

+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {

+    this.isFile = !!isFile;

+    this.isDirectory = !!isDirectory;

+    this.name = name || '';

+    this.fullPath = fullPath || '';

+    this.filesystem = fileSystem || null;

+}

+

+/**

+ * Look up the metadata of the entry.

+ *

+ * @param successCallback

+ *            {Function} is called with a Metadata object

+ * @param errorCallback

+ *            {Function} is called with a FileError

+ */

+Entry.prototype.getMetadata = function(successCallback, errorCallback) {

+    argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);

+    var success = successCallback && function(lastModified) {

+        var metadata = new Metadata(lastModified);

+        successCallback(metadata);

+    };

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+

+    exec(success, fail, "File", "getMetadata", [this.fullPath]);

+};

+

+/**

+ * Set the metadata of the entry.

+ *

+ * @param successCallback

+ *            {Function} is called with a Metadata object

+ * @param errorCallback

+ *            {Function} is called with a FileError

+ * @param metadataObject

+ *            {Object} keys and values to set

+ */

+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {

+    argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);

+    exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);

+};

+

+/**

+ * Move a file or directory to a new location.

+ *

+ * @param parent

+ *            {DirectoryEntry} the directory to which to move this entry

+ * @param newName

+ *            {DOMString} new name of the entry, defaults to the current name

+ * @param successCallback

+ *            {Function} called with the new DirectoryEntry object

+ * @param errorCallback

+ *            {Function} called with a FileError

+ */

+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {

+    argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+    // source path

+    var srcPath = this.fullPath,

+        // entry name

+        name = newName || this.name,

+        success = function(entry) {

+            if (entry) {

+                if (successCallback) {

+                    // create appropriate Entry object

+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);

+                    successCallback(result);

+                }

+            }

+            else {

+                // no Entry object returned

+                fail && fail(FileError.NOT_FOUND_ERR);

+            }

+        };

+

+    // copy

+    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);

+};

+

+/**

+ * Copy a directory to a different location.

+ *

+ * @param parent

+ *            {DirectoryEntry} the directory to which to copy the entry

+ * @param newName

+ *            {DOMString} new name of the entry, defaults to the current name

+ * @param successCallback

+ *            {Function} called with the new Entry object

+ * @param errorCallback

+ *            {Function} called with a FileError

+ */

+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {

+    argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+

+        // source path

+    var srcPath = this.fullPath,

+        // entry name

+        name = newName || this.name,

+        // success callback

+        success = function(entry) {

+            if (entry) {

+                if (successCallback) {

+                    // create appropriate Entry object

+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);

+                    successCallback(result);

+                }

+            }

+            else {

+                // no Entry object returned

+                fail && fail(FileError.NOT_FOUND_ERR);

+            }

+        };

+

+    // copy

+    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);

+};

+

+/**

+ * Return a URL that can be used to identify this entry.

+ */

+Entry.prototype.toURL = function() {

+    // fullPath attribute contains the full URL

+    return this.fullPath;

+};

+

+/**

+ * Returns a URI that can be used to identify this entry.

+ *

+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.

+ * @return uri

+ */

+Entry.prototype.toURI = function(mimeType) {

+    console.log("DEPRECATED: Update your code to use 'toURL'");

+    // fullPath attribute contains the full URI

+    return this.toURL();

+};

+

+/**

+ * Remove a file or directory. It is an error to attempt to delete a

+ * directory that is not empty. It is an error to attempt to delete a

+ * root directory of a file system.

+ *

+ * @param successCallback {Function} called with no parameters

+ * @param errorCallback {Function} called with a FileError

+ */

+Entry.prototype.remove = function(successCallback, errorCallback) {

+    argscheck.checkArgs('FF', 'Entry.remove', arguments);

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+    exec(successCallback, fail, "File", "remove", [this.fullPath]);

+};

+

+/**

+ * Look up the parent DirectoryEntry of this entry.

+ *

+ * @param successCallback {Function} called with the parent DirectoryEntry object

+ * @param errorCallback {Function} called with a FileError

+ */

+Entry.prototype.getParent = function(successCallback, errorCallback) {

+    argscheck.checkArgs('FF', 'Entry.getParent', arguments);

+    var win = successCallback && function(result) {

+        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');

+        var entry = new DirectoryEntry(result.name, result.fullPath);

+        successCallback(entry);

+    };

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+    exec(win, fail, "File", "getParent", [this.fullPath]);

+};

+

+module.exports = Entry;

+

+});

+

+// file: lib/common/plugin/File.js

+define("cordova/plugin/File", function(require, exports, module) {

+

+/**

+ * Constructor.

+ * name {DOMString} name of the file, without path information

+ * fullPath {DOMString} the full path of the file, including the name

+ * type {DOMString} mime type

+ * lastModifiedDate {Date} last modified date

+ * size {Number} size of the file in bytes

+ */

+

+var File = function(name, fullPath, type, lastModifiedDate, size){

+    this.name = name || '';

+    this.fullPath = fullPath || null;

+    this.type = type || null;

+    this.lastModifiedDate = lastModifiedDate || null;

+    this.size = size || 0;

+

+    // These store the absolute start and end for slicing the file.

+    this.start = 0;

+    this.end = this.size;

+};

+

+/**

+ * Returns a "slice" of the file. Since Cordova Files don't contain the actual

+ * content, this really returns a File with adjusted start and end.

+ * Slices of slices are supported.

+ * start {Number} The index at which to start the slice (inclusive).

+ * end {Number} The index at which to end the slice (exclusive).

+ */

+File.prototype.slice = function(start, end) {

+    var size = this.end - this.start;

+    var newStart = 0;

+    var newEnd = size;

+    if (arguments.length) {

+        if (start < 0) {

+            newStart = Math.max(size + start, 0);

+        } else {

+            newStart = Math.min(size, start);

+        }

+    }

+

+    if (arguments.length >= 2) {

+        if (end < 0) {

+            newEnd = Math.max(size + end, 0);

+        } else {

+            newEnd = Math.min(end, size);

+        }

+    }

+

+    var newFile = new File(this.name, this.fullPath, this.type, this.lastModifiedData, this.size);

+    newFile.start = this.start + newStart;

+    newFile.end = this.start + newEnd;

+    return newFile;

+};

+

+

+module.exports = File;

+

+});

+

+// file: lib/common/plugin/FileEntry.js

+define("cordova/plugin/FileEntry", function(require, exports, module) {

+

+var utils = require('cordova/utils'),

+    exec = require('cordova/exec'),

+    Entry = require('cordova/plugin/Entry'),

+    FileWriter = require('cordova/plugin/FileWriter'),

+    File = require('cordova/plugin/File'),

+    FileError = require('cordova/plugin/FileError');

+

+/**

+ * An interface representing a file on the file system.

+ *

+ * {boolean} isFile always true (readonly)

+ * {boolean} isDirectory always false (readonly)

+ * {DOMString} name of the file, excluding the path leading to it (readonly)

+ * {DOMString} fullPath the absolute full path to the file (readonly)

+ * {FileSystem} filesystem on which the file resides (readonly)

+ */

+var FileEntry = function(name, fullPath) {

+     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);

+};

+

+utils.extend(FileEntry, Entry);

+

+/**

+ * Creates a new FileWriter associated with the file that this FileEntry represents.

+ *

+ * @param {Function} successCallback is called with the new FileWriter

+ * @param {Function} errorCallback is called with a FileError

+ */

+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {

+    this.file(function(filePointer) {

+        var writer = new FileWriter(filePointer);

+

+        if (writer.fileName === null || writer.fileName === "") {

+            errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR));

+        } else {

+            successCallback && successCallback(writer);

+        }

+    }, errorCallback);

+};

+

+/**

+ * Returns a File that represents the current state of the file that this FileEntry represents.

+ *

+ * @param {Function} successCallback is called with the new File object

+ * @param {Function} errorCallback is called with a FileError

+ */

+FileEntry.prototype.file = function(successCallback, errorCallback) {

+    var win = successCallback && function(f) {

+        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);

+        successCallback(file);

+    };

+    var fail = errorCallback && function(code) {

+        errorCallback(new FileError(code));

+    };

+    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);

+};

+

+

+module.exports = FileEntry;

+

+});

+

+// file: lib/common/plugin/FileError.js

+define("cordova/plugin/FileError", function(require, exports, module) {

+

+/**

+ * FileError

+ */

+function FileError(error) {

+  this.code = error || null;

+}

+

+// File error codes

+// Found in DOMException

+FileError.NOT_FOUND_ERR = 1;

+FileError.SECURITY_ERR = 2;

+FileError.ABORT_ERR = 3;

+

+// Added by File API specification

+FileError.NOT_READABLE_ERR = 4;

+FileError.ENCODING_ERR = 5;

+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;

+FileError.INVALID_STATE_ERR = 7;

+FileError.SYNTAX_ERR = 8;

+FileError.INVALID_MODIFICATION_ERR = 9;

+FileError.QUOTA_EXCEEDED_ERR = 10;

+FileError.TYPE_MISMATCH_ERR = 11;

+FileError.PATH_EXISTS_ERR = 12;

+

+module.exports = FileError;

+

+});

+

+// file: lib/common/plugin/FileReader.js

+define("cordova/plugin/FileReader", function(require, exports, module) {

+

+var exec = require('cordova/exec'),

+    modulemapper = require('cordova/modulemapper'),

+    utils = require('cordova/utils'),

+    File = require('cordova/plugin/File'),

+    FileError = require('cordova/plugin/FileError'),

+    ProgressEvent = require('cordova/plugin/ProgressEvent'),

+    origFileReader = modulemapper.getOriginalSymbol(this, 'FileReader');

+

+/**

+ * This class reads the mobile device file system.

+ *

+ * For Android:

+ *      The root directory is the root of the file system.

+ *      To read from the SD card, the file name is "sdcard/my_file.txt"

+ * @constructor

+ */

+var FileReader = function() {

+    this._readyState = 0;

+    this._error = null;

+    this._result = null;

+    this._fileName = '';

+    this._realReader = origFileReader ? new origFileReader() : {};

+};

+

+// States

+FileReader.EMPTY = 0;

+FileReader.LOADING = 1;

+FileReader.DONE = 2;

+

+utils.defineGetter(FileReader.prototype, 'readyState', function() {

+    return this._fileName ? this._readyState : this._realReader.readyState;

+});

+

+utils.defineGetter(FileReader.prototype, 'error', function() {

+    return this._fileName ? this._error: this._realReader.error;

+});

+

+utils.defineGetter(FileReader.prototype, 'result', function() {

+    return this._fileName ? this._result: this._realReader.result;

+});

+

+function defineEvent(eventName) {

+    utils.defineGetterSetter(FileReader.prototype, eventName, function() {

+        return this._realReader[eventName] || null;

+    }, function(value) {

+        this._realReader[eventName] = value;

+    });

+}

+defineEvent('onloadstart');    // When the read starts.

+defineEvent('onprogress');     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)

+defineEvent('onload');         // When the read has successfully completed.

+defineEvent('onerror');        // When the read has failed (see errors).

+defineEvent('onloadend');      // When the request has completed (either in success or failure).

+defineEvent('onabort');        // When the read has been aborted. For instance, by invoking the abort() method.

+

+function initRead(reader, file) {

+    // Already loading something

+    if (reader.readyState == FileReader.LOADING) {

+      throw new FileError(FileError.INVALID_STATE_ERR);

+    }

+

+    reader._result = null;

+    reader._error = null;

+    reader._readyState = FileReader.LOADING;

+

+    if (typeof file.fullPath == 'string') {

+        reader._fileName = file.fullPath;

+    } else {

+        reader._fileName = '';

+        return true;

+    }

+

+    reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader}));

+}

+

+/**

+ * Abort reading file.

+ */

+FileReader.prototype.abort = function() {

+    if (origFileReader && !this._fileName) {

+        return this._realReader.abort();

+    }

+    this._result = null;

+

+    if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {

+      return;

+    }

+

+    this._readyState = FileReader.DONE;

+

+    // If abort callback

+    if (typeof this.onabort === 'function') {

+        this.onabort(new ProgressEvent('abort', {target:this}));

+    }

+    // If load end callback

+    if (typeof this.onloadend === 'function') {

+        this.onloadend(new ProgressEvent('loadend', {target:this}));

+    }

+};

+

+/**

+ * Read text file.

+ *

+ * @param file          {File} File object containing file properties

+ * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)

+ */

+FileReader.prototype.readAsText = function(file, encoding) {

+    if (initRead(this, file)) {

+        return this._realReader.readAsText(file, encoding);

+    }

+

+    // Default encoding is UTF-8

+    var enc = encoding ? encoding : "UTF-8";

+    var me = this;

+    var execArgs = [this._fileName, enc, file.start, file.end];

+

+    // Read file

+    exec(

+        // Success callback

+        function(r) {

+            // If DONE (cancelled), then don't do anything

+            if (me._readyState === FileReader.DONE) {

+                return;

+            }

+

+            // Save result

+            me._result = r;

+

+            // If onload callback

+            if (typeof me.onload === "function") {

+                me.onload(new ProgressEvent("load", {target:me}));

+            }

+

+            // DONE state

+            me._readyState = FileReader.DONE;

+

+            // If onloadend callback

+            if (typeof me.onloadend === "function") {

+                me.onloadend(new ProgressEvent("loadend", {target:me}));

+            }

+        },

+        // Error callback

+        function(e) {

+            // If DONE (cancelled), then don't do anything

+            if (me._readyState === FileReader.DONE) {

+                return;

+            }

+

+            // DONE state

+            me._readyState = FileReader.DONE;

+

+            // null result

+            me._result = null;

+

+            // Save error

+            me._error = new FileError(e);

+

+            // If onerror callback

+            if (typeof me.onerror === "function") {

+                me.onerror(new ProgressEvent("error", {target:me}));

+            }

+

+            // If onloadend callback

+            if (typeof me.onloadend === "function") {

+                me.onloadend(new ProgressEvent("loadend", {target:me}));

+            }

+        }, "File", "readAsText", execArgs);

+};

+

+

+/**

+ * Read file and return data as a base64 encoded data url.

+ * A data url is of the form:

+ *      data:[<mediatype>][;base64],<data>

+ *

+ * @param file          {File} File object containing file properties

+ */

+FileReader.prototype.readAsDataURL = function(file) {

+    if (initRead(this, file)) {

+        return this._realReader.readAsDataURL(file);

+    }

+

+    var me = this;

+    var execArgs = [this._fileName, file.start, file.end];

+

+    // 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", execArgs);

+};

+

+/**

+ * Read file and return data as a binary data.

+ *

+ * @param file          {File} File object containing file properties

+ */

+FileReader.prototype.readAsBinaryString = function(file) {

+    if (initRead(this, file)) {

+        return this._realReader.readAsBinaryString(file);

+    }

+

+    var me = this;

+    var execArgs = [this._fileName, file.start, file.end];

+

+    // 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;

+

+            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", "readAsBinaryString", execArgs);

+};

+

+/**

+ * Read file and return data as a binary data.

+ *

+ * @param file          {File} File object containing file properties

+ */

+FileReader.prototype.readAsArrayBuffer = function(file) {

+    if (initRead(this, file)) {

+        return this._realReader.readAsArrayBuffer(file);

+    }

+

+    var me = this;

+    var execArgs = [this._fileName, file.start, file.end];

+

+    // 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;

+

+            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", "readAsArrayBuffer", execArgs);

+};

+

+module.exports = FileReader;

+

+});

+

+// file: lib/common/plugin/FileSystem.js

+define("cordova/plugin/FileSystem", function(require, exports, module) {

+

+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');

+

+/**

+ * An interface representing a file system

+ *

+ * @constructor

+ * {DOMString} name the unique name of the file system (readonly)

+ * {DirectoryEntry} root directory of the file system (readonly)

+ */

+var FileSystem = function(name, root) {

+    this.name = name || null;

+    if (root) {

+        this.root = new DirectoryEntry(root.name, root.fullPath);

+    }

+};

+

+module.exports = FileSystem;

+

+});

+

+// file: lib/common/plugin/FileTransfer.js

+define("cordova/plugin/FileTransfer", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    exec = require('cordova/exec'),

+    FileTransferError = require('cordova/plugin/FileTransferError'),

+    ProgressEvent = require('cordova/plugin/ProgressEvent');

+

+function newProgressEvent(result) {

+    var pe = new ProgressEvent();

+    pe.lengthComputable = result.lengthComputable;

+    pe.loaded = result.loaded;

+    pe.total = result.total;

+    return pe;

+}

+

+function getBasicAuthHeader(urlString) {

+    var header =  null;

+

+    if (window.btoa) {

+        // parse the url using the Location object

+        var url = document.createElement('a');

+        url.href = urlString;

+

+        var credentials = null;

+        var protocol = url.protocol + "//";

+        var origin = protocol + url.host;

+

+        // check whether there are the username:password credentials in the url

+        if (url.href.indexOf(origin) !== 0) { // credentials found

+            var atIndex = url.href.indexOf("@");

+            credentials = url.href.substring(protocol.length, atIndex);

+        }

+

+        if (credentials) {

+            var authHeader = "Authorization";

+            var authHeaderValue = "Basic " + window.btoa(credentials);

+

+            header = {

+                name : authHeader,

+                value : authHeaderValue

+            };

+        }

+    }

+

+    return header;

+}

+

+var idCounter = 0;

+

+/**

+ * FileTransfer uploads a file to a remote server.

+ * @constructor

+ */

+var FileTransfer = function() {

+    this._id = ++idCounter;

+    this.onprogress = null; // optional callback

+};

+

+/**

+* Given an absolute file path, uploads a file on the device to a remote server

+* using a multipart HTTP request.

+* @param filePath {String}           Full path of the file on the device

+* @param server {String}             URL of the server to receive the file

+* @param successCallback (Function}  Callback to be invoked when upload has completed

+* @param errorCallback {Function}    Callback to be invoked upon error

+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype

+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false

+*/

+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {

+    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);

+    // check for options

+    var fileKey = null;

+    var fileName = null;

+    var mimeType = null;

+    var params = null;

+    var chunkedMode = true;

+    var headers = null;

+    var httpMethod = null;

+    var basicAuthHeader = getBasicAuthHeader(server);

+    if (basicAuthHeader) {

+        options = options || {};

+        options.headers = options.headers || {};

+        options.headers[basicAuthHeader.name] = basicAuthHeader.value;

+    }

+

+    if (options) {

+        fileKey = options.fileKey;

+        fileName = options.fileName;

+        mimeType = options.mimeType;

+        headers = options.headers;

+        httpMethod = options.httpMethod || "POST";

+        if (httpMethod.toUpperCase() == "PUT"){

+            httpMethod = "PUT";

+        } else {

+            httpMethod = "POST";

+        }

+        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {

+            chunkedMode = options.chunkedMode;

+        }

+        if (options.params) {

+            params = options.params;

+        }

+        else {

+            params = {};

+        }

+    }

+

+    var fail = errorCallback && function(e) {

+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);

+        errorCallback(error);

+    };

+

+    var self = this;

+    var win = function(result) {

+        if (typeof result.lengthComputable != "undefined") {

+            if (self.onprogress) {

+                self.onprogress(newProgressEvent(result));

+            }

+        } else {

+            successCallback && successCallback(result);

+        }

+    };

+    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);

+};

+

+/**

+ * Downloads a file form a given URL and saves it to the specified directory.

+ * @param source {String}          URL of the server to receive the file

+ * @param target {String}         Full path of the file on the device

+ * @param successCallback (Function}  Callback to be invoked when upload has completed

+ * @param errorCallback {Function}    Callback to be invoked upon error

+ * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false

+ * @param options {FileDownloadOptions} Optional parameters such as headers

+ */

+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {

+    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);

+    var self = this;

+

+    var basicAuthHeader = getBasicAuthHeader(source);

+    if (basicAuthHeader) {

+        options = options || {};

+        options.headers = options.headers || {};

+        options.headers[basicAuthHeader.name] = basicAuthHeader.value;

+    }

+

+    var headers = null;

+    if (options) {

+        headers = options.headers || null;

+    }

+

+    var win = function(result) {

+        if (typeof result.lengthComputable != "undefined") {

+            if (self.onprogress) {

+                return self.onprogress(newProgressEvent(result));

+            }

+        } else if (successCallback) {

+            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 = errorCallback && function(e) {

+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);

+        errorCallback(error);

+    };

+

+    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);

+};

+

+/**

+ * Aborts the ongoing file transfer on this object. The original error

+ * callback for the file transfer will be called if necessary.

+ */

+FileTransfer.prototype.abort = function() {

+    exec(null, null, 'FileTransfer', 'abort', [this._id]);

+};

+

+module.exports = FileTransfer;

+

+});

+

+// file: lib/common/plugin/FileTransferError.js

+define("cordova/plugin/FileTransferError", function(require, exports, module) {

+

+/**

+ * FileTransferError

+ * @constructor

+ */

+var FileTransferError = function(code, source, target, status, body) {

+    this.code = code || null;

+    this.source = source || null;

+    this.target = target || null;

+    this.http_status = status || null;

+    this.body = body || null;

+};

+

+FileTransferError.FILE_NOT_FOUND_ERR = 1;

+FileTransferError.INVALID_URL_ERR = 2;

+FileTransferError.CONNECTION_ERR = 3;

+FileTransferError.ABORT_ERR = 4;

+

+module.exports = FileTransferError;

+

+});

+

+// file: lib/common/plugin/FileUploadOptions.js

+define("cordova/plugin/FileUploadOptions", function(require, exports, module) {

+

+/**

+ * Options to customize the HTTP request used to upload files.

+ * @constructor

+ * @param fileKey {String}   Name of file request parameter.

+ * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.

+ * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.

+ * @param params {Object}    Object with key: value params to send to the server.

+ * @param headers {Object}   Keys are header names, values are header values. Multiple

+ *                           headers of the same name are not supported.

+ */

+var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) {

+    this.fileKey = fileKey || null;

+    this.fileName = fileName || null;

+    this.mimeType = mimeType || null;

+    this.params = params || null;

+    this.headers = headers || null;

+    this.httpMethod = httpMethod || 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 data text or blob to be written

+ */

+FileWriter.prototype.write = function(data) {

+

+    var that=this;

+    var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined');

+    var isBinary;

+

+    // Check to see if the incoming data is a blob

+    if (data instanceof File || (supportsBinary && data instanceof Blob)) {

+        var fileReader = new FileReader();

+        fileReader.onload = function() {

+            // Call this method again, with the arraybuffer as argument

+            FileWriter.prototype.write.call(that, this.result);

+        };

+        if (supportsBinary) {

+            fileReader.readAsArrayBuffer(data);

+        } else {

+            fileReader.readAsText(data);

+        }

+        return;

+    }

+

+    // Mark data type for safer transport over the binary bridge

+    isBinary = supportsBinary && (data instanceof ArrayBuffer);

+

+    // 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, data, this.position, isBinary]);

+};

+

+/**

+ * Moves the file pointer to the location specified.

+ *

+ * If the offset is a negative number the position of the file

+ * pointer is rewound.  If the offset is greater than the file

+ * size the position is set to the end of the file.

+ *

+ * @param offset is the location to move the file pointer to.

+ */

+FileWriter.prototype.seek = function(offset) {

+    // Throw an exception if we are already writing a file

+    if (this.readyState === FileWriter.WRITING) {

+        throw new FileError(FileError.INVALID_STATE_ERR);

+    }

+

+    if (!offset && offset !== 0) {

+        return;

+    }

+

+    // See back from end of file.

+    if (offset < 0) {

+        this.position = Math.max(offset + this.length, 0);

+    }

+    // Offset is bigger than file size so set position

+    // to the end of the file.

+    else if (offset > this.length) {

+        this.position = this.length;

+    }

+    // Offset is between 0 and file size so set the position

+    // to start writing.

+    else {

+        this.position = offset;

+    }

+};

+

+/**

+ * Truncates the file to the size specified.

+ *

+ * @param size to chop the file at.

+ */

+FileWriter.prototype.truncate = function(size) {

+    // Throw an exception if we are already writing a file

+    if (this.readyState === FileWriter.WRITING) {

+        throw new FileError(FileError.INVALID_STATE_ERR);

+    }

+

+    // WRITING state

+    this.readyState = FileWriter.WRITING;

+

+    var me = this;

+

+    // If onwritestart callback

+    if (typeof me.onwritestart === "function") {

+        me.onwritestart(new ProgressEvent("writestart", {"target":this}));

+    }

+

+    // Write file

+    exec(

+        // Success callback

+        function(r) {

+            // If DONE (cancelled), then don't do anything

+            if (me.readyState === FileWriter.DONE) {

+                return;

+            }

+

+            // DONE state

+            me.readyState = FileWriter.DONE;

+

+            // Update the length of the file

+            me.length = r;

+            me.position = Math.min(me.position, r);

+

+            // If onwrite callback

+            if (typeof me.onwrite === "function") {

+                me.onwrite(new ProgressEvent("write", {"target":me}));

+            }

+

+            // If onwriteend callback

+            if (typeof me.onwriteend === "function") {

+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));

+            }

+        },

+        // Error callback

+        function(e) {

+            // If DONE (cancelled), then don't do anything

+            if (me.readyState === FileWriter.DONE) {

+                return;

+            }

+

+            // DONE state

+            me.readyState = FileWriter.DONE;

+

+            // Save error

+            me.error = new FileError(e);

+

+            // If onerror callback

+            if (typeof me.onerror === "function") {

+                me.onerror(new ProgressEvent("error", {"target":me}));

+            }

+

+            // If onwriteend callback

+            if (typeof me.onwriteend === "function") {

+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));

+            }

+        }, "File", "truncate", [this.fileName, size]);

+};

+

+module.exports = FileWriter;

+

+});

+

+// file: lib/common/plugin/Flags.js

+define("cordova/plugin/Flags", function(require, exports, module) {

+

+/**

+ * Supplies arguments to methods that lookup or create files and directories.

+ *

+ * @param create

+ *            {boolean} file or directory if it doesn't exist

+ * @param exclusive

+ *            {boolean} used with create; if true the command will fail if

+ *            target path exists

+ */

+function Flags(create, exclusive) {

+    this.create = create || false;

+    this.exclusive = exclusive || false;

+}

+

+module.exports = Flags;

+

+});

+

+// file: lib/common/plugin/GlobalizationError.js

+define("cordova/plugin/GlobalizationError", function(require, exports, module) {

+

+

+/**

+ * Globalization error object

+ *

+ * @constructor

+ * @param code

+ * @param message

+ */

+var GlobalizationError = function(code, message) {

+    this.code = code || null;

+    this.message = message || '';

+};

+

+// Globalization error codes

+GlobalizationError.UNKNOWN_ERROR = 0;

+GlobalizationError.FORMATTING_ERROR = 1;

+GlobalizationError.PARSING_ERROR = 2;

+GlobalizationError.PATTERN_ERROR = 3;

+

+module.exports = GlobalizationError;

+

+});

+

+// file: lib/common/plugin/InAppBrowser.js

+define("cordova/plugin/InAppBrowser", function(require, exports, module) {

+

+var exec = require('cordova/exec');

+var channel = require('cordova/channel');

+var modulemapper = require('cordova/modulemapper');

+var urlutil = require('cordova/urlutil');

+

+function InAppBrowser() {

+   this.channels = {

+        'loadstart': channel.create('loadstart'),

+        'loadstop' : channel.create('loadstop'),

+        'loaderror' : channel.create('loaderror'),

+        'exit' : channel.create('exit')

+   };

+   this._alive = true;

+}

+

+InAppBrowser.prototype = {

+    _eventHandler: function (event) {

+        if (event.type in this.channels) {

+            this.channels[event.type].fire(event);

+        }

+    },

+    close: function (eventname) {

+        if (this._alive) {

+            this._alive = false;

+            exec(null, null, "InAppBrowser", "close", []);

+        }

+    },

+    show: function (eventname) {

+      exec(null, null, "InAppBrowser", "show", []);

+    },

+    addEventListener: function (eventname,f) {

+        if (eventname in this.channels) {

+            this.channels[eventname].subscribe(f);

+        }

+    },

+    removeEventListener: function(eventname, f) {

+        if (eventname in this.channels) {

+            this.channels[eventname].unsubscribe(f);

+        }

+    },

+

+    executeScript: function(injectDetails, cb) {

+        if (injectDetails.code) {

+            exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);

+        } else if (injectDetails.file) {

+            exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);

+        } else {

+            throw new Error('executeScript requires exactly one of code or file to be specified');

+        }

+    },

+

+    insertCSS: function(injectDetails, cb) {

+        if (injectDetails.code) {

+            exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);

+        } else if (injectDetails.file) {

+            exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);

+        } else {

+            throw new Error('insertCSS requires exactly one of code or file to be specified');

+        }

+    }

+};

+

+module.exports = function(strUrl, strWindowName, strWindowFeatures) {

+    // Don't catch calls that write to existing frames (e.g. named iframes).

+    if (window.frames && window.frames[strWindowName]) {

+        var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');

+        return origOpenFunc.apply(window, arguments);

+    }

+

+    strUrl = urlutil.makeAbsolute(strUrl);

+    var iab = new InAppBrowser();

+    var cb = function(eventname) {

+       iab._eventHandler(eventname);

+    };

+

+    exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);

+    return iab;

+};

+

+

+});

+

+// 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 argscheck = require('cordova/argscheck'),

+    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) {

+    argscheck.checkArgs('SFFF', 'Media', arguments);

+    this.id = utils.createUUID();

+    mediaObjects[this.id] = this;

+    this.src = src;

+    this.successCallback = successCallback;

+    this.errorCallback = errorCallback;

+    this.statusCallback = statusCallback;

+    this._duration = -1;

+    this._position = -1;

+    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);

+};

+

+// Media messages

+Media.MEDIA_STATE = 1;

+Media.MEDIA_DURATION = 2;

+Media.MEDIA_POSITION = 3;

+Media.MEDIA_ERROR = 9;

+

+// Media states

+Media.MEDIA_NONE = 0;

+Media.MEDIA_STARTING = 1;

+Media.MEDIA_RUNNING = 2;

+Media.MEDIA_PAUSED = 3;

+Media.MEDIA_STOPPED = 4;

+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];

+

+// "static" function to return existing objs.

+Media.get = function(id) {

+    return mediaObjects[id];

+};

+

+/**

+ * Start or resume playing audio file.

+ */

+Media.prototype.play = function(options) {

+    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);

+};

+

+/**

+ * Stop playing audio file.

+ */

+Media.prototype.stop = function() {

+    var me = this;

+    exec(function() {

+        me._position = 0;

+    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);

+};

+

+/**

+ * Seek or jump to a new time in the track..

+ */

+Media.prototype.seekTo = function(milliseconds) {

+    var me = this;

+    exec(function(p) {

+        me._position = p;

+    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);

+};

+

+/**

+ * Pause playing audio file.

+ */

+Media.prototype.pause = function() {

+    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);

+};

+

+/**

+ * Get duration of an audio file.

+ * The duration is only set for audio that is playing, paused or stopped.

+ *

+ * @return      duration or -1 if not known.

+ */

+Media.prototype.getDuration = function() {

+    return this._duration;

+};

+

+/**

+ * Get position of audio.

+ */

+Media.prototype.getCurrentPosition = function(success, fail) {

+    var me = this;

+    exec(function(p) {

+        me._position = p;

+        success(p);

+    }, fail, "Media", "getCurrentPositionAudio", [this.id]);

+};

+

+/**

+ * Start recording audio file.

+ */

+Media.prototype.startRecord = function() {

+    exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);

+};

+

+/**

+ * Stop recording audio file.

+ */

+Media.prototype.stopRecord = function() {

+    exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);

+};

+

+/**

+ * Release the resources.

+ */

+Media.prototype.release = function() {

+    exec(null, this.errorCallback, "Media", "release", [this.id]);

+};

+

+/**

+ * Adjust the volume.

+ */

+Media.prototype.setVolume = function(volume) {

+    exec(null, null, "Media", "setVolume", [this.id, volume]);

+};

+

+/**

+ * Audio has status update.

+ * PRIVATE

+ *

+ * @param id            The media object id (string)

+ * @param msgType       The 'type' of update this is

+ * @param value         Use of value is determined by the msgType

+ */

+Media.onStatus = function(id, msgType, value) {

+

+    var media = mediaObjects[id];

+

+    if(media) {

+        switch(msgType) {

+            case Media.MEDIA_STATE :

+                media.statusCallback && media.statusCallback(value);

+                if(value == Media.MEDIA_STOPPED) {

+                    media.successCallback && media.successCallback();

+                }

+                break;

+            case Media.MEDIA_DURATION :

+                media._duration = value;

+                break;

+            case Media.MEDIA_ERROR :

+                media.errorCallback && media.errorCallback(value);

+                break;

+            case Media.MEDIA_POSITION :

+                media._position = Number(value);

+                break;

+            default :

+                console.error && console.error("Unhandled Media.onStatus :: " + msgType);

+                break;

+        }

+    }

+    else {

+         console.error && console.error("Received Media.onStatus callback for unknown media :: " + id);

+    }

+

+};

+

+module.exports = Media;

+

+});

+

+// file: lib/common/plugin/MediaError.js

+define("cordova/plugin/MediaError", function(require, exports, module) {

+

+/**

+ * This class contains information about any Media errors.

+*/

+/*

+ According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror

+ We should never be creating these objects, we should just implement the interface

+ which has 1 property for an instance, 'code'

+

+ instead of doing :

+    errorCallbackFunction( new MediaError(3,'msg') );

+we should simply use a literal :

+    errorCallbackFunction( {'code':3} );

+ */

+

+ var _MediaError = window.MediaError;

+

+

+if(!_MediaError) {

+    window.MediaError = _MediaError = function(code, msg) {

+        this.code = (typeof code != 'undefined') ? code : null;

+        this.message = msg || ""; // message is NON-standard! do not use!

+    };

+}

+

+_MediaError.MEDIA_ERR_NONE_ACTIVE    = _MediaError.MEDIA_ERR_NONE_ACTIVE    || 0;

+_MediaError.MEDIA_ERR_ABORTED        = _MediaError.MEDIA_ERR_ABORTED        || 1;

+_MediaError.MEDIA_ERR_NETWORK        = _MediaError.MEDIA_ERR_NETWORK        || 2;

+_MediaError.MEDIA_ERR_DECODE         = _MediaError.MEDIA_ERR_DECODE         || 3;

+_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;

+// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.

+// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes

+_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;

+

+module.exports = _MediaError;

+

+});

+

+// file: lib/common/plugin/MediaFile.js

+define("cordova/plugin/MediaFile", function(require, exports, module) {

+

+var utils = require('cordova/utils'),

+    exec = require('cordova/exec'),

+    File = require('cordova/plugin/File'),

+    CaptureError = require('cordova/plugin/CaptureError');

+/**

+ * Represents a single file.

+ *

+ * name {DOMString} name of the file, without path information

+ * fullPath {DOMString} the full path of the file, including the name

+ * type {DOMString} mime type

+ * lastModifiedDate {Date} last modified date

+ * size {Number} size of the file in bytes

+ */

+var MediaFile = function(name, fullPath, type, lastModifiedDate, size){

+    MediaFile.__super__.constructor.apply(this, arguments);

+};

+

+utils.extend(MediaFile, File);

+

+/**

+ * Request capture format data for a specific file and type

+ *

+ * @param {Function} successCB

+ * @param {Function} errorCB

+ */

+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {

+    if (typeof this.fullPath === "undefined" || this.fullPath === null) {

+        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));

+    } else {

+        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);

+    }

+};

+

+module.exports = MediaFile;

+

+});

+

+// file: lib/common/plugin/MediaFileData.js

+define("cordova/plugin/MediaFileData", function(require, exports, module) {

+

+/**

+ * MediaFileData encapsulates format information of a media file.

+ *

+ * @param {DOMString} codecs

+ * @param {long} bitrate

+ * @param {long} height

+ * @param {long} width

+ * @param {float} duration

+ */

+var MediaFileData = function(codecs, bitrate, height, width, duration){

+    this.codecs = codecs || null;

+    this.bitrate = bitrate || 0;

+    this.height = height || 0;

+    this.width = width || 0;

+    this.duration = duration || 0;

+};

+

+module.exports = MediaFileData;

+

+});

+

+// file: lib/common/plugin/Metadata.js

+define("cordova/plugin/Metadata", function(require, exports, module) {

+

+/**

+ * Information about the state of the file or directory

+ *

+ * {Date} modificationTime (readonly)

+ */

+var Metadata = function(time) {

+    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);

+};

+

+module.exports = Metadata;

+

+});

+

+// file: lib/common/plugin/Position.js

+define("cordova/plugin/Position", function(require, exports, module) {

+

+var Coordinates = require('cordova/plugin/Coordinates');

+

+var Position = function(coords, timestamp) {

+    if (coords) {

+        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);

+    } else {

+        this.coords = new Coordinates();

+    }

+    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();

+};

+

+module.exports = Position;

+

+});

+

+// file: lib/common/plugin/PositionError.js

+define("cordova/plugin/PositionError", function(require, exports, module) {

+

+/**

+ * Position error object

+ *

+ * @constructor

+ * @param code

+ * @param message

+ */

+var PositionError = function(code, message) {

+    this.code = code || null;

+    this.message = message || '';

+};

+

+PositionError.PERMISSION_DENIED = 1;

+PositionError.POSITION_UNAVAILABLE = 2;

+PositionError.TIMEOUT = 3;

+

+module.exports = PositionError;

+

+});

+

+// file: lib/common/plugin/ProgressEvent.js

+define("cordova/plugin/ProgressEvent", function(require, exports, module) {

+

+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill

+// Feature test: See if we can instantiate a native ProgressEvent;

+// if so, use that approach,

+// otherwise fill-in with our own implementation.

+//

+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.

+var ProgressEvent = (function() {

+    /*

+    var createEvent = function(data) {

+        var event = document.createEvent('Events');

+        event.initEvent('ProgressEvent', false, false);

+        if (data) {

+            for (var i in data) {

+                if (data.hasOwnProperty(i)) {

+                    event[i] = data[i];

+                }

+            }

+            if (data.target) {

+                // TODO: cannot call <some_custom_object>.dispatchEvent

+                // need to first figure out how to implement EventTarget

+            }

+        }

+        return event;

+    };

+    try {

+        var ev = createEvent({type:"abort",target:document});

+        return function ProgressEvent(type, data) {

+            data.type = type;

+            return createEvent(data);

+        };

+    } catch(e){

+    */

+        return function ProgressEvent(type, dict) {

+            this.type = type;

+            this.bubbles = false;

+            this.cancelBubble = false;

+            this.cancelable = false;

+            this.lengthComputable = false;

+            this.loaded = dict && dict.loaded ? dict.loaded : 0;

+            this.total = dict && dict.total ? dict.total : 0;

+            this.target = dict && dict.target ? dict.target : null;

+        };

+    //}

+})();

+

+module.exports = ProgressEvent;

+

+});

+

+// file: lib/common/plugin/accelerometer.js

+define("cordova/plugin/accelerometer", function(require, exports, module) {

+

+/**

+ * This class provides access to device accelerometer data.

+ * @constructor

+ */

+var argscheck = require('cordova/argscheck'),

+    utils = require("cordova/utils"),

+    exec = require("cordova/exec"),

+    Acceleration = require('cordova/plugin/Acceleration');

+

+// Is the accel sensor running?

+var running = false;

+

+// Keeps reference to watchAcceleration calls.

+var timers = {};

+

+// Array of listeners; used to keep track of when we should call start and stop.

+var listeners = [];

+

+// Last returned acceleration object from native

+var accel = null;

+

+// Tells native to start.

+function start() {

+    exec(function(a) {

+        var tempListeners = listeners.slice(0);

+        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);

+        for (var i = 0, l = tempListeners.length; i < l; i++) {

+            tempListeners[i].win(accel);

+        }

+    }, function(e) {

+        var tempListeners = listeners.slice(0);

+        for (var i = 0, l = tempListeners.length; i < l; i++) {

+            tempListeners[i].fail(e);

+        }

+    }, "Accelerometer", "start", []);

+    running = true;

+}

+

+// Tells native to stop.

+function stop() {

+    exec(null, null, "Accelerometer", "stop", []);

+    running = false;

+}

+

+// Adds a callback pair to the listeners array

+function createCallbackPair(win, fail) {

+    return {win:win, fail:fail};

+}

+

+// Removes a win/fail listener pair from the listeners array

+function removeListeners(l) {

+    var idx = listeners.indexOf(l);

+    if (idx > -1) {

+        listeners.splice(idx, 1);

+        if (listeners.length === 0) {

+            stop();

+        }

+    }

+}

+

+var accelerometer = {

+    /**

+     * Asynchronously acquires the current acceleration.

+     *

+     * @param {Function} successCallback    The function to call when the acceleration data is available

+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)

+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)

+     */

+    getCurrentAcceleration: function(successCallback, errorCallback, options) {

+        argscheck.checkArgs('fFO', 'accelerometer.getCurrentAcceleration', arguments);

+

+        var p;

+        var win = function(a) {

+            removeListeners(p);

+            successCallback(a);

+        };

+        var fail = function(e) {

+            removeListeners(p);

+            errorCallback && errorCallback(e);

+        };

+

+        p = createCallbackPair(win, fail);

+        listeners.push(p);

+

+        if (!running) {

+            start();

+        }

+    },

+

+    /**

+     * Asynchronously acquires the acceleration repeatedly at a given interval.

+     *

+     * @param {Function} successCallback    The function to call each time the acceleration data is available

+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)

+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)

+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.

+     */

+    watchAcceleration: function(successCallback, errorCallback, options) {

+        argscheck.checkArgs('fFO', 'accelerometer.watchAcceleration', arguments);

+        // Default interval (10 sec)

+        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;

+

+        // Keep reference to watch id, and report accel readings as often as defined in frequency

+        var id = utils.createUUID();

+

+        var p = createCallbackPair(function(){}, function(e) {

+            removeListeners(p);

+            errorCallback && errorCallback(e);

+        });

+        listeners.push(p);

+

+        timers[id] = {

+            timer:window.setInterval(function() {

+                if (accel) {

+                    successCallback(accel);

+                }

+            }, frequency),

+            listeners:p

+        };

+

+        if (running) {

+            // If we're already running then immediately invoke the success callback

+            // but only if we have retrieved a value, sample code does not check for null ...

+            if (accel) {

+                successCallback(accel);

+            }

+        } else {

+            start();

+        }

+

+        return id;

+    },

+

+    /**

+     * Clears the specified accelerometer watch.

+     *

+     * @param {String} id       The id of the watch returned from #watchAcceleration.

+     */

+    clearWatch: function(id) {

+        // Stop javascript timer & remove from timer list

+        if (id && timers[id]) {

+            window.clearInterval(timers[id].timer);

+            removeListeners(timers[id].listeners);

+            delete timers[id];

+        }

+    }

+};

+

+module.exports = accelerometer;

+

+});

+

+// file: lib/common/plugin/accelerometer/symbols.js

+define("cordova/plugin/accelerometer/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.defaults('cordova/plugin/Acceleration', 'Acceleration');

+modulemapper.defaults('cordova/plugin/accelerometer', 'navigator.accelerometer');

+

+});

+

+// file: lib/common/plugin/battery.js

+define("cordova/plugin/battery", function(require, exports, module) {

+

+/**

+ * This class contains information about the current battery status.

+ * @constructor

+ */

+var cordova = require('cordova'),

+    exec = require('cordova/exec');

+

+function handlers() {

+  return battery.channels.batterystatus.numHandlers +

+         battery.channels.batterylow.numHandlers +

+         battery.channels.batterycritical.numHandlers;

+}

+

+var Battery = function() {

+    this._level = null;

+    this._isPlugged = null;

+    // Create new event handlers on the window (returns a channel instance)

+    this.channels = {

+      batterystatus:cordova.addWindowEventHandler("batterystatus"),

+      batterylow:cordova.addWindowEventHandler("batterylow"),

+      batterycritical:cordova.addWindowEventHandler("batterycritical")

+    };

+    for (var key in this.channels) {

+        this.channels[key].onHasSubscribersChange = Battery.onHasSubscribersChange;

+    }

+};

+/**

+ * Event handlers for when callbacks get registered for the battery.

+ * Keep track of how many handlers we have so we can start and stop the native battery listener

+ * appropriately (and hopefully save on battery life!).

+ */

+Battery.onHasSubscribersChange = function() {

+  // If we just registered the first handler, make sure native listener is started.

+  if (this.numHandlers === 1 && handlers() === 1) {

+      exec(battery._status, battery._error, "Battery", "start", []);

+  } else if (handlers() === 0) {

+      exec(null, null, "Battery", "stop", []);

+  }

+};

+

+/**

+ * Callback for battery status

+ *

+ * @param {Object} info            keys: level, isPlugged

+ */

+Battery.prototype._status = function(info) {

+    if (info) {

+        var me = battery;

+    var level = info.level;

+        if (me._level !== level || me._isPlugged !== info.isPlugged) {

+            // Fire batterystatus event

+            cordova.fireWindowEvent("batterystatus", info);

+

+            // Fire low battery event

+            if (level === 20 || level === 5) {

+                if (level === 20) {

+                    cordova.fireWindowEvent("batterylow", info);

+                }

+                else {

+                    cordova.fireWindowEvent("batterycritical", info);

+                }

+            }

+        }

+        me._level = level;

+        me._isPlugged = info.isPlugged;

+    }

+};

+

+/**

+ * Error callback for battery start

+ */

+Battery.prototype._error = function(e) {

+    console.log("Error initializing Battery: " + e);

+};

+

+var battery = new Battery();

+

+module.exports = battery;

+

+});

+

+// file: lib/common/plugin/battery/symbols.js

+define("cordova/plugin/battery/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.defaults('cordova/plugin/battery', 'navigator.battery');

+

+});

+

+// file: lib/common/plugin/camera/symbols.js

+define("cordova/plugin/camera/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.defaults('cordova/plugin/Camera', 'navigator.camera');

+modulemapper.defaults('cordova/plugin/CameraConstants', 'Camera');

+modulemapper.defaults('cordova/plugin/CameraPopoverOptions', 'CameraPopoverOptions');

+

+});

+

+// 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/capture/symbols.js

+define("cordova/plugin/capture/symbols", function(require, exports, module) {

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/CaptureError', 'CaptureError');

+modulemapper.clobbers('cordova/plugin/CaptureAudioOptions', 'CaptureAudioOptions');

+modulemapper.clobbers('cordova/plugin/CaptureImageOptions', 'CaptureImageOptions');

+modulemapper.clobbers('cordova/plugin/CaptureVideoOptions', 'CaptureVideoOptions');

+modulemapper.clobbers('cordova/plugin/ConfigurationData', 'ConfigurationData');

+modulemapper.clobbers('cordova/plugin/MediaFile', 'MediaFile');

+modulemapper.clobbers('cordova/plugin/MediaFileData', 'MediaFileData');

+modulemapper.clobbers('cordova/plugin/capture', 'navigator.device.capture');

+

+});

+

+// file: lib/common/plugin/compass.js

+define("cordova/plugin/compass", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    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) {

+            argscheck.checkArgs('fFO', 'compass.getCurrentHeading', arguments);

+

+            var win = function(result) {

+                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);

+                successCallback(ch);

+            };

+            var fail = errorCallback && 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) {

+            argscheck.checkArgs('fFO', 'compass.watchHeading', arguments);

+            // Default interval (100 msec)

+            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;

+            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;

+

+            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/compass/symbols.js

+define("cordova/plugin/compass/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/CompassHeading', 'CompassHeading');

+modulemapper.clobbers('cordova/plugin/CompassError', 'CompassError');

+modulemapper.clobbers('cordova/plugin/compass', 'navigator.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 = logger.format.apply(logger.format, [].slice.call(arguments, 1));

+    console.log("ASSERT: " + message);

+};

+

+//------------------------------------------------------------------------------

+console.clear = function() {};

+

+//------------------------------------------------------------------------------

+console.dir = function(object) {

+    console.log("%o", object);

+};

+

+//------------------------------------------------------------------------------

+console.dirxml = function(node) {

+    console.log(node.innerHTML);

+};

+

+//------------------------------------------------------------------------------

+console.trace = noop;

+

+//------------------------------------------------------------------------------

+console.group = console.log;

+

+//------------------------------------------------------------------------------

+console.groupCollapsed = console.log;

+

+//------------------------------------------------------------------------------

+console.groupEnd = noop;

+

+//------------------------------------------------------------------------------

+console.time = function(name) {

+    Timers[name] = new Date().valueOf();

+};

+

+//------------------------------------------------------------------------------

+console.timeEnd = function(name) {

+    var timeStart = Timers[name];

+    if (!timeStart) {

+        console.warn("unknown timer: " + name);

+        return;

+    }

+

+    var timeElapsed = new Date().valueOf() - timeStart;

+    console.log(name + ": " + timeElapsed + "ms");

+};

+

+//------------------------------------------------------------------------------

+console.timeStamp = noop;

+

+//------------------------------------------------------------------------------

+console.profile = noop;

+

+//------------------------------------------------------------------------------

+console.profileEnd = noop;

+

+//------------------------------------------------------------------------------

+console.count = noop;

+

+//------------------------------------------------------------------------------

+console.exception = console.log;

+

+//------------------------------------------------------------------------------

+console.table = function(data, columns) {

+    console.log("%o", data);

+};

+

+//------------------------------------------------------------------------------

+// return a new function that calls both functions passed as args

+//------------------------------------------------------------------------------

+function wrappedOrigCall(orgFunc, newFunc) {

+    return function() {

+        var args = [].slice.call(arguments);

+        try { orgFunc.apply(WinConsole, args); } catch (e) {}

+        try { newFunc.apply(console,    args); } catch (e) {}

+    };

+}

+

+//------------------------------------------------------------------------------

+// For every function that exists in the original console object, that

+// also exists in the new console object, wrap the new console method

+// with one that calls both

+//------------------------------------------------------------------------------

+for (var key in console) {

+    if (typeof WinConsole[key] == "function") {

+        console[key] = wrappedOrigCall(WinConsole[key], console[key]);

+    }

+}

+

+});

+

+// file: lib/common/plugin/contacts.js

+define("cordova/plugin/contacts", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    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) {

+        argscheck.checkArgs('afFO', 'contacts.find', arguments);

+        if (!fields.length) {

+            errorCB && errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));

+        } else {

+            var win = function(result) {

+                var cs = [];

+                for (var i = 0, l = result.length; i < l; i++) {

+                    cs.push(contacts.create(result[i]));

+                }

+                successCB(cs);

+            };

+            exec(win, errorCB, "Contacts", "search", [fields, options]);

+        }

+    },

+

+    /**

+     * This function creates a new contact, but it does not persist the contact

+     * to device storage. To persist the contact to device storage, invoke

+     * contact.save().

+     * @param properties an object whose properties will be examined to create a new Contact

+     * @returns new Contact object

+     */

+    create:function(properties) {

+        argscheck.checkArgs('O', 'contacts.create', arguments);

+        var contact = new Contact();

+        for (var i in properties) {

+            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {

+                contact[i] = properties[i];

+            }

+        }

+        return contact;

+    }

+};

+

+module.exports = contacts;

+

+});

+

+// file: lib/common/plugin/contacts/symbols.js

+define("cordova/plugin/contacts/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/contacts', 'navigator.contacts');

+modulemapper.clobbers('cordova/plugin/Contact', 'Contact');

+modulemapper.clobbers('cordova/plugin/ContactAddress', 'ContactAddress');

+modulemapper.clobbers('cordova/plugin/ContactError', 'ContactError');

+modulemapper.clobbers('cordova/plugin/ContactField', 'ContactField');

+modulemapper.clobbers('cordova/plugin/ContactFindOptions', 'ContactFindOptions');

+modulemapper.clobbers('cordova/plugin/ContactName', 'ContactName');

+modulemapper.clobbers('cordova/plugin/ContactOrganization', 'ContactOrganization');

+

+});

+

+// file: lib/common/plugin/device.js

+define("cordova/plugin/device", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    channel = require('cordova/channel'),

+    utils = require('cordova/utils'),

+    exec = require('cordova/exec');

+

+// Tell cordova channel to wait on the CordovaInfoReady event

+channel.waitForInitialization('onCordovaInfoReady');

+

+/**

+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the

+ * phone, etc.

+ * @constructor

+ */

+function Device() {

+    this.available = false;

+    this.platform = null;

+    this.version = null;

+    this.uuid = null;

+    this.cordova = null;

+    this.model = null;

+

+    var me = this;

+

+    channel.onCordovaReady.subscribe(function() {

+        me.getInfo(function(info) {

+            var buildLabel = info.cordova;

+            if (buildLabel != CORDOVA_JS_BUILD_LABEL) {

+                buildLabel += ' JS=' + CORDOVA_JS_BUILD_LABEL;

+            }

+            me.available = true;

+            me.platform = info.platform;

+            me.version = info.version;

+            me.uuid = info.uuid;

+            me.cordova = buildLabel;

+            me.model = info.model;

+            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) {

+    argscheck.checkArgs('fF', 'Device.getInfo', arguments);

+    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);

+};

+

+module.exports = new Device();

+

+});

+

+// file: lib/common/plugin/device/symbols.js

+define("cordova/plugin/device/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/device', 'device');

+

+});

+

+// file: lib/common/plugin/echo.js

+define("cordova/plugin/echo", function(require, exports, module) {

+

+var exec = require('cordova/exec'),

+    utils = require('cordova/utils');

+

+/**

+ * Sends the given message through exec() to the Echo plugin, which sends it back to the successCallback.

+ * @param successCallback  invoked with a FileSystem object

+ * @param errorCallback  invoked if error occurs retrieving file system

+ * @param message  The string to be echoed.

+ * @param forceAsync  Whether to force an async return value (for testing native->js bridge).

+ */

+module.exports = function(successCallback, errorCallback, message, forceAsync) {

+    var action = 'echo';

+    var messageIsMultipart = (utils.typeName(message) == "Array");

+    var args = messageIsMultipart ? message : [message];

+

+    if (utils.typeName(message) == 'ArrayBuffer') {

+        if (forceAsync) {

+            console.warn('Cannot echo ArrayBuffer with forced async, falling back to sync.');

+        }

+        action += 'ArrayBuffer';

+    } else if (messageIsMultipart) {

+        if (forceAsync) {

+            console.warn('Cannot echo MultiPart Array with forced async, falling back to sync.');

+        }

+        action += 'MultiPart';

+    } else if (forceAsync) {

+        action += 'Async';

+    }

+

+    exec(successCallback, errorCallback, "Echo", action, args);

+};

+

+

+});

+

+// file: lib/common/plugin/file/symbols.js

+define("cordova/plugin/file/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper'),

+    symbolshelper = require('cordova/plugin/file/symbolshelper');

+

+symbolshelper(modulemapper.defaults);

+

+});

+

+// file: lib/common/plugin/file/symbolshelper.js

+define("cordova/plugin/file/symbolshelper", function(require, exports, module) {

+

+module.exports = function(exportFunc) {

+    exportFunc('cordova/plugin/DirectoryEntry', 'DirectoryEntry');

+    exportFunc('cordova/plugin/DirectoryReader', 'DirectoryReader');

+    exportFunc('cordova/plugin/Entry', 'Entry');

+    exportFunc('cordova/plugin/File', 'File');

+    exportFunc('cordova/plugin/FileEntry', 'FileEntry');

+    exportFunc('cordova/plugin/FileError', 'FileError');

+    exportFunc('cordova/plugin/FileReader', 'FileReader');

+    exportFunc('cordova/plugin/FileSystem', 'FileSystem');

+    exportFunc('cordova/plugin/FileUploadOptions', 'FileUploadOptions');

+    exportFunc('cordova/plugin/FileUploadResult', 'FileUploadResult');

+    exportFunc('cordova/plugin/FileWriter', 'FileWriter');

+    exportFunc('cordova/plugin/Flags', 'Flags');

+    exportFunc('cordova/plugin/LocalFileSystem', 'LocalFileSystem');

+    exportFunc('cordova/plugin/Metadata', 'Metadata');

+    exportFunc('cordova/plugin/ProgressEvent', 'ProgressEvent');

+    exportFunc('cordova/plugin/requestFileSystem', 'requestFileSystem');

+    exportFunc('cordova/plugin/resolveLocalFileSystemURI', 'resolveLocalFileSystemURI');

+};

+

+});

+

+// file: lib/common/plugin/filetransfer/symbols.js

+define("cordova/plugin/filetransfer/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/FileTransfer', 'FileTransfer');

+modulemapper.clobbers('cordova/plugin/FileTransferError', 'FileTransferError');

+

+});

+

+// file: lib/common/plugin/geolocation.js

+define("cordova/plugin/geolocation", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    utils = require('cordova/utils'),

+    exec = require('cordova/exec'),

+    PositionError = require('cordova/plugin/PositionError'),

+    Position = require('cordova/plugin/Position');

+

+var timers = {};   // list of timers in use

+

+// Returns default params, overrides if provided with values

+function parseParameters(options) {

+    var opt = {

+        maximumAge: 0,

+        enableHighAccuracy: false,

+        timeout: Infinity

+    };

+

+    if (options) {

+        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {

+            opt.maximumAge = options.maximumAge;

+        }

+        if (options.enableHighAccuracy !== undefined) {

+            opt.enableHighAccuracy = options.enableHighAccuracy;

+        }

+        if (options.timeout !== undefined && !isNaN(options.timeout)) {

+            if (options.timeout < 0) {

+                opt.timeout = 0;

+            } else {

+                opt.timeout = options.timeout;

+            }

+        }

+    }

+

+    return opt;

+}

+

+// Returns a timeout failure, closed over a specified timeout value and error callback.

+function createTimeout(errorCallback, timeout) {

+    var t = setTimeout(function() {

+        clearTimeout(t);

+        t = null;

+        errorCallback({

+            code:PositionError.TIMEOUT,

+            message:"Position retrieval timed out."

+        });

+    }, timeout);

+    return t;

+}

+

+var geolocation = {

+    lastPosition:null, // reference to last known (cached) position returned

+    /**

+   * Asynchronously acquires the current position.

+   *

+   * @param {Function} successCallback    The function to call when the position data is available

+   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)

+   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)

+   */

+    getCurrentPosition:function(successCallback, errorCallback, options) {

+        argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments);

+        options = parseParameters(options);

+

+        // Timer var that will fire an error callback if no position is retrieved from native

+        // before the "timeout" param provided expires

+        var timeoutTimer = {timer:null};

+

+        var win = function(p) {

+            clearTimeout(timeoutTimer.timer);

+            if (!(timeoutTimer.timer)) {

+                // Timeout already happened, or native fired error callback for

+                // this geo request.

+                // Don't continue with success callback.

+                return;

+            }

+            var pos = new Position(

+                {

+                    latitude:p.latitude,

+                    longitude:p.longitude,

+                    altitude:p.altitude,

+                    accuracy:p.accuracy,

+                    heading:p.heading,

+                    velocity:p.velocity,

+                    altitudeAccuracy:p.altitudeAccuracy

+                },

+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))

+            );

+            geolocation.lastPosition = pos;

+            successCallback(pos);

+        };

+        var fail = function(e) {

+            clearTimeout(timeoutTimer.timer);

+            timeoutTimer.timer = null;

+            var err = new PositionError(e.code, e.message);

+            if (errorCallback) {

+                errorCallback(err);

+            }

+        };

+

+        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just

+        // fire the success callback with the cached position.

+        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {

+            successCallback(geolocation.lastPosition);

+        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.

+        } else if (options.timeout === 0) {

+            fail({

+                code:PositionError.TIMEOUT,

+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceeds provided PositionOptions' maximumAge parameter."

+            });

+        // Otherwise we have to call into native to retrieve a position.

+        } else {

+            if (options.timeout !== Infinity) {

+                // If the timeout value was not set to Infinity (default), then

+                // set up a timeout function that will fire the error callback

+                // if no successful position was retrieved before timeout expired.

+                timeoutTimer.timer = createTimeout(fail, options.timeout);

+            } else {

+                // This is here so the check in the win function doesn't mess stuff up

+                // may seem weird but this guarantees timeoutTimer is

+                // always truthy before we call into native

+                timeoutTimer.timer = true;

+            }

+            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);

+        }

+        return timeoutTimer;

+    },

+    /**

+     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,

+     * the successCallback is called with the new location.

+     *

+     * @param {Function} successCallback    The function to call each time the location data is available

+     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)

+     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)

+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.

+     */

+    watchPosition:function(successCallback, errorCallback, options) {

+        argscheck.checkArgs('fFO', 'geolocation.getCurrentPosition', arguments);

+        options = parseParameters(options);

+

+        var id = utils.createUUID();

+

+        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition

+        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);

+

+        var fail = function(e) {

+            clearTimeout(timers[id].timer);

+            var err = new PositionError(e.code, e.message);

+            if (errorCallback) {

+                errorCallback(err);

+            }

+        };

+

+        var win = function(p) {

+            clearTimeout(timers[id].timer);

+            if (options.timeout !== Infinity) {

+                timers[id].timer = createTimeout(fail, options.timeout);

+            }

+            var pos = new Position(

+                {

+                    latitude:p.latitude,

+                    longitude:p.longitude,

+                    altitude:p.altitude,

+                    accuracy:p.accuracy,

+                    heading:p.heading,

+                    velocity:p.velocity,

+                    altitudeAccuracy:p.altitudeAccuracy

+                },

+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))

+            );

+            geolocation.lastPosition = pos;

+            successCallback(pos);

+        };

+

+        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);

+

+        return id;

+    },

+    /**

+     * Clears the specified heading watch.

+     *

+     * @param {String} id       The ID of the watch returned from #watchPosition

+     */

+    clearWatch:function(id) {

+        if (id && timers[id] !== undefined) {

+            clearTimeout(timers[id].timer);

+            timers[id].timer = false;

+            exec(null, null, "Geolocation", "clearWatch", [id]);

+        }

+    }

+};

+

+module.exports = geolocation;

+

+});

+

+// file: lib/common/plugin/geolocation/symbols.js

+define("cordova/plugin/geolocation/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.defaults('cordova/plugin/geolocation', 'navigator.geolocation');

+modulemapper.clobbers('cordova/plugin/PositionError', 'PositionError');

+modulemapper.clobbers('cordova/plugin/Position', 'Position');

+modulemapper.clobbers('cordova/plugin/Coordinates', 'Coordinates');

+

+});

+

+// file: lib/common/plugin/globalization.js

+define("cordova/plugin/globalization", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    exec = require('cordova/exec'),

+    GlobalizationError = require('cordova/plugin/GlobalizationError');

+

+var globalization = {

+

+/**

+* Returns the string identifier for the client's current language.

+* It returns the language identifier string to the successCB callback with a

+* properties object as a parameter. If there is an error getting the language,

+* then the errorCB callback is invoked.

+*

+* @param {Function} successCB

+* @param {Function} errorCB

+*

+* @return Object.value {String}: The language identifier

+*

+* @error GlobalizationError.UNKNOWN_ERROR

+*

+* Example

+*    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},

+*                                function () {});

+*/

+getPreferredLanguage:function(successCB, failureCB) {

+    argscheck.checkArgs('fF', 'Globalization.getPreferredLanguage', arguments);

+    exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);

+},

+

+/**

+* Returns the string identifier for the client's current locale setting.

+* It returns the locale identifier string to the successCB callback with a

+* properties object as a parameter. If there is an error getting the locale,

+* then the errorCB callback is invoked.

+*

+* @param {Function} successCB

+* @param {Function} errorCB

+*

+* @return Object.value {String}: The locale identifier

+*

+* @error GlobalizationError.UNKNOWN_ERROR

+*

+* Example

+*    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},

+*                                function () {});

+*/

+getLocaleName:function(successCB, failureCB) {

+    argscheck.checkArgs('fF', 'Globalization.getLocaleName', arguments);

+    exec(successCB, failureCB, "Globalization","getLocaleName", []);

+},

+

+

+/**

+* Returns a date formatted as a string according to the client's user preferences and

+* calendar using the time zone of the client. It returns the formatted date string to the

+* successCB callback with a properties object as a parameter. If there is an error

+* formatting the date, then the errorCB callback is invoked.

+*

+* The defaults are: formatLenght="short" and selector="date and time"

+*

+* @param {Date} date

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            formatLength {String}: 'short', 'medium', 'long', or 'full'

+*            selector {String}: 'date', 'time', or 'date and time'

+*

+* @return Object.value {String}: The localized date string

+*

+* @error GlobalizationError.FORMATTING_ERROR

+*

+* Example

+*    globalization.dateToString(new Date(),

+*                function (date) {alert('date:' + date.value + '\n');},

+*                function (errorCode) {alert(errorCode);},

+*                {formatLength:'short'});

+*/

+dateToString:function(date, successCB, failureCB, options) {

+    argscheck.checkArgs('dfFO', 'Globalization.dateToString', arguments);

+    var dateValue = date.valueOf();

+    exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);

+},

+

+

+/**

+* Parses a date formatted as a string according to the client's user

+* preferences and calendar using the time zone of the client and returns

+* the corresponding date object. It returns the date to the successCB

+* callback with a properties object as a parameter. If there is an error

+* parsing the date string, then the errorCB callback is invoked.

+*

+* The defaults are: formatLength="short" and selector="date and time"

+*

+* @param {String} dateString

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            formatLength {String}: 'short', 'medium', 'long', or 'full'

+*            selector {String}: 'date', 'time', or 'date and time'

+*

+* @return    Object.year {Number}: The four digit year

+*            Object.month {Number}: The month from (0 - 11)

+*            Object.day {Number}: The day from (1 - 31)

+*            Object.hour {Number}: The hour from (0 - 23)

+*            Object.minute {Number}: The minute from (0 - 59)

+*            Object.second {Number}: The second from (0 - 59)

+*            Object.millisecond {Number}: The milliseconds (from 0 - 999),

+*                                        not available on all platforms

+*

+* @error GlobalizationError.PARSING_ERROR

+*

+* Example

+*    globalization.stringToDate('4/11/2011',

+*                function (date) { alert('Month:' + date.month + '\n' +

+*                    'Day:' + date.day + '\n' +

+*                    'Year:' + date.year + '\n');},

+*                function (errorCode) {alert(errorCode);},

+*                {selector:'date'});

+*/

+stringToDate:function(dateString, successCB, failureCB, options) {

+    argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);

+    exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);

+},

+

+

+/**

+* Returns a pattern string for formatting and parsing dates according to the client's

+* user preferences. It returns the pattern to the successCB callback with a

+* properties object as a parameter. If there is an error obtaining the pattern,

+* then the errorCB callback is invoked.

+*

+* The defaults are: formatLength="short" and selector="date and time"

+*

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            formatLength {String}: 'short', 'medium', 'long', or 'full'

+*            selector {String}: 'date', 'time', or 'date and time'

+*

+* @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.

+*                                    The patterns follow Unicode Technical Standard #35

+*                                    http://unicode.org/reports/tr35/tr35-4.html

+*            Object.timezone {String}: The abbreviated name of the time zone on the client

+*            Object.utc_offset {Number}: The current difference in seconds between the client's

+*                                        time zone and coordinated universal time.

+*            Object.dst_offset {Number}: The current daylight saving time offset in seconds

+*                                        between the client's non-daylight saving's time zone

+*                                        and the client's daylight saving's time zone.

+*

+* @error GlobalizationError.PATTERN_ERROR

+*

+* Example

+*    globalization.getDatePattern(

+*                function (date) {alert('pattern:' + date.pattern + '\n');},

+*                function () {},

+*                {formatLength:'short'});

+*/

+getDatePattern:function(successCB, failureCB, options) {

+    argscheck.checkArgs('fFO', 'Globalization.getDatePattern', arguments);

+    exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);

+},

+

+

+/**

+* Returns an array of either the names of the months or days of the week

+* according to the client's user preferences and calendar. It returns the array of names to the

+* successCB callback with a properties object as a parameter. If there is an error obtaining the

+* names, then the errorCB callback is invoked.

+*

+* The defaults are: type="wide" and item="months"

+*

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            type {String}: 'narrow' or 'wide'

+*            item {String}: 'months', or 'days'

+*

+* @return Object.value {Array{String}}: The array of names starting from either

+*                                        the first month in the year or the

+*                                        first day of the week.

+* @error GlobalizationError.UNKNOWN_ERROR

+*

+* Example

+*    globalization.getDateNames(function (names) {

+*        for(var i = 0; i < names.value.length; i++) {

+*            alert('Month:' + names.value[i] + '\n');}},

+*        function () {});

+*/

+getDateNames:function(successCB, failureCB, options) {

+    argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);

+    exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);

+},

+

+/**

+* Returns whether daylight savings time is in effect for a given date using the client's

+* time zone and calendar. It returns whether or not daylight savings time is in effect

+* to the successCB callback with a properties object as a parameter. If there is an error

+* reading the date, then the errorCB callback is invoked.

+*

+* @param {Date} date

+* @param {Function} successCB

+* @param {Function} errorCB

+*

+* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is

+*                                in effect for the given date and "false" indicate that it is not.

+*

+* @error GlobalizationError.UNKNOWN_ERROR

+*

+* Example

+*    globalization.isDayLightSavingsTime(new Date(),

+*                function (date) {alert('dst:' + date.dst + '\n');}

+*                function () {});

+*/

+isDayLightSavingsTime:function(date, successCB, failureCB) {

+    argscheck.checkArgs('dfF', 'Globalization.isDayLightSavingsTime', arguments);

+    var dateValue = date.valueOf();

+    exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);

+},

+

+/**

+* Returns the first day of the week according to the client's user preferences and calendar.

+* The days of the week are numbered starting from 1 where 1 is considered to be Sunday.

+* It returns the day to the successCB callback with a properties object as a parameter.

+* If there is an error obtaining the pattern, then the errorCB callback is invoked.

+*

+* @param {Function} successCB

+* @param {Function} errorCB

+*

+* @return Object.value {Number}: The number of the first day of the week.

+*

+* @error GlobalizationError.UNKNOWN_ERROR

+*

+* Example

+*    globalization.getFirstDayOfWeek(function (day)

+*                { alert('Day:' + day.value + '\n');},

+*                function () {});

+*/

+getFirstDayOfWeek:function(successCB, failureCB) {

+    argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments);

+    exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);

+},

+

+

+/**

+* Returns a number formatted as a string according to the client's user preferences.

+* It returns the formatted number string to the successCB callback with a properties object as a

+* parameter. If there is an error formatting the number, then the errorCB callback is invoked.

+*

+* The defaults are: type="decimal"

+*

+* @param {Number} number

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            type {String}: 'decimal', "percent", or 'currency'

+*

+* @return Object.value {String}: The formatted number string.

+*

+* @error GlobalizationError.FORMATTING_ERROR

+*

+* Example

+*    globalization.numberToString(3.25,

+*                function (number) {alert('number:' + number.value + '\n');},

+*                function () {},

+*                {type:'decimal'});

+*/

+numberToString:function(number, successCB, failureCB, options) {

+    argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);

+    exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);

+},

+

+/**

+* Parses a number formatted as a string according to the client's user preferences and

+* returns the corresponding number. It returns the number to the successCB callback with a

+* properties object as a parameter. If there is an error parsing the number string, then

+* the errorCB callback is invoked.

+*

+* The defaults are: type="decimal"

+*

+* @param {String} numberString

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            type {String}: 'decimal', "percent", or 'currency'

+*

+* @return Object.value {Number}: The parsed number.

+*

+* @error GlobalizationError.PARSING_ERROR

+*

+* Example

+*    globalization.stringToNumber('1234.56',

+*                function (number) {alert('Number:' + number.value + '\n');},

+*                function () { alert('Error parsing number');});

+*/

+stringToNumber:function(numberString, successCB, failureCB, options) {

+    argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);

+    exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);

+},

+

+/**

+* Returns a pattern string for formatting and parsing numbers according to the client's user

+* preferences. It returns the pattern to the successCB callback with a properties object as a

+* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.

+*

+* The defaults are: type="decimal"

+*

+* @param {Function} successCB

+* @param {Function} errorCB

+* @param {Object} options {optional}

+*            type {String}: 'decimal', "percent", or 'currency'

+*

+* @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.

+*                                    The patterns follow Unicode Technical Standard #35.

+*                                    http://unicode.org/reports/tr35/tr35-4.html

+*            Object.symbol {String}: The symbol to be used when formatting and parsing

+*                                    e.g., percent or currency symbol.

+*            Object.fraction {Number}: The number of fractional digits to use when parsing and

+*                                    formatting numbers.

+*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.

+*            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.

+*            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.

+*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.

+*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.

+*

+* @error GlobalizationError.PATTERN_ERROR

+*

+* Example

+*    globalization.getNumberPattern(

+*                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},

+*                function () {});

+*/

+getNumberPattern:function(successCB, failureCB, options) {

+    argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments);

+    exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);

+},

+

+/**

+* Returns a pattern string for formatting and parsing currency values according to the client's

+* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a

+* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB

+* callback is invoked.

+*

+* @param {String} currencyCode

+* @param {Function} successCB

+* @param {Function} errorCB

+*

+* @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.

+*                                    The patterns follow Unicode Technical Standard #35

+*                                    http://unicode.org/reports/tr35/tr35-4.html

+*            Object.code {String}: The ISO 4217 currency code for the pattern.

+*            Object.fraction {Number}: The number of fractional digits to use when parsing and

+*                                    formatting currency.

+*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.

+*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.

+*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.

+*

+* @error GlobalizationError.FORMATTING_ERROR

+*

+* Example

+*    globalization.getCurrencyPattern('EUR',

+*                function (currency) {alert('Pattern:' + currency.pattern + '\n');}

+*                function () {});

+*/

+getCurrencyPattern:function(currencyCode, successCB, failureCB) {

+    argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);

+    exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);

+}

+

+};

+

+module.exports = globalization;

+

+});

+

+// file: lib/common/plugin/globalization/symbols.js

+define("cordova/plugin/globalization/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/globalization', 'navigator.globalization');

+modulemapper.clobbers('cordova/plugin/GlobalizationError', 'GlobalizationError');

+

+});

+

+// 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 UseLogger    = true;

+var Queued       = [];

+var DeviceReady  = false;

+var CurrentLevel;

+

+var originalConsole = console;

+

+/**

+ * Logging levels

+ */

+

+var Levels = [

+    "LOG",

+    "ERROR",

+    "WARN",

+    "INFO",

+    "DEBUG"

+];

+

+/*

+ * add the logging levels to the logger object and

+ * to a separate levelsMap object for testing

+ */

+

+var LevelsMap = {};

+for (var i=0; i<Levels.length; i++) {

+    var level = Levels[i];

+    LevelsMap[level] = i;

+    logger[level]    = level;

+}

+

+CurrentLevel = LevelsMap.WARN;

+

+/**

+ * Getter/Setter for the logging level

+ *

+ * Returns the current logging level.

+ *

+ * When a value is passed, sets the logging level to that value.

+ * The values should be one of the following constants:

+ *    logger.LOG

+ *    logger.ERROR

+ *    logger.WARN

+ *    logger.INFO

+ *    logger.DEBUG

+ *

+ * The value used determines which messages get printed.  The logging

+ * values above are in order, and only messages logged at the logging

+ * level or above will actually be displayed to the user.  E.g., the

+ * default level is WARN, so only messages logged with LOG, ERROR, or

+ * WARN will be displayed; INFO and DEBUG messages will be ignored.

+ */

+logger.level = function (value) {

+    if (arguments.length) {

+        if (LevelsMap[value] === null) {

+            throw new Error("invalid logging level: " + value);

+        }

+        CurrentLevel = LevelsMap[value];

+    }

+

+    return Levels[CurrentLevel];

+};

+

+/**

+ * Getter/Setter for the useConsole functionality

+ *

+ * When useConsole is true, the logger will log via the

+ * browser 'console' object.

+ */

+logger.useConsole = function (value) {

+    if (arguments.length) UseConsole = !!value;

+

+    if (UseConsole) {

+        if (typeof console == "undefined") {

+            throw new Error("global console object is not defined");

+        }

+

+        if (typeof console.log != "function") {

+            throw new Error("global console object does not have a log function");

+        }

+

+        if (typeof console.useLogger == "function") {

+            if (console.useLogger()) {

+                throw new Error("console and logger are too intertwingly");

+            }

+        }

+    }

+

+    return UseConsole;

+};

+

+/**

+ * Getter/Setter for the useLogger functionality

+ *

+ * When useLogger is true, the logger will log via the

+ * native Logger plugin.

+ */

+logger.useLogger = function (value) {

+    // Enforce boolean

+    if (arguments.length) UseLogger = !!value;

+    return UseLogger;

+};

+

+/**

+ * Logs a message at the LOG level.

+ *

+ * Parameters passed after message are used applied to

+ * the message with utils.format()

+ */

+logger.log   = function(message) { logWithArgs("LOG",   arguments); };

+

+/**

+ * Logs a message at the ERROR level.

+ *

+ * Parameters passed after message are used applied to

+ * the message with utils.format()

+ */

+logger.error = function(message) { logWithArgs("ERROR", arguments); };

+

+/**

+ * Logs a message at the WARN level.

+ *

+ * Parameters passed after message are used applied to

+ * the message with utils.format()

+ */

+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };

+

+/**

+ * Logs a message at the INFO level.

+ *

+ * Parameters passed after message are used applied to

+ * the message with utils.format()

+ */

+logger.info  = function(message) { logWithArgs("INFO",  arguments); };

+

+/**

+ * Logs a message at the DEBUG level.

+ *

+ * Parameters passed after message are used applied to

+ * the message with utils.format()

+ */

+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };

+

+// log at the specified level with args

+function logWithArgs(level, args) {

+    args = [level].concat([].slice.call(args));

+    logger.logLevel.apply(logger, args);

+}

+

+/**

+ * Logs a message at the specified level.

+ *

+ * Parameters passed after message are used applied to

+ * the message with utils.format()

+ */

+logger.logLevel = function(level /* , ... */) {

+    // format the message with the parameters

+    var formatArgs = [].slice.call(arguments, 1);

+    var message    = logger.format.apply(logger.format, formatArgs);

+

+    if (LevelsMap[level] === null) {

+        throw new Error("invalid logging level: " + level);

+    }

+

+    if (LevelsMap[level] > CurrentLevel) return;

+

+    // queue the message if not yet at deviceready

+    if (!DeviceReady && !UseConsole) {

+        Queued.push([level, message]);

+        return;

+    }

+

+    // Log using the native logger if that is enabled

+    if (UseLogger) {

+        exec(null, null, "Logger", "logLevel", [level, message]);

+    }

+

+    // Log using the console if that is enabled

+    if (UseConsole) {

+        // 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:   originalConsole.log(message); break;

+            case logger.ERROR: originalConsole.log("ERROR: " + message); break;

+            case logger.WARN:  originalConsole.log("WARN: "  + message); break;

+            case logger.INFO:  originalConsole.log("INFO: "  + message); break;

+            case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;

+        }

+    }

+};

+

+

+/**

+ * Formats a string and arguments following it ala console.log()

+ *

+ * Any remaining arguments will be appended to the formatted string.

+ *

+ * for rationale, see FireBug's Console API:

+ *    http://getfirebug.com/wiki/index.php/Console_API

+ */

+logger.format = function(formatString, args) {

+    return __format(arguments[0], [].slice.call(arguments,1)).join(' ');

+};

+

+

+//------------------------------------------------------------------------------

+/**

+ * 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().

+ *

+ * Returns an array containing the formatted string and any remaining

+ * arguments.

+ */

+function __format(formatString, args) {

+    if (formatString === null || formatString === undefined) return [""];

+    if (arguments.length == 1) return [formatString.toString()];

+

+    if (typeof formatString != "string")

+        formatString = formatString.toString();

+

+    var pattern = /(.*?)%(.)(.*)/;

+    var rest    = formatString;

+    var result  = [];

+

+    while (args.length) {

+        var match = pattern.exec(rest);

+        if (!match) break;

+

+        var arg   = args.shift();

+        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);

+

+    var remainingArgs = [].slice.call(args);

+    remainingArgs.unshift(result.join(''));

+    return remainingArgs;

+}

+

+function __formatted(object, formatChar) {

+

+    try {

+        switch(formatChar) {

+            case 'j':

+            case 'o': return JSON.stringify(object);

+            case 'c': return '';

+        }

+    }

+    catch (e) {

+        return "error JSON.stringify()ing argument: " + e;

+    }

+

+    if ((object === null) || (object === undefined)) {

+        return Object.prototype.toString.call(object);

+    }

+

+    return object.toString();

+}

+

+

+//------------------------------------------------------------------------------

+// when deviceready fires, log queued messages

+logger.__onDeviceReady = function() {

+    if (DeviceReady) return;

+

+    DeviceReady = true;

+

+    for (var i=0; i<Queued.length; i++) {

+        var messageArgs = Queued[i];

+        logger.logLevel(messageArgs[0], messageArgs[1]);

+    }

+

+    Queued = null;

+};

+

+// add a deviceready event to log queued messages

+document.addEventListener("deviceready", logger.__onDeviceReady, false);

+

+});

+

+// file: lib/common/plugin/logger/symbols.js

+define("cordova/plugin/logger/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/logger', 'cordova.logger');

+

+});

+

+// file: lib/common/plugin/media/symbols.js

+define("cordova/plugin/media/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.defaults('cordova/plugin/Media', 'Media');

+modulemapper.defaults('cordova/plugin/MediaError', 'MediaError');

+

+});

+

+// file: lib/common/plugin/network.js

+define("cordova/plugin/network", function(require, exports, module) {

+

+var exec = require('cordova/exec'),

+    cordova = require('cordova'),

+    channel = require('cordova/channel'),

+    utils = require('cordova/utils');

+

+// Link the onLine property with the Cordova-supplied network info.

+// This works because we clobber the naviagtor object with our own

+// object in bootstrap.js.

+if (typeof navigator != 'undefined') {

+    utils.defineGetter(navigator, 'onLine', function() {

+        return this.connection.type != 'none';

+    });

+}

+

+function NetworkConnection() {

+    this.type = 'unknown';

+}

+

+/**

+ * Get connection info

+ *

+ * @param {Function} successCallback The function to call when the Connection data is available

+ * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)

+ */

+NetworkConnection.prototype.getInfo = function(successCallback, errorCallback) {

+    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);

+};

+

+var me = new NetworkConnection();

+var timerId = null;

+var timeout = 500;

+

+channel.onCordovaReady.subscribe(function() {

+    me.getInfo(function(info) {

+        me.type = info;

+        if (info === "none") {

+            // set a timer if still offline at the end of timer send the offline event

+            timerId = setTimeout(function(){

+                cordova.fireDocumentEvent("offline");

+                timerId = null;

+            }, timeout);

+        } else {

+            // If there is a current offline event pending clear it

+            if (timerId !== null) {

+                clearTimeout(timerId);

+                timerId = null;

+            }

+            cordova.fireDocumentEvent("online");

+        }

+

+        // should only fire this once

+        if (channel.onCordovaConnectionReady.state !== 2) {

+            channel.onCordovaConnectionReady.fire();

+        }

+    },

+    function (e) {

+        // If we can't get the network info we should still tell Cordova

+        // to fire the deviceready event.

+        if (channel.onCordovaConnectionReady.state !== 2) {

+            channel.onCordovaConnectionReady.fire();

+        }

+        console.log("Error initializing Network Connection: " + e);

+    });

+});

+

+module.exports = me;

+

+});

+

+// file: lib/common/plugin/networkstatus/symbols.js

+define("cordova/plugin/networkstatus/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/network', 'navigator.network.connection', 'navigator.network.connection is deprecated. Use navigator.connection instead.');

+modulemapper.clobbers('cordova/plugin/network', 'navigator.connection');

+modulemapper.defaults('cordova/plugin/Connection', 'Connection');

+

+});

+

+// file: lib/common/plugin/notification.js

+define("cordova/plugin/notification", function(require, exports, module) {

+

+var exec = require('cordova/exec');

+var platform = require('cordova/platform');

+

+/**

+ * Provides access to notifications on the device.

+ */

+

+module.exports = {

+

+    /**

+     * Open a native alert dialog, with a customizable title and button text.

+     *

+     * @param {String} message              Message to print in the body of the alert

+     * @param {Function} completeCallback   The callback that is called when user clicks on a button.

+     * @param {String} title                Title of the alert dialog (default: Alert)

+     * @param {String} buttonLabel          Label of the close button (default: OK)

+     */

+    alert: function(message, completeCallback, title, buttonLabel) {

+        var _title = (title || "Alert");

+        var _buttonLabel = (buttonLabel || "OK");

+        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);

+    },

+

+    /**

+     * Open a native confirm dialog, with a customizable title and button text.

+     * The result that the user selects is returned to the result callback.

+     *

+     * @param {String} message              Message to print in the body of the alert

+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.

+     * @param {String} title                Title of the alert dialog (default: Confirm)

+     * @param {Array} buttonLabels          Array of the labels of the buttons (default: ['OK', 'Cancel'])

+     */

+    confirm: function(message, resultCallback, title, buttonLabels) {

+        var _title = (title || "Confirm");

+        var _buttonLabels = (buttonLabels || ["OK", "Cancel"]);

+

+        // Strings are deprecated!

+        if (typeof _buttonLabels === 'string') {

+            console.log("Notification.confirm(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).");

+        }

+

+        // Some platforms take an array of button label names.

+        // Other platforms take a comma separated list.

+        // For compatibility, we convert to the desired type based on the platform.

+        if (platform.id == "android" || platform.id == "ios" || platform.id == "windowsphone" || platform.id == "blackberry10") {

+            if (typeof _buttonLabels === 'string') {

+                var buttonLabelString = _buttonLabels;

+                _buttonLabels = _buttonLabels.split(","); // not crazy about changing the var type here

+            }

+        } else {

+            if (Array.isArray(_buttonLabels)) {

+                var buttonLabelArray = _buttonLabels;

+                _buttonLabels = buttonLabelArray.toString();

+            }

+        }

+        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);

+    },

+

+    /**

+     * Open a native prompt dialog, with a customizable title and button text.

+     * The following results are returned to the result callback:

+     *  buttonIndex     Index number of the button selected.

+     *  input1          The text entered in the prompt dialog box.

+     *

+     * @param {String} message              Dialog message to display (default: "Prompt message")

+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.

+     * @param {String} title                Title of the dialog (default: "Prompt")

+     * @param {Array} buttonLabels          Array of strings for the button labels (default: ["OK","Cancel"])

+     * @param {String} defaultText          Textbox input value (default: "Default text")

+     */

+    prompt: function(message, resultCallback, title, buttonLabels, defaultText) {

+        var _message = (message || "Prompt message");

+        var _title = (title || "Prompt");

+        var _buttonLabels = (buttonLabels || ["OK","Cancel"]);

+        var _defaultText = (defaultText || "Default text");

+        exec(resultCallback, null, "Notification", "prompt", [_message, _title, _buttonLabels, _defaultText]);

+    },

+

+    /**

+     * Causes the device to vibrate.

+     *

+     * @param {Integer} mills       The number of milliseconds to vibrate for.

+     */

+    vibrate: function(mills) {

+        exec(null, null, "Notification", "vibrate", [mills]);

+    },

+

+    /**

+     * Causes the device to beep.

+     * On Android, the default notification ringtone is played "count" times.

+     *

+     * @param {Integer} count       The number of beeps.

+     */

+    beep: function(count) {

+        exec(null, null, "Notification", "beep", [count]);

+    }

+};

+

+});

+

+// file: lib/common/plugin/notification/symbols.js

+define("cordova/plugin/notification/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.defaults('cordova/plugin/notification', 'navigator.notification');

+

+});

+

+// file: lib/common/plugin/requestFileSystem.js

+define("cordova/plugin/requestFileSystem", function(require, exports, module) {

+

+var argscheck = require('cordova/argscheck'),

+    FileError = require('cordova/plugin/FileError'),

+    FileSystem = require('cordova/plugin/FileSystem'),

+    exec = require('cordova/exec');

+

+/**

+ * Request a file system in which to store application data.

+ * @param type  local file system type

+ * @param size  indicates how much storage space, in bytes, the application expects to need

+ * @param successCallback  invoked with a FileSystem object

+ * @param errorCallback  invoked if error occurs retrieving file system

+ */

+var requestFileSystem = function(type, size, successCallback, errorCallback) {

+    argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);

+    var fail = function(code) {

+        errorCallback && errorCallback(new FileError(code));

+    };

+

+    if (type < 0 || type > 3) {

+        fail(FileError.SYNTAX_ERR);

+    } else {

+        // if successful, return a FileSystem object

+        var success = function(file_system) {

+            if (file_system) {

+                if (successCallback) {

+                    // 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 argscheck = require('cordova/argscheck'),

+    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) {

+    argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments);

+    // error callback

+    var fail = function(error) {

+        errorCallback && 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 (successCallback) {

+                // create appropriate Entry object

+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);

+                successCallback(result);

+            }

+        }

+        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/plugin/splashscreen/symbols.js

+define("cordova/plugin/splashscreen/symbols", function(require, exports, module) {

+

+

+var modulemapper = require('cordova/modulemapper');

+

+modulemapper.clobbers('cordova/plugin/splashscreen', 'navigator.splashscreen');

+

+});

+

+// file: lib/common/pluginloader.js

+define("cordova/pluginloader", function(require, exports, module) {

+

+var channel = require('cordova/channel');

+var modulemapper = require('cordova/modulemapper');

+

+// Helper function to inject a <script> tag.

+function injectScript(url, onload, onerror) {

+    var script = document.createElement("script");

+    // onload fires even when script fails loads with an error.

+    script.onload = onload;

+    script.onerror = onerror || onload;

+    script.src = url;

+    document.head.appendChild(script);

+}

+

+function onScriptLoadingComplete(moduleList) {

+    // Loop through all the plugins and then through their clobbers and merges.

+    for (var i = 0, module; module = moduleList[i]; i++) {

+        if (module) {

+            try {

+                if (module.clobbers && module.clobbers.length) {

+                    for (var j = 0; j < module.clobbers.length; j++) {

+                        modulemapper.clobbers(module.id, module.clobbers[j]);

+                    }

+                }

+

+                if (module.merges && module.merges.length) {

+                    for (var k = 0; k < module.merges.length; k++) {

+                        modulemapper.merges(module.id, module.merges[k]);

+                    }

+                }

+

+                // Finally, if runs is truthy we want to simply require() the module.

+                // This can be skipped if it had any merges or clobbers, though,

+                // since the mapper will already have required the module.

+                if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {

+                    modulemapper.runs(module.id);

+                }

+            }

+            catch(err) {

+                // error with module, most likely clobbers, should we continue?

+            }

+        }

+    }

+

+    finishPluginLoading();

+}

+

+// Called when:

+// * There are plugins defined and all plugins are finished loading.

+// * There are no plugins to load.

+function finishPluginLoading() {

+    channel.onPluginsReady.fire();

+}

+

+// Handler for the cordova_plugins.js content.

+// See plugman's plugin_loader.js for the details of this object.

+// This function is only called if the really is a plugins array that isn't empty.

+// Otherwise the onerror response handler will just call finishPluginLoading().

+function handlePluginsObject(path, moduleList) {

+    // Now inject the scripts.

+    var scriptCounter = moduleList.length;

+

+    if (!scriptCounter) {

+        finishPluginLoading();

+        return;

+    }

+    function scriptLoadedCallback() {

+        if (!--scriptCounter) {

+            onScriptLoadingComplete(moduleList);

+        }

+    }

+

+    for (var i = 0; i < moduleList.length; i++) {

+        injectScript(path + moduleList[i].file, scriptLoadedCallback);

+    }

+}

+

+function injectPluginScript(pathPrefix) {

+    injectScript(pathPrefix + 'cordova_plugins.js', function(){

+        try {

+            var moduleList = require("cordova/plugin_list");

+            handlePluginsObject(pathPrefix, moduleList);

+        } catch (e) {

+            // Error loading cordova_plugins.js, file not found or something

+            // this is an acceptable error, pre-3.0.0, so we just move on.

+            finishPluginLoading();

+        }

+    },finishPluginLoading); // also, add script load error handler for file not found

+}

+

+function findCordovaPath() {

+    var path = null;

+    var scripts = document.getElementsByTagName('script');

+    var term = 'cordova.js';

+    for (var n = scripts.length-1; n>-1; n--) {

+        var src = scripts[n].src;

+        if (src.indexOf(term) == (src.length - term.length)) {

+            path = src.substring(0, src.length - term.length);

+            break;

+        }

+    }

+    return path;

+}

+

+// Tries to load all plugins' js-modules.

+// This is an async process, but onDeviceReady is blocked on onPluginsReady.

+// onPluginsReady is fired when there are no plugins to load, or they are all done.

+exports.load = function() {

+    var pathPrefix = findCordovaPath();

+    if (pathPrefix === null) {

+        console.log('Could not find cordova.js script tag. Plugin loading may fail.');

+        pathPrefix = '';

+    }

+    injectPluginScript(pathPrefix);

+};

+

+

+});

+

+// file: lib/common/symbols.js

+define("cordova/symbols", function(require, exports, module) {

+

+var modulemapper = require('cordova/modulemapper');

+

+// Use merges here in case others symbols files depend on this running first,

+// but fail to declare the dependency with a require().

+modulemapper.merges('cordova', 'cordova');

+modulemapper.clobbers('cordova/exec', 'cordova.exec');

+modulemapper.clobbers('cordova/exec', 'Cordova.exec');

+

+});

+

+// file: lib/common/urlutil.js

+define("cordova/urlutil", function(require, exports, module) {

+

+var urlutil = exports;

+var anchorEl = document.createElement('a');

+

+/**

+ * For already absolute URLs, returns what is passed in.

+ * For relative URLs, converts them to absolute ones.

+ */

+urlutil.makeAbsolute = function(url) {

+  anchorEl.href = url;

+  return anchorEl.href;

+};

+

+});

+

+// file: lib/common/utils.js

+define("cordova/utils", function(require, exports, module) {

+

+var utils = exports;

+

+/**

+ * Defines a property getter / setter for obj[key].

+ */

+utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {

+    if (Object.defineProperty) {

+        var desc = {

+            get: getFunc,

+            configurable: true

+        };

+        if (opt_setFunc) {

+            desc.set = opt_setFunc;

+        }

+        Object.defineProperty(obj, key, desc);

+    } else {

+        obj.__defineGetter__(key, getFunc);

+        if (opt_setFunc) {

+            obj.__defineSetter__(key, opt_setFunc);

+        }

+    }

+};

+

+/**

+ * Defines a property getter for obj[key].

+ */

+utils.defineGetter = utils.defineGetterSetter;

+

+utils.arrayIndexOf = function(a, item) {

+    if (a.indexOf) {

+        return a.indexOf(item);

+    }

+    var len = a.length;

+    for (var i = 0; i < len; ++i) {

+        if (a[i] == item) {

+            return i;

+        }

+    }

+    return -1;

+};

+

+/**

+ * Returns whether the item was found in the array.

+ */

+utils.arrayRemove = function(a, item) {

+    var index = utils.arrayIndexOf(a, item);

+    if (index != -1) {

+        a.splice(index, 1);

+    }

+    return index != -1;

+};

+

+utils.typeName = function(val) {

+    return Object.prototype.toString.call(val).slice(8, -1);

+};

+

+/**

+ * Returns an indication of whether the argument is an array or not

+ */

+utils.isArray = function(a) {

+    return utils.typeName(a) == 'Array';

+};

+

+/**

+ * Returns an indication of whether the argument is a Date or not

+ */

+utils.isDate = function(d) {

+    return utils.typeName(d) == 'Date';

+};

+

+/**

+ * Does a deep clone of the object.

+ */

+utils.clone = function(obj) {

+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {

+        return obj;

+    }

+

+    var retVal, i;

+

+    if(utils.isArray(obj)){

+        retVal = [];

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

+            retVal.push(utils.clone(obj[i]));

+        }

+        return retVal;

+    }

+

+    retVal = {};

+    for(i in obj){

+        if(!(i in retVal) || retVal[i] != obj[i]) {

+            retVal[i] = utils.clone(obj[i]);

+        }

+    }

+    return retVal;

+};

+

+/**

+ * Returns a wrapped version of the function

+ */

+utils.close = function(context, func, params) {

+    if (typeof params == 'undefined') {

+        return function() {

+            return func.apply(context, arguments);

+        };

+    } else {

+        return function() {

+            return func.apply(context, params);

+        };

+    }

+};

+

+/**

+ * Create a UUID

+ */

+utils.createUUID = function() {

+    return UUIDcreatePart(4) + '-' +

+        UUIDcreatePart(2) + '-' +

+        UUIDcreatePart(2) + '-' +

+        UUIDcreatePart(2) + '-' +

+        UUIDcreatePart(6);

+};

+

+/**

+ * Extends a child object from a parent object using classical inheritance

+ * pattern.

+ */

+utils.extend = (function() {

+    // proxy used to establish prototype chain

+    var F = function() {};

+    // extend Child from Parent

+    return function(Child, Parent) {

+        F.prototype = Parent.prototype;

+        Child.prototype = new F();

+        Child.__super__ = Parent.prototype;

+        Child.prototype.constructor = Child;

+    };

+}());

+

+/**

+ * Alerts a message in any available way: alert or console.log.

+ */

+utils.alert = function(msg) {

+    if (window.alert) {

+        window.alert(msg);

+    } else if (console && console.log) {

+        console.log(msg);

+    }

+};

+

+

+//------------------------------------------------------------------------------

+function UUIDcreatePart(length) {

+    var uuidpart = "";

+    for (var i=0; i<length; i++) {

+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);

+        if (uuidchar.length == 1) {

+            uuidchar = "0" + uuidchar;

+        }

+        uuidpart += uuidchar;

+    }

+    return uuidpart;

+}

+

+

+});

+

+window.cordova = require('cordova');

+// file: lib/scripts/bootstrap.js

+

+(function (context) {

+    if (context._cordovaJsLoaded) {

+        throw new Error('cordova.js included multiple times.');

+    }

+    context._cordovaJsLoaded = true;

+

+    var channel = require('cordova/channel');

+    var pluginloader = require('cordova/pluginloader');

+

+    var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];

+

+    function logUnfiredChannels(arr) {

+        for (var i = 0; i < arr.length; ++i) {

+            if (arr[i].state != 2) {

+                console.log('Channel not fired: ' + arr[i].type);

+            }

+        }

+    }

+

+    window.setTimeout(function() {

+        if (channel.onDeviceReady.state != 2) {

+            console.log('deviceready has not fired after 5 seconds.');

+            logUnfiredChannels(platformInitChannelsArray);

+            logUnfiredChannels(channel.deviceReadyChannelsArray);

+        }

+    }, 5000);

+

+    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.

+    // We replace it so that properties that can't be clobbered can instead be overridden.

+    function replaceNavigator(origNavigator) {

+        var CordovaNavigator = function() {};

+        CordovaNavigator.prototype = origNavigator;

+        var newNavigator = new CordovaNavigator();

+        // This work-around really only applies to new APIs that are newer than Function.bind.

+        // Without it, APIs such as getGamepads() break.

+        if (CordovaNavigator.bind) {

+            for (var key in origNavigator) {

+                if (typeof origNavigator[key] == 'function') {

+                    newNavigator[key] = origNavigator[key].bind(origNavigator);

+                }

+            }

+        }

+        return newNavigator;

+    }

+    if (context.navigator) {

+        context.navigator = replaceNavigator(context.navigator);

+    }

+

+    // _nativeReady is global variable that the native side can set

+    // to signify that the native code is ready. It is a global since

+    // it may be called before any cordova JS is ready.

+    if (window._nativeReady) {

+        channel.onNativeReady.fire();

+    }

+

+    /**

+     * Create all cordova objects once native side is ready.

+     */

+    channel.join(function() {

+        // Call the platform-specific initialization

+        require('cordova/platform').initialize();

+

+        // Fire event to notify that all objects are created

+        channel.onCordovaReady.fire();

+

+        // Fire onDeviceReady event once page has fully loaded, all

+        // constructors have run and cordova info has been received from native

+        // side.

+        // This join call is deliberately made after platform.initialize() in

+        // order that plugins may manipulate channel.deviceReadyChannelsArray

+        // if necessary.

+        channel.join(function() {

+            require('cordova').fireDocumentEvent('deviceready');

+        }, channel.deviceReadyChannelsArray);

+

+    }, platformInitChannelsArray);

+

+    // Don't attempt to load when running unit tests.

+    if (typeof XMLHttpRequest != 'undefined') {

+        pluginloader.load();

+    }

+}(window));

+

 })();
\ No newline at end of file
diff --git a/wp7/bin/check_reqs b/wp7/bin/check_reqs
old mode 100644
new mode 100755
diff --git a/wp7/bin/check_reqs.bat b/wp7/bin/check_reqs.bat
index 26e7393..19d5df1 100644
--- a/wp7/bin/check_reqs.bat
+++ b/wp7/bin/check_reqs.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%check_reqs.js (
-        cscript "%full_path%check_reqs.js" %* //nologo
+SET script_path="%~dp0check_reqs.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'check_reqs.js' in 'bin' folder, aborting...>&2
diff --git a/wp7/bin/check_reqs.js b/wp7/bin/check_reqs.js
index 3dc1496..2b10e8c 100644
--- a/wp7/bin/check_reqs.js
+++ b/wp7/bin/check_reqs.js
@@ -43,7 +43,12 @@
 
 // gets the output from a command, failing with the given error message
 function check_command(cmd, fail_msg) {
-    var out = wscript_shell.Exec(cmd);
+    try {
+        var out = wscript_shell.Exec(cmd);
+    } catch(exception) {
+        Log(fail_msg, true);
+        WScript.Quit(1);
+    }
     while (out.Status == 0) {
         WScript.Sleep(100);
     }
@@ -73,9 +78,9 @@
  */
 function SystemRequiermentsMet() {
     var cmd = 'msbuild -version'
-    var fail_msg = 'The command `msbuild` failed. Make sure you have the latest Windows Phone SDKs installed, and the `msbuild.exe` command (inside C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319) is added to your path.'
+    var fail_msg = 'The command `msbuild` failed. Make sure you have the latest Windows Phone SDKs installed, AND have the latest .NET framework added to your path (i.e C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319).'
     var output = check_command(cmd, fail_msg);
-    var msversion = output.match(/\.NET\sFramework\,\sversion\s4\.0/);
+    var msversion = output.match(/\.NET\sFramework\,\sversion\s4\.0/i);
     if (!msversion) {
         Log('Please install the .NET Framwork v4.0.30319 (in the latest windows phone SDK\'s).', true);
         Log('Make sure the "msbuild" command in your path is pointing to  v4.0.30319 of msbuild as well (inside C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319).', true);
@@ -86,7 +91,7 @@
         cmd = 'git --version';
         fail_msg = 'The command `git` failed. Make sure you have git installed as well ad in your PATH environment so the tool can use it';
         output = check_command(cmd, fail_msg);
-        var gitVersion = output.match(/git\sversion\s1\./);
+        var gitVersion = output.match(/git\sversion\s1\./i);
         if (!gitVersion) {
             Log('Please ensure you have at least git v1 installed and added to you PATH so this tool can use it to get the latest codova.');
         }
@@ -108,4 +113,4 @@
     }
 }
 
-SystemRequiermentsMet();
\ No newline at end of file
+SystemRequiermentsMet();
diff --git a/wp7/bin/create.js b/wp7/bin/create.js
index ccd6073..983df58 100644
--- a/wp7/bin/create.js
+++ b/wp7/bin/create.js
@@ -113,6 +113,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in create.js : " + command);
         Log(line, true);
         WScript.Quit(1);
     }
@@ -168,7 +169,7 @@
     }
 
     //clean up any Bin/obj or other generated files
-    exec('cscript ' + path + '\\cordova\\lib\\clean.js //nologo');
+    exec('cscript "' + path + '\\cordova\\lib\\clean.js" //nologo');
 
     // delete any .user and .sou files if any
     if (fso.FolderExists(path)) {
diff --git a/wp7/framework/Properties/AssemblyInfo.cs b/wp7/framework/Properties/AssemblyInfo.cs
index 70ee17d..29be4ee 100644
--- a/wp7/framework/Properties/AssemblyInfo.cs
+++ b/wp7/framework/Properties/AssemblyInfo.cs
@@ -2,11 +2,11 @@
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
-// General Information about an assembly is controlled through the following 
+// General Information about an assembly is controlled through the following
 // set of attributes. Change these attribute values to modify the information
 // associated with an assembly.
 [assembly: AssemblyTitle("WPCordovaClassLib")]
-[assembly: AssemblyDescription("2.9.0")]
+[assembly: AssemblyDescription("2.9.1")]
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("Apache Cordova")]
 [assembly: AssemblyProduct("WPCordovaClassLib")]
@@ -14,8 +14,8 @@
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
 // COM, set the ComVisible attribute to true on that type.
 [assembly: ComVisible(false)]
 
@@ -25,13 +25,13 @@
 // Version information for an assembly consists of the following four values:
 //
 //      Major Version
-//      Minor Version 
+//      Minor Version
 //      Build Number
 //      Revision
 //
-// You can specify all the values or you can default the Revision and Build Numbers 
+// You can specify all the values or you can default the Revision and Build Numbers
 // by using the '*' as shown below:
 
-[assembly: AssemblyVersion("2.9.0.0")]
-[assembly: AssemblyFileVersion("2.9.0")]
+[assembly: AssemblyVersion("2.9.1.0")]
+[assembly: AssemblyFileVersion("2.9.1")]
 
diff --git a/wp7/framework/WPCordovaClassLib.csproj b/wp7/framework/WPCordovaClassLib.csproj
index b8f76ae..93801e8 100644
--- a/wp7/framework/WPCordovaClassLib.csproj
+++ b/wp7/framework/WPCordovaClassLib.csproj
@@ -80,145 +80,57 @@
     <Reference Include="System.Xml.Linq" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="..\templates\standalone\cordovalib\BaseCommand.cs">
+    <Compile Include="..\template\cordovalib\BaseCommand.cs">
       <Link>CordovaLib\BaseCommand.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\BrowserMouseHelper.cs">
+    <Compile Include="..\template\cordovalib\BrowserMouseHelper.cs">
       <Link>CordovaLib\BrowserMouseHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CommandFactory.cs">
+    <Compile Include="..\template\cordovalib\CommandFactory.cs">
       <Link>CordovaLib\CommandFactory.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ConfigHandler.cs">
+    <Compile Include="..\template\cordovalib\ConfigHandler.cs">
       <Link>CordovaLib\ConfigHandler.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CordovaCommandCall.cs">
+    <Compile Include="..\template\cordovalib\ConsoleHelper.cs">
+      <Link>CordovaLib\ConsoleHelper.cs</Link>
+    </Compile>
+    <Compile Include="..\template\cordovalib\CordovaCommandCall.cs">
       <Link>CordovaLib\CordovaCommandCall.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CordovaView.xaml.cs">
+    <Compile Include="..\template\cordovalib\CordovaView.xaml.cs">
       <Link>CordovaLib\CordovaView.xaml.cs</Link>
-      <DependentUpon>CordovaView.xaml</DependentUpon>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\DOMStorageHelper.cs">
+    <Compile Include="..\template\cordovalib\DOMStorageHelper.cs">
       <Link>CordovaLib\DOMStorageHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ImageExifHelper.cs">
+    <Compile Include="..\template\cordovalib\IBrowserDecorator.cs">
+      <Link>CordovaLib\IBrowserDecorator.cs</Link>
+    </Compile>
+    <Compile Include="..\template\cordovalib\ImageExifHelper.cs">
       <Link>CordovaLib\ImageExifHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\JSON\JsonHelper.cs">
+    <Compile Include="..\template\cordovalib\JSON\JsonHelper.cs">
       <Link>CordovaLib\JSON\JsonHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\NativeExecution.cs">
+    <Compile Include="..\template\cordovalib\NativeExecution.cs">
       <Link>CordovaLib\NativeExecution.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\OrientationHelper.cs">
+    <Compile Include="..\template\cordovalib\OrientationHelper.cs">
       <Link>CordovaLib\OrientationHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\PluginResult.cs">
+    <Compile Include="..\template\cordovalib\PluginResult.cs">
       <Link>CordovaLib\PluginResult.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ScriptCallback.cs">
+    <Compile Include="..\template\cordovalib\ScriptCallback.cs">
       <Link>CordovaLib\ScriptCallback.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Accelerometer.cs">
-      <Link>CordovaLib\Plugins\Accelerometer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\AudioFormatsHelper.cs">
-      <Link>CordovaLib\Plugins\AudioFormatsHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\AudioPlayer.cs">
-      <Link>CordovaLib\Plugins\AudioPlayer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Battery.cs">
-      <Link>CordovaLib\Plugins\Battery.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Camera.cs">
-      <Link>CordovaLib\Plugins\Camera.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Capture.cs">
-      <Link>CordovaLib\Plugins\Capture.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Compass.cs">
-      <Link>CordovaLib\Plugins\Compass.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Contacts.cs">
-      <Link>CordovaLib\Plugins\Contacts.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\DebugConsole.cs">
-      <Link>CordovaLib\Plugins\DebugConsole.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Device.cs">
-      <Link>CordovaLib\Plugins\Device.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\File.cs">
-      <Link>CordovaLib\Plugins\File.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\FileTransfer.cs">
-      <Link>CordovaLib\Plugins\FileTransfer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\GeoLocation.cs">
-      <Link>CordovaLib\Plugins\GeoLocation.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Globalization.cs">
-      <Link>CordovaLib\Plugins\Globalization.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\InAppBrowser.cs">
-      <Link>CordovaLib\Plugins\InAppBrowser.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Media.cs">
-      <Link>CordovaLib\Plugins\Media.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\MimeTypeMapper.cs">
-      <Link>CordovaLib\Plugins\MimeTypeMapper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\NetworkStatus.cs">
-      <Link>CordovaLib\Plugins\NetworkStatus.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Notification.cs">
-      <Link>CordovaLib\Plugins\Notification.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\AudioCaptureTask.cs">
-      <Link>CordovaLib\Plugins\UI\AudioCaptureTask.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\AudioRecorder.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\AudioRecorder.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\ImageCapture.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\ImageCapture.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\NotificationBox.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\NotificationBox.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\VideoCaptureTask.cs">
-      <Link>CordovaLib\Plugins\UI\VideoCaptureTask.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\VideoRecorder.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\VideoRecorder.xaml.cs</Link>
+    <Compile Include="..\template\cordovalib\XHRHelper.cs">
+      <Link>CordovaLib\XHRHelper.cs</Link>
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Content Include="..\templates\standalone\cordovalib\resources\notification-beep.wav">
-      <Link>CordovaLib\resources\notification-beep.wav</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.back.rest.png">
-      <Link>CordovaLib\Images\appbar.back.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.close.rest.png">
-      <Link>CordovaLib\Images\appbar.close.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.feature.video.rest.png">
-      <Link>CordovaLib\Images\appbar.feature.video.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.next.rest.png">
-      <Link>CordovaLib\Images\appbar.next.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.save.rest.png">
-      <Link>CordovaLib\Images\appbar.save.rest.png</Link>
-    </Content>
-    <Content Include="..\templates\standalone\Images\appbar.stop.rest.png">
-      <Link>CordovaLib\Images\appbar.stop.rest.png</Link>
-    </Content>
     <Content Include="Images\appbar.back.rest.png">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -245,31 +157,14 @@
     <Resource Include="resources\notification-beep.wav" />
   </ItemGroup>
   <ItemGroup>
-    <Page Include="..\templates\standalone\cordovalib\CordovaView.xaml">
+    <Page Include="..\template\cordovalib\CordovaView.xaml">
       <Link>CordovaLib\CordovaView.xaml</Link>
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\AudioRecorder.xaml">
-      <Link>CordovaLib\Plugins\UI\AudioRecorder.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\ImageCapture.xaml">
-      <Link>CordovaLib\Plugins\UI\ImageCapture.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\NotificationBox.xaml">
-      <Link>CordovaLib\Plugins\UI\NotificationBox.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\VideoRecorder.xaml">
-      <Link>CordovaLib\Plugins\UI\VideoRecorder.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Plugins\" />
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
diff --git a/wp7/template/CordovaWP7AppProj.csproj b/wp7/template/CordovaWP7AppProj.csproj
index f7a6b48..8f30f7e 100644
--- a/wp7/template/CordovaWP7AppProj.csproj
+++ b/wp7/template/CordovaWP7AppProj.csproj
@@ -88,21 +88,55 @@
     <Compile Include="cordovalib\BrowserMouseHelper.cs" />
     <Compile Include="cordovalib\CommandFactory.cs" />
     <Compile Include="cordovalib\ConfigHandler.cs" />
+    <Compile Include="cordovalib\ConsoleHelper.cs" />
     <Compile Include="cordovalib\CordovaCommandCall.cs" />
     <Compile Include="cordovalib\CordovaView.xaml.cs">
       <DependentUpon>CordovaView.xaml</DependentUpon>
     </Compile>
     <Compile Include="cordovalib\DOMStorageHelper.cs" />
-    <Compile Include="cordovalib\ImageExifHelper.cs" />
+    <Compile Include="cordovalib\IBrowserDecorator.cs" />
     <Compile Include="cordovalib\JSON\JsonHelper.cs" />
     <Compile Include="cordovalib\NativeExecution.cs" />
     <Compile Include="cordovalib\OrientationHelper.cs" />
     <Compile Include="cordovalib\PluginResult.cs" />
     <Compile Include="cordovalib\ScriptCallback.cs" />
+    <Compile Include="cordovalib\XHRHelper.cs" />
     <Compile Include="MainPage.xaml.cs">
       <DependentUpon>MainPage.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Plugins\Accelerometer.cs" />
+    <Compile Include="Plugins\AudioFormatsHelper.cs" />
+    <Compile Include="Plugins\AudioPlayer.cs" />
+    <Compile Include="Plugins\Battery.cs" />
+    <Compile Include="Plugins\Camera.cs" />
     <Compile Include="Plugins\Capture.cs" />
+    <Compile Include="Plugins\Compass.cs" />
+    <Compile Include="Plugins\Contacts.cs" />
+    <Compile Include="Plugins\Device.cs" />
+    <Compile Include="Plugins\File.cs" />
+    <Compile Include="Plugins\FileTransfer.cs" />
+    <Compile Include="Plugins\GeoLocation.cs" />
+    <Compile Include="Plugins\Globalization.cs" />
+    <Compile Include="Plugins\ImageExifHelper.cs" />
+    <Compile Include="Plugins\InAppBrowser.cs" />
+    <Compile Include="Plugins\Media.cs" />
+    <Compile Include="Plugins\MimeTypeMapper.cs" />
+    <Compile Include="Plugins\NetworkStatus.cs" />
+    <Compile Include="Plugins\Notification.cs" />
+    <Compile Include="Plugins\UI\AudioCaptureTask.cs" />
+    <Compile Include="Plugins\UI\AudioRecorder.xaml.cs">
+      <DependentUpon>AudioRecorder.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Plugins\UI\ImageCapture.xaml.cs">
+      <DependentUpon>ImageCapture.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Plugins\UI\NotificationBox.xaml.cs">
+      <DependentUpon>NotificationBox.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Plugins\UI\VideoCaptureTask.cs" />
+    <Compile Include="Plugins\UI\VideoRecorder.xaml.cs">
+      <DependentUpon>VideoRecorder.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -118,17 +152,41 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </Page>
+    <Page Include="Plugins\UI\AudioRecorder.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Plugins\UI\ImageCapture.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Plugins\UI\NotificationBox.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Plugins\UI\VideoRecorder.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
   </ItemGroup>
   <ItemGroup>
+    <Content Include="config.xml" />
+    <Content Include="www\cordova.js" />
+    <Content Include="www\index.html" />
+    <Content Include="www\css\index.css" />
+    <Content Include="www\js\index.js" />
+    <Content Include="www\img\logo.png" />
+    <Content Include="Images\appbar.back.rest.png" />
+    <Content Include="Images\appbar.close.rest.png" />
+    <Content Include="Images\appbar.feature.video.rest.png" />
+    <Content Include="Images\appbar.next.rest.png" />
+    <Content Include="Images\appbar.save.rest.png" />
+    <Content Include="Images\appbar.stop.rest.png" />
     <None Include="cordova\lib\build.js" />
     <None Include="cordova\lib\clean.js" />
     <None Include="cordova\lib\deploy.js" />
     <None Include="cordova\lib\log.js" />
     <None Include="cordova\lib\target-list.js" />
-    <Content Include="www\**" />
-    <Content Include="config.xml" />
-    <Content Include="Images\**" />
-    <Content Include="resources\notification-beep.wav" />
     <None Include="cordova\build.bat" />
     <None Include="cordova\clean.bat" />
     <None Include="cordova\lib\install-device.bat" />
@@ -167,58 +225,6 @@
   <ItemGroup>
     <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Plugins\Accelerometer.cs" />
-    <Compile Include="Plugins\AudioFormatsHelper.cs" />
-    <Compile Include="Plugins\AudioPlayer.cs" />
-    <Compile Include="Plugins\Battery.cs" />
-    <Compile Include="Plugins\Camera.cs" />
-    <Compile Include="Plugins\Compass.cs" />
-    <Compile Include="Plugins\Contacts.cs" />
-    <Compile Include="Plugins\DebugConsole.cs" />
-    <Compile Include="Plugins\Device.cs" />
-    <Compile Include="Plugins\File.cs" />
-    <Compile Include="Plugins\FileTransfer.cs" />
-    <Compile Include="Plugins\GeoLocation.cs" />
-    <Compile Include="Plugins\Globalization.cs" />
-    <Compile Include="Plugins\InAppBrowser.cs" />
-    <Compile Include="Plugins\Media.cs" />
-    <Compile Include="Plugins\MimeTypeMapper.cs" />
-    <Compile Include="Plugins\NetworkStatus.cs" />
-    <Compile Include="Plugins\Notification.cs" />
-    <Compile Include="Plugins\UI\AudioCaptureTask.cs" />
-    <Compile Include="Plugins\UI\AudioRecorder.xaml.cs">
-      <DependentUpon>AudioRecorder.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\ImageCapture.xaml.cs">
-      <DependentUpon>ImageCapture.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\NotificationBox.xaml.cs">
-      <DependentUpon>NotificationBox.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\VideoCaptureTask.cs" />
-    <Compile Include="Plugins\UI\VideoRecorder.xaml.cs">
-      <DependentUpon>VideoRecorder.xaml</DependentUpon>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <Page Include="Plugins\UI\AudioRecorder.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\ImageCapture.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\NotificationBox.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\VideoRecorder.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
diff --git a/wp7/template/MainPage.xaml b/wp7/template/MainPage.xaml
index 8b1e84b..e066fa6 100644
--- a/wp7/template/MainPage.xaml
+++ b/wp7/template/MainPage.xaml
@@ -22,14 +22,6 @@
                    Margin="0,0,0,0"  
                    x:Name="CordovaView" 
                    VerticalAlignment="Stretch" />
-        <Image Source="SplashScreenImage.jpg"
-          x:Name="SplashImage"
-          VerticalAlignment="Center"
-          HorizontalAlignment="Stretch">
-            <Image.Projection>
-                <PlaneProjection x:Name="SplashProjector"  CenterOfRotationX="0"/>
-            </Image.Projection>
-        </Image>
     </Grid>
 
 </phone:PhoneApplicationPage>
diff --git a/wp7/template/MainPage.xaml.cs b/wp7/template/MainPage.xaml.cs
index b9ec7e1..187228c 100644
--- a/wp7/template/MainPage.xaml.cs
+++ b/wp7/template/MainPage.xaml.cs
@@ -48,25 +48,6 @@
         private void CordovaView_Loaded(object sender, RoutedEventArgs e)
         {
             this.CordovaView.Loaded -= CordovaView_Loaded;
-            // first time load will have an animation
-            Storyboard _storyBoard = new Storyboard();
-            DoubleAnimation animation = new DoubleAnimation()
-            {
-                From = 0,
-                Duration = TimeSpan.FromSeconds(0.6),
-                To = 90
-            };
-            Storyboard.SetTarget(animation, SplashProjector);
-            Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
-            _storyBoard.Children.Add(animation);
-            _storyBoard.Begin();
-            _storyBoard.Completed += Splash_Completed;
-        }
-
-        void Splash_Completed(object sender, EventArgs e)
-        {
-            (sender as Storyboard).Completed -= Splash_Completed;
-            LayoutRoot.Children.Remove(SplashImage);
         }
     }
 }
diff --git a/wp7/template/MyTemplate.vstemplate b/wp7/template/MyTemplate.vstemplate
index 88fa911..b5e66f0 100644
--- a/wp7/template/MyTemplate.vstemplate
+++ b/wp7/template/MyTemplate.vstemplate
@@ -1,133 +1,132 @@
 <VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
-  <TemplateData>
-    <Name>CordovaWP7_2_9_1</Name>
-    <Description>Starter project for building a Cordova app for Windows Phone 7.5 version: 2.9.0</Description>
-    <ProjectType>CSharp</ProjectType>
-    <ProjectSubType>
-    </ProjectSubType>
-    <SortOrder>1000</SortOrder>
-    <CreateNewFolder>true</CreateNewFolder>
-    <DefaultName>CordovaWP7_2_9_1</DefaultName>
-    <ProvideDefaultName>true</ProvideDefaultName>
-    <LocationField>Enabled</LocationField>
-    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
-    <Icon>__TemplateIcon.png</Icon>
-    <PreviewImage>__PreviewImage.jpg</PreviewImage>
-  </TemplateData>
-  <TemplateContent>
-    <Project TargetFileName="CordovaWP7AppProj.csproj" File="CordovaWP7AppProj.csproj" ReplaceParameters="true">
-      <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="BuildManifestProcessor.js">BuildManifestProcessor.js</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
-      <Folder Name="cordova" TargetFolderName="cordova">
-        <ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
-        <Folder Name="lib" TargetFolderName="lib">
-          <ProjectItem ReplaceParameters="true" TargetFileName="build.js">build.js</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="clean.js">clean.js</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="deploy.js">deploy.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="log.js">log.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="target-list.js">target-list.js</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
-      </Folder>
-      <Folder Name="cordovalib" TargetFolderName="cordovalib">
-        <ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="DOMStorageHelper.cs">DOMStorageHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
-        <Folder Name="JSON" TargetFolderName="JSON">
-          <ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
-      </Folder>
-      <ProjectItem ReplaceParameters="true" TargetFileName="CordovaSourceDictionary.xml">CordovaSourceDictionary.xml</ProjectItem>
-      <Folder Name="Images" TargetFolderName="Images">
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
-      </Folder>
-      <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
-      <Folder Name="Plugins" TargetFolderName="Plugins">
-        <ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="DebugConsole.cs">DebugConsole.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
-        <Folder Name="UI" TargetFolderName="UI">
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
-        </Folder>
-      </Folder>
-      <Folder Name="Properties" TargetFolderName="Properties">
-        <ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
-      </Folder>
-      <Folder Name="resources" TargetFolderName="resources">
-        <ProjectItem ReplaceParameters="false" TargetFileName="notification-beep.wav">notification-beep.wav</ProjectItem>
-      </Folder>
-      <Folder Name="Service References" TargetFolderName="Service References" />
-      <ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
-      <Folder Name="www" TargetFolderName="www">
-        <ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
-        <Folder Name="css" TargetFolderName="css">
-          <ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
-        </Folder>
-        <Folder Name="img" TargetFolderName="img">
-          <ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
-        <Folder Name="js" TargetFolderName="js">
-          <ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
-        </Folder>
-      </Folder>
-    </Project>
-  </TemplateContent>
-</VSTemplate>
\ No newline at end of file
+	<TemplateData>
+		<Name>CordovaWP7_2_9_1</Name>
+		<Description>Starter project for building a Cordova app for Windows Phone 7.5 version: 2.9.1</Description>
+		<ProjectType>CSharp</ProjectType>
+		<ProjectSubType>
+		</ProjectSubType>
+		<SortOrder>1000</SortOrder>
+		<CreateNewFolder>true</CreateNewFolder>
+		<DefaultName>CordovaWP7_2_9_1_</DefaultName>
+		<ProvideDefaultName>true</ProvideDefaultName>
+		<LocationField>Enabled</LocationField>
+		<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+		<Icon>__TemplateIcon.png</Icon>
+		<PreviewImage>__PreviewImage.jpg</PreviewImage>
+	</TemplateData>
+	<TemplateContent>
+		<Project TargetFileName="CordovaWP7AppProj.csproj" File="CordovaWP7AppProj.csproj" ReplaceParameters="true">
+			<ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
+			<ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
+			<ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="BuildManifestProcessor.js">BuildManifestProcessor.js</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
+			<Folder Name="cordova" TargetFolderName="cordova">
+				<Folder Name="lib" TargetFolderName="lib">
+					<ProjectItem ReplaceParameters="true" TargetFileName="build.js">build.js</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="clean.js">clean.js</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="deploy.js">deploy.js</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="log.js">log.js</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="target-list.js">target-list.js</ProjectItem>
+				</Folder>
+				<ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
+			</Folder>
+			<Folder Name="cordovalib" TargetFolderName="cordovalib">
+				<Folder Name="JSON" TargetFolderName="JSON">
+					<ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
+				</Folder>
+				<ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ConsoleHelper.cs">ConsoleHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="DOMStorageHelper.cs">DOMStorageHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="IBrowserDecorator.cs">IBrowserDecorator.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="XHRHelper.cs">XHRHelper.cs</ProjectItem>
+			</Folder>
+			<ProjectItem ReplaceParameters="true" TargetFileName="CordovaSourceDictionary.xml">CordovaSourceDictionary.xml</ProjectItem>
+			<Folder Name="Images" TargetFolderName="Images">
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
+			</Folder>
+			<ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
+			<Folder Name="Properties" TargetFolderName="Properties">
+				<ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
+			</Folder>
+			<Folder Name="Service References" TargetFolderName="Service References"/>
+			<ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
+			<ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
+			<Folder Name="www" TargetFolderName="www">
+				<ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
+				<Folder Name="css" TargetFolderName="css">
+					<ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
+				</Folder>
+				<Folder Name="img" TargetFolderName="img">
+					<ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
+				</Folder>
+				<ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
+				<Folder Name="js" TargetFolderName="js">
+					<ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
+				</Folder>
+			</Folder>
+			<Folder Name="Plugins" TargetFolderName="Plugins">
+				<ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
+				<Folder Name="UI" TargetFolderName="UI">
+					<ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
+				</Folder>
+			</Folder>
+		</Project>
+	</TemplateContent>
+</VSTemplate>
diff --git a/wp7/template/Properties/WMAppManifest.xml b/wp7/template/Properties/WMAppManifest.xml
index 96332e1..bea7076 100644
--- a/wp7/template/Properties/WMAppManifest.xml
+++ b/wp7/template/Properties/WMAppManifest.xml
@@ -9,20 +9,7 @@
     
     <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
     <Capabilities>
-      <Capability Name="ID_CAP_IDENTITY_DEVICE" />
-      <Capability Name="ID_CAP_IDENTITY_USER" />
-      <Capability Name="ID_CAP_LOCATION" />
-      <Capability Name="ID_CAP_NETWORKING" />
-      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
-      <Capability Name="ID_CAP_APPOINTMENTS"/>
-      <Capability Name="ID_CAP_CONTACTS"/>
-      <Capability Name="ID_CAP_ISV_CAMERA"/>
-      <Capability Name="ID_CAP_MEDIALIB"/>
-      <Capability Name="ID_CAP_MICROPHONE"/>
-      <Capability Name="ID_CAP_PHONEDIALER"/>
-      <Capability Name="ID_CAP_PUSH_NOTIFICATION"/>
-      <Capability Name="ID_CAP_SENSORS"/>
-      <Capability Name="ID_HW_FRONTCAMERA"/>      
+      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />   
     </Capabilities>
     
     <Tasks>
diff --git a/wp7/template/config.xml b/wp7/template/config.xml
index d1ef04b..a5f7010 100644
--- a/wp7/template/config.xml
+++ b/wp7/template/config.xml
@@ -20,68 +20,52 @@
 #
 -->
 <widget>
-
-  <features>
-    <feature name="Device">
-      <param name="wp-package" value="Device" onload="false"/>
-    </feature>
-    <feature name="Logger">
-      <param name="wp-package" value="Logger"/>
-    </feature>
-    <feature name="Compass">
-      <param name="wp-package" value="Compass" />
-    </feature>
-    <feature name="Accelerometer">
-      <param name="wp-package" value="Accelerometer"/>
-    </feature>
-    <feature name="Camera">
-      <param name="wp-package" value="Camera"/>
-    </feature>
-    <feature name="NetworkStatus">
-      <param name="wp-package" value="NetworkStatus"/>
-    </feature>
-    <feature name="Contacts">
-      <param name="wp-package" value="Contacts"/>
-    </feature>
-    <feature name="DebugConsole">
-      <param name="wp-package" value="DebugConsole"/>
-    </feature>
-    <feature name="Echo">
-      <param name="wp-package" value="Echo"/>
-    </feature>
-    <feature name="File">
-      <param name="wp-package" value="File"/>
-    </feature>
-    <feature name="FileTransfer">
-      <param name="wp-package" value="FileTransfer"/>
-    </feature>
-    <feature name="Geolocation">
-      <param name="wp-package" value="Geolocation"/>
-    </feature>
-    <feature name="Media">
-      <param name="wp-package" value="Media"/>
-    </feature>
-    <feature name="Capture">
-      <param name="wp-package" value="Capture"/>
-    </feature>
-    <feature name="SplashScreen">
-      <param name="wp-package" value="SplashScreen"/>
-    </feature>
-    <feature name="Battery">
-      <param name="wp-package" value="Battery"/>
-    </feature>
-    <feature name="Globalization">
-      <param name="wp-package" value="Globalization"/>
-    </feature>
-    <feature name="InAppBrowser">
-      <param name="wp-package" value="InAppBrowser"/>
-    </feature>
-    <feature name="Notification">
-      <param name="wp-package" value="Notification"/>
-    </feature>
-  </features>
-
-
-  <access origin="*"/>
-
+    <access origin="*"/>
+    <features>
+        <feature name="Device">
+            <param name="wp-package" value="Device" onload="false"/>
+        </feature>
+        <feature name="Compass">
+            <param name="wp-package" value="Compass" />
+        </feature>
+        <feature name="Accelerometer">
+            <param name="wp-package" value="Accelerometer"/>
+        </feature>
+        <feature name="Camera">
+            <param name="wp-package" value="Camera"/>
+        </feature>
+        <feature name="NetworkStatus">
+            <param name="wp-package" value="NetworkStatus"/>
+        </feature>
+        <feature name="Contacts">
+            <param name="wp-package" value="Contacts"/>
+        </feature>
+        <feature name="File">
+            <param name="wp-package" value="File"/>
+        </feature>
+        <feature name="FileTransfer">
+            <param name="wp-package" value="FileTransfer"/>
+        </feature>
+        <feature name="Geolocation">
+            <param name="wp-package" value="Geolocation"/>
+        </feature>
+        <feature name="Media">
+            <param name="wp-package" value="Media"/>
+        </feature>
+        <feature name="Capture">
+            <param name="wp-package" value="Capture"/>
+        </feature>
+        <feature name="Battery">
+            <param name="wp-package" value="Battery"/>
+        </feature>
+        <feature name="Globalization">
+            <param name="wp-package" value="Globalization"/>
+        </feature>
+        <feature name="InAppBrowser">
+            <param name="wp-package" value="InAppBrowser"/>
+        </feature>
+        <feature name="Notification">
+            <param name="wp-package" value="Notification"/>
+        </feature>
+    </features>
 </widget>
diff --git a/wp7/template/cordova/build.bat b/wp7/template/cordova/build.bat
index b48598a..06a321a 100644
--- a/wp7/template/cordova/build.bat
+++ b/wp7/template/cordova/build.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\build.js (
-    cscript "%full_path%lib\build.js" %* //nologo
+SET script_path="%~dp0lib\build.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'build.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/clean.bat b/wp7/template/cordova/clean.bat
index 1bafe1b..f637470 100644
--- a/wp7/template/cordova/clean.bat
+++ b/wp7/template/cordova/clean.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\clean.js (
-    cscript "%full_path%lib\clean.js" %* //nologo
+SET script_path="%~dp0lib\clean.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'clean.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/lib/build.js b/wp7/template/cordova/lib/build.js
index 1375c54..bd7c494 100644
--- a/wp7/template/cordova/lib/build.js
+++ b/wp7/template/cordova/lib/build.js
@@ -66,6 +66,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in build.js : " + command);
         Log(line, true);
         WScript.Quit(2);
     }
@@ -78,7 +79,7 @@
         var proj_files = new Enumerator(proj_folder.Files);
         for (;!proj_files.atEnd(); proj_files.moveNext()) {
             if (fso.GetExtensionName(proj_files.item()) == 'csproj') {
-                return true;  
+                return true;
             }
         }
     }
@@ -100,13 +101,17 @@
 
 // builds the project and .xap in release mode
 function build_xap_release(path) {
+
+    exec_verbose('%comspec% /c "' + path + '\\cordova\\clean"');
+
     Log("Building Cordova-WP7 Project:");
     Log("\tConfiguration : Release");
     Log("\tDirectory : " + path);
-    
+
     wscript_shell.CurrentDirectory = path;
-    exec_verbose('msbuild ' + get_solution_name(path) + ' /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Release');
-    
+    var cmd = 'msbuild "' + get_solution_name(path) + '" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Release';
+    exec_verbose(cmd);
+
     // check if file xap was created
     if (fso.FolderExists(path + '\\Bin\\Release')) {
         var out_folder = fso.GetFolder(path + '\\Bin\\Release');
@@ -114,7 +119,7 @@
         for (;!out_files.atEnd(); out_files.moveNext()) {
             if (fso.GetExtensionName(out_files.item()) == 'xap') {
                 Log("BUILD SUCCESS.");
-                return;  
+                return;
             }
         }
     }
@@ -124,13 +129,17 @@
 
 // builds the project and .xap in debug mode
 function build_xap_debug(path) {
+
+    exec_verbose('%comspec% /c "' + path + '\\cordova\\clean"');
+
     Log("Building Cordova-WP7 Project:");
     Log("\tConfiguration : Debug");
     Log("\tDirectory : " + path);
-    
+
     wscript_shell.CurrentDirectory = path;
-    exec_verbose('msbuild ' + get_solution_name(path) + ' /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Debug');
-    
+    var cmd = 'msbuild "' + get_solution_name(path) + '" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Debug';
+    exec_verbose(cmd);
+
     // check if file xap was created
     if (fso.FolderExists(path + '\\Bin\\Debug')) {
         var out_folder = fso.GetFolder(path + '\\Bin\\Debug');
@@ -138,7 +147,7 @@
         for (;!out_files.atEnd(); out_files.moveNext()) {
             if (fso.GetExtensionName(out_files.item()) == 'xap') {
                 Log("BUILD SUCCESS.");
-                return;  
+                return;
             }
         }
     }
@@ -169,11 +178,9 @@
         }
 
         if (args(0) == "--debug" || args(0) == "-d") {
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\clean');
             build_xap_debug(ROOT);
         }
         else if (args(0) == "--release" || args(0) == "-r") {
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\clean');
             build_xap_release(ROOT);
         }
         else {
diff --git a/wp7/template/cordova/lib/deploy.js b/wp7/template/cordova/lib/deploy.js
index 448fa78..0599765 100644
--- a/wp7/template/cordova/lib/deploy.js
+++ b/wp7/template/cordova/lib/deploy.js
@@ -106,6 +106,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in deploy.js : " + command);
         Log(line, true);
         WScript.Quit(2);
     }
@@ -144,7 +145,7 @@
         if (fso.FolderExists(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\Bin')) {
             fso.DeleteFolder(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\Bin');
         }
-        exec_verbose('msbuild ' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln');
+        exec_verbose('msbuild "' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln"');
 
         if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
             Log('CordovaDeploy.exe compiled, SUCCESS.');
@@ -167,7 +168,7 @@
     if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
         Log('Deploying to device ...');
         //TODO: get device ID from list-devices and deploy to first one
-        exec_verbose('%comspec% /c ' + path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:0');
+        exec_verbose('"' + path + CORDOVA_DEPLOY_EXE + '" "' + path + '" -d:0');
     }
     else
     {
@@ -184,7 +185,7 @@
     if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
         Log('Deploying to emulator ...');
         //TODO: get emulator ID from list-emulators and deploy to first one
-        exec_verbose('%comspec% /c ' + path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:1');
+        exec_verbose('"' + path + CORDOVA_DEPLOY_EXE + '" "' + path + '" -d:1');
     }
     else
     {
@@ -239,16 +240,16 @@
 function build(path) {
     switch (build_type) {
         case DEBUG :
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --debug');
+            exec_verbose('%comspec% /c "' + ROOT + '\\cordova\\build" --debug');
             break;
         case RELEASE :
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --release');
+            exec_verbose('%comspec% /c "' + ROOT + '\\cordova\\build" --release');
             break;
         case NO_BUILD :
             break;
         case NONE :
             Log("WARNING: [ --debug | --release | --nobuild ] not specified, defaulting to --debug.");
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --debug');
+            exec_verbose('%comspec% /c "' + ROOT + '\\cordova\\build" --debug');
             break;
         default :
             Log("Build option not recognized: " + build_type, true);
diff --git a/wp7/template/cordova/lib/install-device.bat b/wp7/template/cordova/lib/install-device.bat
index 9507c36..b953743 100644
--- a/wp7/template/cordova/lib/install-device.bat
+++ b/wp7/template/cordova/lib/install-device.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%deploy.js (
-    cscript "%full_path%deploy.js" %* --device --nobuild //nologo
+SET script_path="%~dp0deploy.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --device --nobuild //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/lib/install-emulator.bat b/wp7/template/cordova/lib/install-emulator.bat
index b3ee451..5df933b 100644
--- a/wp7/template/cordova/lib/install-emulator.bat
+++ b/wp7/template/cordova/lib/install-emulator.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%deploy.js (
-    cscript "%full_path%deploy.js" %* --emulator --nobuild //nologo
+SET script_path="%~dp0deploy.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --emulator --nobuild //nologo
 ) ELSE (
     ECHO. 
     ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/lib/list-devices.bat b/wp7/template/cordova/lib/list-devices.bat
index bf4492b..d2158c6 100644
--- a/wp7/template/cordova/lib/list-devices.bat
+++ b/wp7/template/cordova/lib/list-devices.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%target-list.js (
-    cscript "%full_path%target-list.js" %* --devices //nologo
+SET script_path="%~dp0target-list.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --devices //nologo
 ) ELSE (
     ECHO. 
     ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/lib/list-emulator-images.bat b/wp7/template/cordova/lib/list-emulator-images.bat
index 3f571c7..44b52ef 100644
--- a/wp7/template/cordova/lib/list-emulator-images.bat
+++ b/wp7/template/cordova/lib/list-emulator-images.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%target-list.js (
-    cscript "%full_path%target-list.js" %* --emulators //nologo
+SET script_path="%~dp0target-list.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --emulators //nologo
 ) ELSE (
     ECHO. 
     ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/lib/target-list.js b/wp7/template/cordova/lib/target-list.js
index 805eea5..c899a27 100644
--- a/wp7/template/cordova/lib/target-list.js
+++ b/wp7/template/cordova/lib/target-list.js
@@ -70,6 +70,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in target-list.js : " + command);
         Log(line, true);
         WScript.Quit(2);
     }
@@ -167,7 +168,7 @@
         if (fso.FolderExists(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\Bin")) {
             fso.DeleteFolder(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\Bin");
         }
-        exec('msbuild ' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln');
+        exec('msbuild "' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln"');
 
         if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
             return;
diff --git a/wp7/template/cordova/run.bat b/wp7/template/cordova/run.bat
index b966856..c8ad0a9 100644
--- a/wp7/template/cordova/run.bat
+++ b/wp7/template/cordova/run.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\deploy.js (
-        cscript "%full_path%lib\deploy.js" %* //nologo
+SET script_path="%~dp0lib\deploy.js"
+IF EXIST %script_path% (
+        cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
diff --git a/wp7/template/cordova/version.bat b/wp7/template/cordova/version.bat
index 714e876..68cf7d1 100644
--- a/wp7/template/cordova/version.bat
+++ b/wp7/template/cordova/version.bat
@@ -1,9 +1,9 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST "%full_path%..\VERSION" (
-    type "%full_path%..\VERSION"
+SET script_path="%~dp0..\VERSION"
+IF EXIST %script_path% (
+    type %script_path%
 ) ELSE (
     ECHO.
-    ECHO ERROR: Could not find file VERSION in project folder
+    ECHO ERROR: Could not find file VERSION in project folder, path tried was %script_path% >&2
     EXIT /B 1
 )
\ No newline at end of file
diff --git a/wp7/template/cordovalib/ConfigHandler.cs b/wp7/template/cordovalib/ConfigHandler.cs
index fe646c7..cfdd007 100644
--- a/wp7/template/cordovalib/ConfigHandler.cs
+++ b/wp7/template/cordovalib/ConfigHandler.cs
@@ -83,7 +83,7 @@
                 Uri uri = new Uri(origin.Replace("*", "replaced-text"), UriKind.Absolute);
 
                 string tempHostName = uri.Host.Replace("replaced-text", "*");
-                //if (uri.HostNameType == UriHostNameType.Dns){}        
+                //if (uri.HostNameType == UriHostNameType.Dns){}
                 // starts with wildcard match - we make the first '.' optional (so '*.org.apache.cordova' will match 'org.apache.cordova')
                 if (tempHostName.StartsWith("*."))
                 {    //"(\\s{0}|*.)"
@@ -107,15 +107,15 @@
 
         }
 
-        /**   
-         
+        /**
+
          An access request is granted for a given URI if there exists an item inside the access-request list such that:
 
             - The URI's scheme component is the same as scheme; and
             - if subdomains is false or if the URI's host component is not a domain name (as defined in [RFC1034]), the URI's host component is the same as host; or
             - if subdomains is true, the URI's host component is either the same as host, or is a subdomain of host (as defined in [RFC1034]); and
             - the URI's port component is the same as port.
-         
+
          **/
 
         public bool URLIsAllowed(string url)
@@ -162,6 +162,18 @@
             return false;
         }
 
+        public string[] AutoloadPlugins
+        {
+            get
+            {
+                // TODO:
+                var res = from results in AllowedPlugins.TakeWhile(p => p.Value.isAutoLoad)
+                          select results.Value.Name;
+
+                return new string[] { "", "" };
+            }
+        }
+
         public bool IsPluginAllowed(string key)
         {
             return AllowAllPlugins || AllowedPlugins.Keys.Contains(key);
@@ -169,7 +181,6 @@
 
         private void LoadPluginFeatures(XDocument document)
         {
-<<<<<<< HEAD
             var plugins = from results in document.Descendants("plugin")
                           select new
                           {
@@ -192,12 +203,9 @@
                 }
             }
 
-            var features = document.Descendants("feature");
-=======
             var features = from f in document.Descendants()
                            where f.Name.LocalName == "feature"
                            select f;
->>>>>>> 7944b67... [CB-4807] Handle config.xml namespaces
 
 
             foreach (var feature in features)
diff --git a/wp7/template/cordovalib/ConsoleHelper.cs b/wp7/template/cordovalib/ConsoleHelper.cs
new file mode 100644
index 0000000..c7bc8df
--- /dev/null
+++ b/wp7/template/cordovalib/ConsoleHelper.cs
@@ -0,0 +1,37 @@
+using Microsoft.Phone.Controls;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    class ConsoleHelper : IBrowserDecorator
+    {
+
+        public WebBrowser Browser { get; set; }
+
+        public void InjectScript() 
+        {
+            string script = @"(function(win) {
+        function exec(msg) { window.external.Notify('ConsoleLog/' + msg); }
+        var cons = win.console = win.console || {};
+        cons.log = exec;
+        cons.debug = cons.debug || cons.log;
+        cons.info = cons.info   || function(msg) { exec('INFO:' + msg ); };     
+        cons.warn = cons.warn   || function(msg) { exec('WARN:' + msg ); };
+        cons.error = cons.error || function(msg) { exec('ERROR:' + msg ); };
+    })(window);";
+
+           Browser.InvokeScript("execScript", new string[] { script });
+        }
+
+        public bool HandleCommand(string commandStr)
+        {
+            Debug.WriteLine(commandStr.Substring("ConsoleLog/".Length));
+            return true;
+        }
+
+    }
+}
diff --git a/wp7/template/cordovalib/CordovaCommandCall.cs b/wp7/template/cordovalib/CordovaCommandCall.cs
index 810f5e2..a8851fd 100644
--- a/wp7/template/cordovalib/CordovaCommandCall.cs
+++ b/wp7/template/cordovalib/CordovaCommandCall.cs
@@ -44,6 +44,7 @@
         /// <returns>New class instance or null of string does not represent Cordova command</returns>
         public static CordovaCommandCall Parse(string commandStr)
         {
+            //System.Diagnostics.Debug.WriteLine("CommandString : " + commandStr);
             if (string.IsNullOrEmpty(commandStr))
             {
                 return null;
diff --git a/wp7/template/cordovalib/CordovaView.xaml.cs b/wp7/template/cordovalib/CordovaView.xaml.cs
index fc9eaa1..76e752b 100644
--- a/wp7/template/cordovalib/CordovaView.xaml.cs
+++ b/wp7/template/cordovalib/CordovaView.xaml.cs
@@ -1,10 +1,10 @@
-/*  
+/*
 	Licensed 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.
@@ -75,11 +75,10 @@
 
         protected BrowserMouseHelper bmHelper;
 
-        protected DOMStorageHelper domStorageHelper;
-        protected OrientationHelper orientationHelper;
-
         private ConfigHandler configHandler;
 
+        private Dictionary<string, IBrowserDecorator> browserDecorators;
+
         public System.Windows.Controls.Grid _LayoutRoot
         {
             get
@@ -162,11 +161,41 @@
                 {
                     this.StartPageUri = new Uri(AppRoot + "www/" + configHandler.ContentSrc, UriKind.Relative);
                 }
-            }  
+            }
+
+
+            browserDecorators = new Dictionary<string, IBrowserDecorator>();
 
             // initializes native execution logic
             nativeExecution = new NativeExecution(ref this.CordovaBrowser);
             bmHelper = new BrowserMouseHelper(ref this.CordovaBrowser);
+
+            CreateDecorators();
+        }
+
+        /*
+         *   browserDecorators are a collection of plugin-like classes (IBrowserDecorator) that add some bit of functionality to the browser.
+         *   These are somewhat different than plugins in that they are usually not async and patch a browser feature that we would
+         *   already expect to have.  Essentially these are browser polyfills that are patched from the outside in.
+         * */
+        void CreateDecorators()
+        {
+            XHRHelper xhrProxy = new XHRHelper();
+            xhrProxy.Browser = CordovaBrowser;
+            browserDecorators.Add("XHRLOCAL", xhrProxy);
+
+            OrientationHelper orientHelper = new OrientationHelper();
+            orientHelper.Browser = CordovaBrowser;
+            browserDecorators.Add("Orientation", orientHelper);
+
+            DOMStorageHelper storageHelper = new DOMStorageHelper();
+            storageHelper.Browser = CordovaBrowser;
+            browserDecorators.Add("DOMStorage", storageHelper);
+
+            ConsoleHelper console = new ConsoleHelper();
+            console.Browser = CordovaBrowser;
+            browserDecorators.Add("ConsoleLog", console);
+
         }
 
 
@@ -218,10 +247,6 @@
             // prevents refreshing web control to initial state during pages transitions
             if (this.IsBrowserInitialized) return;
 
-
-
-            this.domStorageHelper = new DOMStorageHelper(this.CordovaBrowser);
-
             try
             {
 
@@ -242,16 +267,14 @@
                     catch (Exception /*ex*/)
                     {
                         deviceUUID = Guid.NewGuid().ToString();
+                        Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
+                        IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
+                        using (StreamWriter writeFile = new StreamWriter(file))
+                        {
+                            writeFile.WriteLine(deviceUUID);
+                            writeFile.Close();
+                        }
                     }
-
-                    Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
-                    IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
-                    using (StreamWriter writeFile = new StreamWriter(file))
-                    {
-                        writeFile.WriteLine(deviceUUID);
-                        writeFile.Close();
-                    }
-
                 }
 
                 StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("CordovaSourceDictionary.xml", UriKind.Relative));
@@ -291,7 +314,7 @@
                                         appStorage.CreateDirectory(strBaseDir);
                                     }
 
-                                    // This will truncate/overwrite an existing file, or 
+                                    // This will truncate/overwrite an existing file, or
                                     using (IsolatedStorageFileStream outFile = appStorage.OpenFile(AppRoot + file.path, FileMode.Create))
                                     {
                                         Debug.WriteLine("INFO: Writing data for " + AppRoot + file.path + " and length = " + data.Length);
@@ -330,9 +353,6 @@
                 if (page != null)
                 {
                     page.BackKeyPress += new EventHandler<CancelEventArgs>(page_BackKeyPress);
-
-                    this.orientationHelper = new OrientationHelper(this.CordovaBrowser, page);
-
                 }
             }
         }
@@ -344,7 +364,7 @@
             {
                 try
                 {
-                    CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton');" });
+                    CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton', {}, true);" });
                     e.Cancel = true;
                 }
                 catch (Exception ex)
@@ -375,11 +395,11 @@
 
         void GapBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
         {
-            string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire()})();";
+            string nativeReady = "(function(){ window.setTimeout(function(){cordova.require('cordova/channel').onNativeReady.fire()},0) })();";
 
             try
             {
-                CordovaBrowser.InvokeScript("eval", new string[] { nativeReady });
+                CordovaBrowser.InvokeScript("execScript", new string[] { nativeReady });
             }
             catch (Exception ex)
             {
@@ -412,25 +432,21 @@
 
         /*
          *  This method does the work of routing commands
-         *  NotifyEventArgs.Value contains a string passed from JS 
+         *  NotifyEventArgs.Value contains a string passed from JS
          *  If the command already exists in our map, we will just attempt to call the method(action) specified, and pass the args along
          *  Otherwise, we create a new instance of the command, add it to the map, and call it ...
          *  This method may also receive JS error messages caught by window.onerror, in any case where the commandStr does not appear to be a valid command
          *  it is simply output to the debugger output, and the method returns.
-         * 
+         *
          **/
         void GapBrowser_ScriptNotify(object sender, NotifyEventArgs e)
         {
             string commandStr = e.Value;
+            string commandName = commandStr.Split('/').FirstOrDefault();
 
-            if (commandStr.IndexOf("DOMStorage") == 0)
+            if (browserDecorators.ContainsKey(commandName))
             {
-                this.domStorageHelper.HandleStorageCommand(commandStr);
-                return;
-            }
-            else if (commandStr.IndexOf("Orientation") == 0)
-            {
-                this.orientationHelper.HandleCommand(commandStr);
+                browserDecorators[commandName].HandleCommand(commandStr);
                 return;
             }
 
@@ -447,7 +463,7 @@
                 {
                     case "overridebackbutton":
                         string arg0 = JsonHelper.Deserialize<string[]>(commandCallParams.Args)[0];
-                        this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true"); 
+                        this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true");
                         break;
                 }
             }
@@ -466,7 +482,7 @@
 
         public void LoadPage(string url)
         {
-            try 
+            try
             {
                 Uri newLoc = new Uri(url,UriKind.RelativeOrAbsolute);
                 CordovaBrowser.Navigate(newLoc);
@@ -490,6 +506,10 @@
         private void GapBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
         {
             Debug.WriteLine("GapBrowser_Navigated :: " + e.Uri.ToString());
+            foreach (IBrowserDecorator iBD in browserDecorators.Values)
+            {
+                iBD.InjectScript();
+            }
         }
 
 
diff --git a/wp7/template/cordovalib/DOMStorageHelper.cs b/wp7/template/cordovalib/DOMStorageHelper.cs
index f57bae4..59389c6 100644
--- a/wp7/template/cordovalib/DOMStorageHelper.cs
+++ b/wp7/template/cordovalib/DOMStorageHelper.cs
@@ -27,6 +27,7 @@
 using Microsoft.Phone.Controls;
 using System.Linq;
 using WPCordovaClassLib.Cordova.JSON;
+using WPCordovaClassLib.CordovaLib;
 
 /*
  * Translates DOMStorage API between JS and Isolated Storage
@@ -35,13 +36,11 @@
 
 namespace WPCordovaClassLib
 {
-    public class DOMStorageHelper
+    public class DOMStorageHelper : IBrowserDecorator
     {
-        protected WebBrowser webBrowser1;
-
-        public DOMStorageHelper(WebBrowser gapBrowser)
+        public WebBrowser Browser { get; set; }
+        public DOMStorageHelper()
         {
-            this.webBrowser1 = gapBrowser;
             // always clear session at creation
             UserSettings["sessionStorage"] = new Dictionary<string, string>();
 
@@ -77,10 +76,137 @@
             return UserSettings[type] as Dictionary<string, string>;
         }
 
-
-        public void HandleStorageCommand(string commandStr)
+        public void InjectScript()
         {
+            string script = @"(function(win, doc) {
+var docDomain = null;
+try {
+    docDomain = doc.domain;
+} catch (err) {}
+if (!docDomain || docDomain.length === 0) {
+    var DOMStorage = function(type) {
+        if (type == 'sessionStorage') {
+            this._type = type;
+        }
+        Object.defineProperty(this, 'length', {
+            configurable: true,
+            get: function() {
+                return this.getLength();
+            }
+        });
+    };
+    DOMStorage.prototype = {
+        _type: 'localStorage',
+        _result: null,
+        keys: null,
+        onResult: function(key, valueStr) {
+            if (!this.keys) {
+                this.keys = [];
+            }
+            this._result = valueStr;
+        },
+        onKeysChanged: function(jsonKeys) {
+            this.keys = JSON.parse(jsonKeys);
+            var key;
+            for (var n = 0, len = this.keys.length; n < len; n++) {
+                key = this.keys[n];
+                if (!this.hasOwnProperty(key)) {
+                    Object.defineProperty(this, key, {
+                        configurable: true,
+                        get: function() {
+                            return this.getItem(key);
+                        },
+                        set: function(val) {
+                            return this.setItem(key, val);
+                        }
+                    });
+                }
+            }
+        },
+        initialize: function() {
+            window.external.Notify('DOMStorage/' + this._type + '/load/keys');
+        },
+        getLength: function() {
+            if (!this.keys) {
+                this.initialize();
+            }
+            return this.keys.length;
+        },
+        key: function(n) {
+            if (!this.keys) {
+                this.initialize();
+            }
+            if (n >= this.keys.length) {
+                return null;
+            } else {
+                return this.keys[n];
+            }
+        },
+        getItem: function(key) {
+            if (!this.keys) {
+                this.initialize();
+            }
+            var retVal = null;
+            if (this.keys.indexOf(key) > -1) {
+                window.external.Notify('DOMStorage/' + this._type + '/get/' + key);
+                retVal = window.unescape(decodeURIComponent(this._result));
+                this._result = null;
+            }
+            return retVal;
+        },
+        setItem: function(key, value) {
+            if (!this.keys) {
+                this.initialize();
+            }
+            window.external.Notify('DOMStorage/' + this._type + '/set/' + key + '/' + encodeURIComponent(window.escape(value)));
+        },
+        removeItem: function(key) {
+            if (!this.keys) {
+                this.initialize();
+            }
+            var index = this.keys.indexOf(key);
+            if (index > -1) {
+                this.keys.splice(index, 1);
+                window.external.Notify('DOMStorage/' + this._type + '/remove/' + key);
+                delete this[key];
+            }
+        },
+        clear: function() {
+            if (!this.keys) {
+                this.initialize();
+            }
+            for (var n = 0, len = this.keys.length; n < len; n++) {
+                delete this[this.keys[n]];
+            }
+            this.keys = [];
+            window.external.Notify('DOMStorage/' + this._type + '/clear/');
+        }
+    };
+    if (typeof window.localStorage === 'undefined') {
+        Object.defineProperty(window, 'localStorage', {
+            writable: false,
+            configurable: false,
+            value: new DOMStorage('localStorage')
+        });
+        window.localStorage.initialize();
+    }
+    if (typeof window.sessionStorage === 'undefined') {
+        Object.defineProperty(window, 'sessionStorage', {
+            writable: false,
+            configurable: false,
+            value: new DOMStorage('sessionStorage')
+        });
+        window.sessionStorage.initialize();
+    }
+}
+})(window, document);";
 
+            Browser.InvokeScript("execScript", new string[] { script });
+        }
+
+
+        public bool HandleCommand(string commandStr)
+        {
             string[] split = commandStr.Split('/');
             if (split.Length > 3)
             {
@@ -99,11 +225,11 @@
                             if (currentStorage.Keys.Contains(param))
                             {
                                 string value = currentStorage[param];
-                                webBrowser1.InvokeScript("execScript", "window." + type + ".onResult('" + param + "','" + value + "');");
+                                Browser.InvokeScript("execScript", "window." + type + ".onResult('" + param + "','" + value + "');");
                             }
                             else
                             {
-                                webBrowser1.InvokeScript("execScript", "window." + type + ".onResult('" + param + "');");
+                                Browser.InvokeScript("execScript", "window." + type + ".onResult('" + param + "');");
                             }
 
                         }
@@ -113,7 +239,7 @@
                             string[] keys = currentStorage.Keys.ToArray();
                             string jsonString = JsonHelper.Serialize(keys);
                             string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            webBrowser1.InvokeScript("execScript", callbackJS);
+                            Browser.InvokeScript("execScript", callbackJS);
                         }
                         break;
                     case "set":
@@ -124,7 +250,7 @@
                             string[] keys = currentStorage.Keys.ToArray();
                             string jsonString = JsonHelper.Serialize(keys);
                             string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            webBrowser1.InvokeScript("execScript", callbackJS);
+                            Browser.InvokeScript("execScript", callbackJS);
                         }
                         break;
                     case "remove":
@@ -139,7 +265,7 @@
                 }
 
             }
-
+            return true;
         }
     }
 }
diff --git a/wp7/template/cordovalib/IBrowserDecorator.cs b/wp7/template/cordovalib/IBrowserDecorator.cs
new file mode 100644
index 0000000..14ea815
--- /dev/null
+++ b/wp7/template/cordovalib/IBrowserDecorator.cs
@@ -0,0 +1,15 @@
+using Microsoft.Phone.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    interface IBrowserDecorator
+    {
+        WebBrowser Browser { get; set; }
+        void InjectScript();
+        bool HandleCommand(string cmd);
+    }
+}
diff --git a/wp7/template/cordovalib/ImageExifHelper.cs b/wp7/template/cordovalib/ImageExifHelper.cs
deleted file mode 100644
index 62b6462..0000000
--- a/wp7/template/cordovalib/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*  
-	Licensed 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.
- 
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class ImageExifOrientation
-    {
-        public const int Portrait = 1;
-        public const int PortraitUpsideDown = 3;
-        public const int LandscapeLeft = 6;
-        public const int LandscapeRight = 8;
-    }
-
-    public class ImageExifHelper
-    {
-
-        public static Stream RotateStream(Stream stream, int angle)
-        {
-            stream.Position = 0;
-            if (angle % 90 != 0 || angle < 0)
-            {
-                throw new ArgumentException();
-            }
-            if (angle % 360 == 0)
-            {
-                return stream;
-            }
-
-            angle = angle % 360;
-
-            BitmapImage bitmap = new BitmapImage();
-            bitmap.SetSource(stream);
-            WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
-            WriteableBitmap wbTarget = null;
-
-            int srcPixelWidth = wbSource.PixelWidth;
-            int srcPixelHeight = wbSource.PixelHeight;
-
-            if (angle % 180 == 0)
-            {
-                wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
-            }
-            else
-            {
-                wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
-            }
-
-            int destPixelWidth = wbTarget.PixelWidth;
-            int[] srcPxls = wbSource.Pixels;
-            int[] destPxls = wbTarget.Pixels;
-
-            // this ugly if/else is to avoid a conditional check for every pixel
-            if (angle == 90)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-            else if (angle == 180)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-            else if (angle == 270)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-
-            MemoryStream targetStream = new MemoryStream();
-            wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
-            return targetStream;
-        }
-
-        public static int getImageOrientationFromStream(Stream imgStream)
-        {
-
-            // 0xFFD8 : jpgHeader
-            // 0xFFE1 :
-            // 0x???? : length of exif data
-            // 0x????, 0x???? : Chars 'E','x','i','f'
-            // 0x0000 : 2 empty bytes
-            // <== mark beginning of tags SIZE:ID:VALUE
-            // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determines littleEndian-ness
-            // 0x002A : marker value
-            // 0x???? : offset to the Image File Data
-
-            // XXXX possible space before actual tag data ... we skip to mark + offset
-
-            // 0x???? number of exif tags present
-
-            // make sure we are at the beginning
-            imgStream.Seek(0, SeekOrigin.Begin);
-            BinaryReader reader = new BinaryReader(imgStream);
-
-            byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
-            byte start = reader.ReadByte(); // 0xFF
-            byte index = reader.ReadByte(); // 0xE1
-
-            while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
-            {
-                // Get the data length
-                ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-                // skip along
-                reader.ReadBytes(dLen - 2);
-                start = reader.ReadByte();
-                index = reader.ReadByte();
-            }
-
-            // It's only success if we found the 0xFFE1 marker
-            if (start != 0xFF || index != 0xE1)
-            {
-                //   throw new Exception("Could not find Exif data block");
-                Debug.WriteLine("Did not find EXIF data");
-                return 0;
-            }
-
-            // read 2 byte length of EXIF data
-            ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            String exif = ""; // build the string
-            for (var n = 0; n < 4; n++)
-            {
-                exif += reader.ReadChar();
-            }
-            if (exif != "Exif")
-            {
-                // did not find exif data ...
-                Debug.WriteLine("Did not find EXIF data");
-                return 0;
-            }
-
-            // read 2 empty bytes
-            //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            reader.ReadBytes(2);
-
-            long headerMark = reader.BaseStream.Position; // where are we now <==
-
-            //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
-            reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
-            if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
-            {
-                Debug.WriteLine("Error in data != 0x002A");
-                return 0;
-            }
-
-            // Get the offset to the IFD (image file directory)
-            ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
-            imgStream.Position = headerMark + imgOffset;
-            ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            for (ushort x = 0; x < tagCount; x++)
-            {
-                // Orientation = 0x112, aka 274
-                if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
-                {
-                    ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-                    // don't care ..
-                    uint comps = reader.ReadUInt32();
-                    byte[] tagData = reader.ReadBytes(4);
-                    int orientation = (int)tagData[0];
-                    Debug.WriteLine("orientation = " + orientation.ToString());
-                    return orientation;
-                    // 6 means rotate clockwise 90 deg
-                    // 8 means rotate counter-clockwise 90 deg
-                    // 1 means all is good
-                    // 3 means flip vertical
-                }
-                // skip to the next item, 12 bytes each
-                reader.BaseStream.Seek(10, SeekOrigin.Current);
-            }
-            return 0;
-        }
-
-    }
-}
diff --git a/wp7/template/cordovalib/NativeExecution.cs b/wp7/template/cordovalib/NativeExecution.cs
index af6b207..decc51d 100644
--- a/wp7/template/cordovalib/NativeExecution.cs
+++ b/wp7/template/cordovalib/NativeExecution.cs
@@ -133,17 +133,18 @@
                     }
                 };
 
-                if ((bc is File) || (bc is Accelerometer))
-                {
-                    // Due to some issues with the IsolatedStorage in current version of WP8 SDK we have to run all File Api commands synchronously.
-                    // TODO: test this in WP8 RTM
-                    methodInvokation.Invoke();
-                }
-                else
-                {
-                    new Thread(methodInvokation).Start();
-                }
+                //if ((bc is File) || (bc is Accelerometer))
+                //{
+                //    // Due to some issues with the IsolatedStorage in current version of WP8 SDK we have to run all File Api commands synchronously.
+                //    // TODO: test this in WP8 RTM
+                //    methodInvokation.Invoke();
+                //}
+                //else
+                //{
+                //    new Thread(methodInvokation).Start();
+                //}
 
+                new Thread(methodInvokation).Start();
 
             }
             catch (Exception ex)
diff --git a/wp7/template/cordovalib/OrientationHelper.cs b/wp7/template/cordovalib/OrientationHelper.cs
index 81a329e..5a298b2 100644
--- a/wp7/template/cordovalib/OrientationHelper.cs
+++ b/wp7/template/cordovalib/OrientationHelper.cs
@@ -23,32 +23,35 @@
 using System.Windows.Media.Animation;
 using System.Windows.Shapes;
 using Microsoft.Phone.Controls;
+using WPCordovaClassLib.CordovaLib;
 
 namespace WPCordovaClassLib.Cordova
 {
-    public class OrientationHelper
+    public class OrientationHelper : IBrowserDecorator
     {
-        protected WebBrowser gapBrowser;
-        protected PhoneApplicationPage page;
+        public WebBrowser Browser { get; set; }
+
+        public PhoneApplicationPage Page
+        {
+            get
+            {
+                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+                if (frame != null)
+                {
+                    return frame.Content as PhoneApplicationPage;
+                }
+                return null;
+            }
+        }
+
         // private PageOrientation CurrentOrientation = PageOrientation.PortraitUp;
         //private PageOrientation[] SupportedOrientations; // TODO:
 
-        public OrientationHelper(WebBrowser gapBrowser, PhoneApplicationPage gapPage)
-        {
-            this.gapBrowser = gapBrowser;
-            page = gapPage;
-
-            page.OrientationChanged += new EventHandler<OrientationChangedEventArgs>(page_OrientationChanged);
-            gapBrowser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(gapBrowser_LoadCompleted);
-
-
-        }
-
-        void gapBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
+        public void InjectScript()
         {
             int i = 0;
 
-            switch (this.page.Orientation)
+            switch (Page.Orientation)
             {
                 case PageOrientation.Portrait: // intentional fall through
                 case PageOrientation.PortraitUp:
@@ -65,12 +68,11 @@
                     i = 90;
                     break;
             }
-            // Cordova.fireEvent('orientationchange', window);
             string jsCallback = String.Format("window.orientation = {0};", i);
 
             try
             {
-                gapBrowser.InvokeScript("execScript", jsCallback);
+                Browser.InvokeScript("execScript", new string[] { jsCallback });
             }
             catch (Exception)
             {
@@ -104,23 +106,24 @@
             try
             {
 
-                gapBrowser.InvokeScript("execScript", jsCallback);
+                Browser.InvokeScript("execScript", new string[] { jsCallback });
 
                 jsCallback = "var evt = document.createEvent('HTMLEvents');";
                 jsCallback += "evt.initEvent( 'orientationchange', true, false );";
                 jsCallback += "window.dispatchEvent(evt);";
                 jsCallback += "if(window.onorientationchange){window.onorientationchange(evt);}";
 
-                gapBrowser.InvokeScript("execScript", jsCallback);
+                Browser.InvokeScript("execScript", new string[] {jsCallback});
             }
             catch (Exception)
             {
             }
         }
 
-        public void HandleCommand(string commandStr)
+        public bool HandleCommand(string commandStr)
         {
-
+            // No commands are currently accepted.
+            return true;
         }
     }
 
diff --git a/wp7/template/cordovalib/XHRHelper.cs b/wp7/template/cordovalib/XHRHelper.cs
new file mode 100644
index 0000000..d9945f3
--- /dev/null
+++ b/wp7/template/cordovalib/XHRHelper.cs
@@ -0,0 +1,270 @@
+using Microsoft.Phone.Controls;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Text;
+using System.Windows;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    public class XHRHelper : IBrowserDecorator
+    {
+
+        public WebBrowser Browser { get; set; }
+        public PhoneApplicationPage Page { get; set; }
+
+        public void InjectScript()
+        {
+
+
+            string script = @"(function(win, doc) {
+
+    var docDomain = null;
+    try {
+        docDomain = doc.domain;
+    } catch (err) {}
+
+    if (!docDomain || docDomain.length === 0) {
+
+        var aliasXHR = win.XMLHttpRequest;
+
+        var XHRShim = function() {};
+        win.XMLHttpRequest = XHRShim;
+        XHRShim.noConflict = aliasXHR;
+        XHRShim.UNSENT = 0;
+        XHRShim.OPENED = 1;
+        XHRShim.HEADERS_RECEIVED = 2;
+        XHRShim.LOADING = 3;
+        XHRShim.DONE = 4;
+        XHRShim.prototype = {
+            isAsync: false,
+            onreadystatechange: null,
+            readyState: 0,
+            _url: '',
+            timeout: 0,
+            withCredentials: false,
+            _requestHeaders: null,
+            open: function (reqType, uri, isAsync, user, password) {
+
+                if (uri && uri.indexOf('http') === 0) {
+                    if (!this.wrappedXHR) {
+                        this.wrappedXHR = new aliasXHR();
+                        var self = this;
+                        if (this.timeout > 0) {
+                            this.wrappedXHR.timeout = this.timeout;
+                        }
+                        Object.defineProperty(this, 'timeout', {
+                            set: function(val) {
+                                this.wrappedXHR.timeout = val;
+                            },
+                            get: function() {
+                                return this.wrappedXHR.timeout;
+                            }
+                        });
+                        if (this.withCredentials) {
+                            this.wrappedXHR.withCredentials = this.withCredentials;
+                        }
+                        Object.defineProperty(this, 'withCredentials', {
+                            set: function(val) {
+                                this.wrappedXHR.withCredentials = val;
+                            },
+                            get: function() {
+                                return this.wrappedXHR.withCredentials;
+                            }
+                        });
+                        Object.defineProperty(this, 'status', {
+                            get: function() {
+                                return this.wrappedXHR.status;
+                            }
+                        });
+                        Object.defineProperty(this, 'responseText', {
+                            get: function() {
+                                return this.wrappedXHR.responseText;
+                            }
+                        });
+                        Object.defineProperty(this, 'statusText', {
+                            get: function() {
+                                return this.wrappedXHR.statusText;
+                            }
+                        });
+                        Object.defineProperty(this, 'responseXML', {
+                            get: function() {
+                                return this.wrappedXHR.responseXML;
+                            }
+                        });
+                        this.getResponseHeader = function(header) {
+                            return this.wrappedXHR.getResponseHeader(header);
+                        };
+                        this.getAllResponseHeaders = function() {
+                            return this.wrappedXHR.getAllResponseHeaders();
+                        };
+                        this.wrappedXHR.onreadystatechange = function() {
+                            self.changeReadyState(self.wrappedXHR.readyState);
+                        };
+                    }
+                    return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
+                }
+                else
+                {
+                    this.isAsync = isAsync;
+                    this.reqType = reqType;
+                    this._url = uri;
+                }
+            },
+            statusText: '',
+            changeReadyState: function(newState) {
+                this.readyState = newState;
+                if (this.onreadystatechange) {
+                    this.onreadystatechange();
+                }
+                if (this.readyState == XHRShim.DONE){
+                    this.onload && this.onload();
+                }
+            },
+            setRequestHeader: function(header, value) {
+                if (this.wrappedXHR) {
+                    this.wrappedXHR.setRequestHeader(header, value);
+                }
+            },
+            getResponseHeader: function(header) {
+                return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : '';
+            },
+            getAllResponseHeaders: function() {
+                return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : '';
+            },
+            overrideMimeType: function(mimetype) {
+                return this.wrappedXHR ? this.wrappedXHR.overrideMimeType(mimetype) : '';
+            },
+            responseText: '',
+            responseXML: '',
+            onResult: function(res) {
+                this.status = 200;
+                if (typeof res == 'object') {
+                    res = JSON.stringify(res);
+                }
+                this.responseText = res;
+                this.responseXML = res;
+                this.changeReadyState(XHRShim.DONE);
+            },
+            onError: function(err) {
+                this.status = 404;
+                this.changeReadyState(XHRShim.DONE);
+            },
+            abort: function() {
+                if (this.wrappedXHR) {
+                    return this.wrappedXHR.abort();
+                }
+            },
+            send: function(data) {
+                if (this.wrappedXHR) {
+                    return this.wrappedXHR.send(data);
+                }
+                else {
+                    this.changeReadyState(XHRShim.OPENED);
+                    var alias = this;
+
+                    var root = window.location.href.split('#')[0];   // remove hash
+                    var basePath = root.substr(0,root.lastIndexOf('/')) + '/';
+
+                    var resolvedUrl = this._url.split('//').join('/').split('#')[0]; // remove hash
+
+                    var wwwFolderPath = navigator.userAgent.indexOf('MSIE 9.0') > -1 ? 'app/www/' : 'www/';
+
+                    if(resolvedUrl.indexOf('/') == 0) {
+                        //console.log('removing leading /');
+                        resolvedUrl = resolvedUrl.substr(1);
+                    }
+
+                    // handle special case where url is of form app/www but we are loaded just from /www
+                    if( resolvedUrl.indexOf('app/www') == 0 ) {
+                        resolvedUrl = window.location.protocol  + wwwFolderPath + resolvedUrl.substr(7);
+                    }
+                    else if( resolvedUrl.indexOf('www') == 0) {
+                        resolvedUrl = window.location.protocol  + wwwFolderPath + resolvedUrl.substr(4);
+                    }
+
+                    if(resolvedUrl.indexOf(':') < 0) {
+                        resolvedUrl = basePath + resolvedUrl; // consider it relative
+                    }
+
+                    var funk = function () {
+                        window.__onXHRLocalCallback = function (responseCode, responseText) {
+                            alias.status = responseCode;
+                            if (responseCode == '200') {
+                                alias.responseText = responseText;
+                            }
+                            else {
+                                alias.onerror && alias.onerror(responseCode);
+                            }
+
+                            alias.changeReadyState(XHRShim.DONE);
+                        }
+                        alias.changeReadyState(XHRShim.LOADING);
+                        window.external.Notify('XHRLOCAL/' + resolvedUrl);
+                    }
+                    if (this.isAsync) {
+                        setTimeout(funk, 0);
+                    }
+                    else {
+                        funk();
+                    }
+                }
+            },
+            status: 404
+        };
+    }
+})(window, document); ";
+
+
+            Browser.InvokeScript("execScript", new string[] { script });
+        }
+
+        public bool HandleCommand(string commandStr)
+        {
+            if (commandStr.IndexOf("XHRLOCAL") == 0)
+            {
+                string url = commandStr.Replace("XHRLOCAL/", "");
+
+                Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
+
+                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+                {
+                    if (isoFile.FileExists(uri.AbsolutePath))
+                    {
+                        using (TextReader reader = new StreamReader(isoFile.OpenFile(uri.AbsolutePath, FileMode.Open, FileAccess.Read)))
+                        {
+                            string text = reader.ReadToEnd();
+                            Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
+                            return true;
+                        }
+                    }
+                }
+
+                Uri relUri = new Uri(uri.AbsolutePath, UriKind.Relative);
+
+                var resource = Application.GetResourceStream(relUri);
+
+                if (resource == null)
+                {
+                    // 404 ?
+                    Browser.InvokeScript("__onXHRLocalCallback", new string[] { "404" });
+                    return true;
+                }
+                else
+                {
+                    using (StreamReader streamReader = new StreamReader(resource.Stream))
+                    {
+                        string text = streamReader.ReadToEnd();
+                        Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+    }
+}
diff --git a/wp7/template/cordovalib/resources/notification-beep.wav b/wp7/template/cordovalib/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
--- a/wp7/template/cordovalib/resources/notification-beep.wav
+++ /dev/null
Binary files differ
diff --git a/wp7/tooling/scripts/createTemplates.js b/wp7/tooling/scripts/createTemplates.js
index a8eccb5..5f044a0 100644
--- a/wp7/tooling/scripts/createTemplates.js
+++ b/wp7/tooling/scripts/createTemplates.js
@@ -36,8 +36,8 @@
 
 var platformRoot = WScript.ScriptFullName.split('\\tooling\\', 1);
 
-//  set with the -install switch, default false 
-var addToVS = false; 
+//  set with the -install switch, default false
+var addToVS = false;
 
 // help function
 function Usage() {
@@ -146,7 +146,7 @@
 function copyCommonItemsToTemplate() {
     var srcPath = repoRoot + '\\common';
     var destPath = platformRoot + templatePath;
-    
+
     var folder = fso.GetFolder(srcPath);
     // iterate over the files in the folder
     for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
@@ -156,7 +156,7 @@
     // iterate over the child folders in the folder
     for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
         //Log("Folder: " + srcPath + "\\" + subFlds.item().name);
-        exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " " 
+        exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " "
             + destPath + "\\" + subFlds.item().name);
     }
 }
@@ -183,7 +183,7 @@
 
     Log("Creating template .zip files for wp7");
     var templateOutFilename = repoRoot + '\\CordovaWP7_' + versionNum.replace(/\./g, '_') + '.zip';
-    
+
     // clear the destination
     deleteFileIfExists(templateOutFilename);
 
@@ -200,12 +200,39 @@
 
     copyFile(repoRoot + '\\VERSION',platformRoot + templatePath);
 
-    // update .vstemplate files for the template zips.
-    var name_regex = /CordovaWP7[_](\d+)[_](\d+)[_](\d+)(rc\d)?/g;
-    var discript_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
+    var cleanVersionName = "CordovaWP7_" + versionNum.replace(/\./g, '_');
 
-    replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', name_regex,  'CordovaWP7_' + versionNum.replace(/\./g, '_'));
-    replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', discript_regex,  "Cordova " + versionNum);
+    // Use proper XML-DOM named nodes and replace them with cordova current version
+    var projXml = WScript.CreateObject("Microsoft.XMLDOM");
+    projXml.async = false;
+    var fullTemplatePath = platformRoot + templatePath + '\\MyTemplate.vstemplate';
+    if (projXml.load(fullTemplatePath)) {
+
+        // <Name>CordovaWP7_ + versionNum.replace(/\./g, '_')</Name>
+        var xNode = projXml.selectSingleNode("VSTemplate/TemplateData/Name");
+        if(xNode != null)
+        {
+            // Log("replacing version in Name");
+            xNode.text = cleanVersionName;
+        }
+
+        // <DefaultName>CordovaWP7_ + versionNum</DefaultName>
+        xNode = projXml.selectSingleNode("VSTemplate/TemplateData/DefaultName");
+        if(xNode != null)
+        {
+            // Log("replacing version in DefaultName");
+            xNode.text = cleanVersionName  + '_';
+        }
+
+        xNode = projXml.selectSingleNode("VSTemplate/TemplateData/Description");
+        if(xNode != null)
+        {
+           xNode.text = xNode.text.replace("0.0.0", versionNum);
+        }
+        projXml.save(fullTemplatePath);
+
+    }
+
 
     zip_project(templateOutFilename, platformRoot + templatePath);
 
@@ -273,8 +300,8 @@
 
     if(args.Count() > 0) {
 
-        //Support help flags -help, --help, /? 
-        if(args(0).indexOf("-help") > -1 || 
+        //Support help flags -help, --help, /?
+        if(args(0).indexOf("-help") > -1 ||
            args(0).indexOf("/?") > -1 ) {
             Usage();
             WScript.Quit(1);
diff --git a/wp7/tooling/scripts/dist.js b/wp7/tooling/scripts/dist.js
index fe2407c..7d185ba 100644
--- a/wp7/tooling/scripts/dist.js
+++ b/wp7/tooling/scripts/dist.js
@@ -43,13 +43,13 @@
 var args = WScript.Arguments;
 Log("args = " + args);
     //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp\cordova-wp7)
-var rootPath = WScript.ScriptFullName.split('\\tooling\\', 1);
+var rootPath = WScript.ScriptFullName.split('\\wp7\\tooling\\', 1);
 Log("rootPath = " + rootPath);
 // tooling scripts
 var scriptPath = '\\tooling\\scripts';
 Log("scriptPath = " + scriptPath);
 //Get version number
-var VERSION=read(rootPath+'\\..\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
+var VERSION=read(rootPath+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
 Log("VERSION = " + VERSION);
 
 //Destination to build to
@@ -148,7 +148,7 @@
             WScript.Quit(1);
         }
         else if (args(0) == '-f') {
-          buildDestination = rootPath;
+          buildDestination = rootPath + '\\wp7';
           replace = true;
         }
         else {
diff --git a/wp7/tooling/scripts/reversion.js b/wp7/tooling/scripts/reversion.js
index 7754514..93de0bf 100644
--- a/wp7/tooling/scripts/reversion.js
+++ b/wp7/tooling/scripts/reversion.js
@@ -33,9 +33,9 @@
     //Root folder of cordova-wp7 (i.e C:\Cordova\cordova-wp7)
     ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
     //Sub folder containing templates
-    TEMPLATES_PATH = '\\templates',
+    TEMPLATE_PATH = '\\template',
     //Sub folder for standalone project
-    STANDALONE_PATH = TEMPLATES_PATH + '\\standalone',
+    STANDALONE_PATH = TEMPLATE_PATH,
     //Sub folder containing framework
     FRAMEWORK_PATH = '\\framework',
     //Subfolder containing example project
@@ -131,7 +131,7 @@
 function updateVersionNumbers() {
     WScript.StdOut.WriteLine("Updating version numbers....");
     var version_regex = /(\d+)[.](\d+)[.](\d+)(rc\d)?/;
-    replaceInFile(BUILD_DESTINATION + '\\VERSION', version_regex,  VERSION);
+    //replaceInFile(BUILD_DESTINATION + '\\VERSION', version_regex,  VERSION);
     // replace assembly versions in framework
     var framework_regex = /Description\(\"(\d+)[.](\d+)[.](\d+)(rc\d)?\"\)\]/; //Will match ("x.x.x[rcx]")]
     replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Description(\"" + VERSION + "\")]");
@@ -139,21 +139,18 @@
     replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Version(\"" + BASE_VERSION + "\")]");
 
     // update standalone project
-    exec('%comspec% /c copy /Y /V ' + BUILD_DESTINATION + "\\VERSION " + BUILD_DESTINATION + STANDALONE_PATH + "\\VERSION");
+    //exec('%comspec% /c copy /Y /V ' + BUILD_DESTINATION + "\\VERSION " + BUILD_DESTINATION + STANDALONE_PATH + "\\VERSION");
     var cordova_regex = /cordova-(\d+)[.](\d+)[.](\d+)(rc\d)?/g; //Matches *first* cordova-x.x.x[rcx] (just ad g at end to make global)
     version_regex = /return\s*\"(\d+)[.](\d+)[.](\d+)(rc\d)?/; //Matches return "x.x.x[rcx]
-    replaceInFile(BUILD_DESTINATION + CORDOVA_LIB + '\\..\\Plugins\\Device.cs', version_regex,  "return \"" + VERSION);
+    //replaceInFile(BUILD_DESTINATION + CORDOVA_LIB + '\\..\\Plugins\\Device.cs', version_regex,  "return \"" + VERSION);
 
-    // update template discription
-    version_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?\s*Windows/g; //Matches version: x.x.x[rcx]
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\description.txt', version_regex,  "Cordova " + VERSION + " Windows");
 
     // update .vstemplate files for the template zips.
     var name_regex = /CordovaWP7[_](\d+)[_](\d+)[_](\d+)(rc\d)?/g;
-    var discript_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
+    var discript_regex = /version:\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
 
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate', name_regex,  'CordovaWP7_' + VERSION.replace(/\./g, '_'));
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate', discript_regex,  "Cordova " + VERSION);
+    replaceInFile(BUILD_DESTINATION + TEMPLATE_PATH + '\\MyTemplate.vstemplate', name_regex,  'CordovaWP7_' + VERSION.replace(/\./g, '_'));
+    replaceInFile(BUILD_DESTINATION + TEMPLATE_PATH + '\\MyTemplate.vstemplate', discript_regex,  "version: " + VERSION);
 }
 
 // delete all cordova.js and generated files (templates) from old version numbers
@@ -193,15 +190,6 @@
             fso.DeleteFile(BUILD_DESTINATION + '\\' + root_folder.Item(i).Name);
         }
     }
-
-    var standalone_www = shell.NameSpace(BUILD_DESTINATION + STANDALONE_PATH + '\\www').Items();
-    for(i = 0; i < standalone_www.Count; i++)
-    {
-        if(standalone_www.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
-        {
-            fso.DeleteFile(BUILD_DESTINATION + STANDALONE_PATH + '\\www\\' + standalone_www.Item(i).Name);
-        }
-    }
 }
 
 
diff --git a/wp8/bin/check_reqs b/wp8/bin/check_reqs
old mode 100644
new mode 100755
diff --git a/wp8/bin/check_reqs.bat b/wp8/bin/check_reqs.bat
index 26e7393..19d5df1 100644
--- a/wp8/bin/check_reqs.bat
+++ b/wp8/bin/check_reqs.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%check_reqs.js (
-        cscript "%full_path%check_reqs.js" %* //nologo
+SET script_path="%~dp0check_reqs.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'check_reqs.js' in 'bin' folder, aborting...>&2
diff --git a/wp8/bin/check_reqs.js b/wp8/bin/check_reqs.js
index 492b13f..58d16cf 100644
--- a/wp8/bin/check_reqs.js
+++ b/wp8/bin/check_reqs.js
@@ -26,7 +26,7 @@
 function Usage() {
     Log("Usage: [ check_reqs | cscript check_reqs.js ]");
     Log("examples:");
-    Log("    cscript C:\\Users\\anonymous\\cordova-wp8\\bin\\check_reqs.js");
+    Log("    cscript C:\\Users\\anonymous\\cordova-wp7\\bin\\check_reqs.js");
     Log("    CordovaWindowsPhone\\bin\\check_reqs");
 
 }
@@ -43,12 +43,17 @@
 
 // gets the output from a command, failing with the given error message
 function check_command(cmd, fail_msg) {
-    var out = wscript_shell.Exec(cmd);
+    try {
+        var out = wscript_shell.Exec(cmd);
+    } catch(exception) {
+        Log(fail_msg, true);
+        WScript.Quit(1);
+    }
     while (out.Status == 0) {
         WScript.Sleep(100);
     }
 
-    //Check that command executed 
+    //Check that command executed
     if (!out.StdErr.AtEndOfStream) {
         var line = out.StdErr.ReadLine();
         Log(fail_msg, true);
@@ -73,9 +78,9 @@
  */
 function SystemRequiermentsMet() {
     var cmd = 'msbuild -version'
-    var fail_msg = 'The command `msbuild` failed. Make sure you have the latest Windows Phone SDKs installed, and the `msbuild.exe` command (inside C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319) is added to your path.'
+    var fail_msg = 'The command `msbuild` failed. Make sure you have the latest Windows Phone SDKs installed, AND have the latest .NET framework added to your path (i.e C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319).'
     var output = check_command(cmd, fail_msg);
-    var msversion = output.match(/\.NET\sFramework\,\sversion\s4\.0/);
+    var msversion = output.match(/\.NET\sFramework\,\sversion\s4\.0/i);
     if (!msversion) {
         Log('Please install the .NET Framwork v4.0.30319 (in the latest windows phone SDK\'s).', true);
         Log('Make sure the "msbuild" command in your path is pointing to  v4.0.30319 of msbuild as well (inside C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319).', true);
@@ -86,7 +91,7 @@
         cmd = 'git --version';
         fail_msg = 'The command `git` failed. Make sure you have git installed as well ad in your PATH environment so the tool can use it';
         output = check_command(cmd, fail_msg);
-        var gitVersion = output.match(/git\sversion\s1\./);
+        var gitVersion = output.match(/git\sversion\s1\./i);
         if (!gitVersion) {
             Log('Please ensure you have at least git v1 installed and added to you PATH so this tool can use it to get the latest codova.');
         }
diff --git a/wp8/bin/create.js b/wp8/bin/create.js
index ae88bf9..5232828 100644
--- a/wp8/bin/create.js
+++ b/wp8/bin/create.js
@@ -113,6 +113,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in create.js : " + command);
         Log(line, true);
         WScript.Quit(1);
     }
@@ -168,7 +169,7 @@
     }
 
     //clean up any Bin/obj or other generated files
-    exec('cscript ' + path + '\\cordova\\lib\\clean.js //nologo');
+    exec('cscript "' + path + '\\cordova\\lib\\clean.js" //nologo');
 
     // delete any .user and .sou files if any
     if (fso.FolderExists(path)) {
diff --git a/wp8/framework/WPCordovaClassLib.csproj b/wp8/framework/WPCordovaClassLib.csproj
index 55da878..a2b36f0 100644
--- a/wp8/framework/WPCordovaClassLib.csproj
+++ b/wp8/framework/WPCordovaClassLib.csproj
@@ -119,127 +119,51 @@
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
-    <Compile Include="..\templates\standalone\cordovalib\BrowserMouseHelper.cs">
+    <Compile Include="..\template\cordovalib\BrowserMouseHelper.cs">
       <Link>CordovaLib\BrowserMouseHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CommandFactory.cs">
+    <Compile Include="..\template\cordovalib\CommandFactory.cs">
       <Link>CordovaLib\CommandFactory.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\Commands\BaseCommand.cs">
+    <Compile Include="..\template\cordovalib\Commands\BaseCommand.cs">
       <Link>CordovaLib\Commands\BaseCommand.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ConfigHandler.cs">
+    <Compile Include="..\template\cordovalib\ConfigHandler.cs">
       <Link>CordovaLib\ConfigHandler.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CordovaCommandCall.cs">
+    <Compile Include="..\template\cordovalib\ConsoleHelper.cs">
+      <Link>CordovaLib\ConsoleHelper.cs</Link>
+    </Compile>
+    <Compile Include="..\template\cordovalib\CordovaCommandCall.cs">
       <Link>CordovaLib\CordovaCommandCall.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\CordovaView.xaml.cs">
+    <Compile Include="..\template\cordovalib\CordovaView.xaml.cs">
       <Link>CordovaLib\CordovaView.xaml.cs</Link>
-      <DependentUpon>CordovaView.xaml</DependentUpon>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\DOMStorageHelper.cs">
-      <Link>CordovaLib\DOMStorageHelper.cs</Link>
+    <Compile Include="..\template\cordovalib\IBrowserDecorator.cs">
+      <Link>CordovaLib\IBrowserDecorator.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\JSON\JsonHelper.cs">
+    <Compile Include="..\template\cordovalib\JSON\JsonHelper.cs">
       <Link>CordovaLib\JSON\JsonHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\NativeExecution.cs">
+    <Compile Include="..\template\cordovalib\NativeExecution.cs">
       <Link>CordovaLib\NativeExecution.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\OrientationHelper.cs">
+    <Compile Include="..\template\cordovalib\OrientationHelper.cs">
       <Link>CordovaLib\OrientationHelper.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\PluginResult.cs">
+    <Compile Include="..\template\cordovalib\PluginResult.cs">
       <Link>CordovaLib\PluginResult.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\cordovalib\ScriptCallback.cs">
+    <Compile Include="..\template\cordovalib\ScriptCallback.cs">
       <Link>CordovaLib\ScriptCallback.cs</Link>
     </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Accelerometer.cs">
-      <Link>CordovaLib\Plugins\Accelerometer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\AudioFormatsHelper.cs">
-      <Link>CordovaLib\Plugins\AudioFormatsHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\AudioPlayer.cs">
-      <Link>CordovaLib\Plugins\AudioPlayer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Battery.cs">
-      <Link>CordovaLib\Plugins\Battery.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Camera.cs">
-      <Link>CordovaLib\Plugins\Camera.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Capture.cs">
-      <Link>CordovaLib\Plugins\Capture.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Compass.cs">
-      <Link>CordovaLib\Plugins\Compass.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Contacts.cs">
-      <Link>CordovaLib\Plugins\Contacts.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\DebugConsole.cs">
-      <Link>CordovaLib\Plugins\DebugConsole.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Device.cs">
-      <Link>CordovaLib\Plugins\Device.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\File.cs">
-      <Link>CordovaLib\Plugins\File.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\FileTransfer.cs">
-      <Link>CordovaLib\Plugins\FileTransfer.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\GeoLocation.cs">
-      <Link>CordovaLib\Plugins\GeoLocation.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Globalization.cs">
-      <Link>CordovaLib\Plugins\Globalization.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\ImageExifHelper.cs">
-      <Link>CordovaLib\Plugins\ImageExifHelper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\InAppBrowser.cs">
-      <Link>CordovaLib\Plugins\InAppBrowser.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Media.cs">
-      <Link>CordovaLib\Plugins\Media.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\MimeTypeMapper.cs">
-      <Link>CordovaLib\Plugins\MimeTypeMapper.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\NetworkStatus.cs">
-      <Link>CordovaLib\Plugins\NetworkStatus.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\Notification.cs">
-      <Link>CordovaLib\Plugins\Notification.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\AudioCaptureTask.cs">
-      <Link>CordovaLib\Plugins\UI\AudioCaptureTask.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\AudioRecorder.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\AudioRecorder.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\ImageCapture.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\ImageCapture.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\NotificationBox.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\NotificationBox.xaml.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\VideoCaptureTask.cs">
-      <Link>CordovaLib\Plugins\UI\VideoCaptureTask.cs</Link>
-    </Compile>
-    <Compile Include="..\templates\standalone\Plugins\UI\VideoRecorder.xaml.cs">
-      <Link>CordovaLib\Plugins\UI\VideoRecorder.xaml.cs</Link>
+    <Compile Include="..\template\cordovalib\XHRHelper.cs">
+      <Link>CordovaLib\XHRHelper.cs</Link>
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Content Include="..\templates\standalone\cordovalib\resources\notification-beep.wav">
-      <Link>CordovaLib\resources\notification-beep.wav</Link>
-    </Content>
     <Content Include="Images\appbar.back.rest.png">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -266,31 +190,14 @@
     <Resource Include="resources\notification-beep.wav" />
   </ItemGroup>
   <ItemGroup>
-    <Page Include="..\templates\standalone\cordovalib\CordovaView.xaml">
+    <Page Include="..\template\cordovalib\CordovaView.xaml">
       <Link>CordovaLib\CordovaView.xaml</Link>
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\AudioRecorder.xaml">
-      <Link>CordovaLib\Plugins\UI\AudioRecorder.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\ImageCapture.xaml">
-      <Link>CordovaLib\Plugins\UI\ImageCapture.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\NotificationBox.xaml">
-      <Link>CordovaLib\Plugins\UI\NotificationBox.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="..\templates\standalone\Plugins\UI\VideoRecorder.xaml">
-      <Link>CordovaLib\Plugins\UI\VideoRecorder.xaml</Link>
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Plugins\" />
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
diff --git a/wp8/template/CordovaWP8AppProj.csproj b/wp8/template/CordovaWP8AppProj.csproj
index 18f5bf8..ffaf53b 100644
--- a/wp8/template/CordovaWP8AppProj.csproj
+++ b/wp8/template/CordovaWP8AppProj.csproj
@@ -123,23 +123,58 @@
     <Compile Include="App.xaml.cs">
       <DependentUpon>App.xaml</DependentUpon>
     </Compile>
+    <Compile Include="cordovalib\Commands\BaseCommand.cs" />
+    <Compile Include="cordovalib\JSON\JsonHelper.cs" />
     <Compile Include="cordovalib\BrowserMouseHelper.cs" />
     <Compile Include="cordovalib\CommandFactory.cs" />
-    <Compile Include="cordovalib\Commands\BaseCommand.cs" />
     <Compile Include="cordovalib\ConfigHandler.cs" />
+    <Compile Include="cordovalib\ConsoleHelper.cs" />
     <Compile Include="cordovalib\CordovaCommandCall.cs" />
     <Compile Include="cordovalib\CordovaView.xaml.cs">
       <DependentUpon>CordovaView.xaml</DependentUpon>
     </Compile>
-    <Compile Include="cordovalib\DOMStorageHelper.cs" />
-    <Compile Include="cordovalib\JSON\JsonHelper.cs" />
+    <Compile Include="cordovalib\IBrowserDecorator.cs" />
     <Compile Include="cordovalib\NativeExecution.cs" />
     <Compile Include="cordovalib\OrientationHelper.cs" />
     <Compile Include="cordovalib\PluginResult.cs" />
     <Compile Include="cordovalib\ScriptCallback.cs" />
+    <Compile Include="cordovalib\XHRHelper.cs" />
     <Compile Include="MainPage.xaml.cs">
       <DependentUpon>MainPage.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Plugins\Accelerometer.cs" />
+    <Compile Include="Plugins\AudioFormatsHelper.cs" />
+    <Compile Include="Plugins\AudioPlayer.cs" />
+    <Compile Include="Plugins\Battery.cs" />
+    <Compile Include="Plugins\Camera.cs" />
+    <Compile Include="Plugins\Capture.cs" />
+    <Compile Include="Plugins\Compass.cs" />
+    <Compile Include="Plugins\Contacts.cs" />
+    <Compile Include="Plugins\Device.cs" />
+    <Compile Include="Plugins\File.cs" />
+    <Compile Include="Plugins\FileTransfer.cs" />
+    <Compile Include="Plugins\GeoLocation.cs" />
+    <Compile Include="Plugins\Globalization.cs" />
+    <Compile Include="Plugins\ImageExifHelper.cs" />
+    <Compile Include="Plugins\InAppBrowser.cs" />
+    <Compile Include="Plugins\Media.cs" />
+    <Compile Include="Plugins\MimeTypeMapper.cs" />
+    <Compile Include="Plugins\NetworkStatus.cs" />
+    <Compile Include="Plugins\Notification.cs" />
+    <Compile Include="Plugins\UI\AudioCaptureTask.cs" />
+    <Compile Include="Plugins\UI\AudioRecorder.xaml.cs">
+      <DependentUpon>AudioRecorder.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Plugins\UI\ImageCapture.xaml.cs">
+      <DependentUpon>ImageCapture.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Plugins\UI\NotificationBox.xaml.cs">
+      <DependentUpon>NotificationBox.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Plugins\UI\VideoCaptureTask.cs" />
+    <Compile Include="Plugins\UI\VideoRecorder.xaml.cs">
+      <DependentUpon>VideoRecorder.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -155,23 +190,41 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Plugins\UI\AudioRecorder.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Plugins\UI\ImageCapture.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Plugins\UI\NotificationBox.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="Plugins\UI\VideoRecorder.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
   </ItemGroup>
   <ItemGroup>
+    <Content Include="config.xml" />
     <Content Include="www\cordova.js" />
+    <Content Include="www\index.html" />
     <Content Include="www\css\index.css" />
-    <Content Include="www\img\logo.png" />
-    <Content Include="www\index.html">
-      <SubType>Designer</SubType>
-    </Content>
     <Content Include="www\js\index.js" />
+    <Content Include="www\img\logo.png" />
+    <Content Include="Images\appbar.back.rest.png" />
+    <Content Include="Images\appbar.close.rest.png" />
+    <Content Include="Images\appbar.feature.video.rest.png" />
+    <Content Include="Images\appbar.next.rest.png" />
+    <Content Include="Images\appbar.save.rest.png" />
+    <Content Include="Images\appbar.stop.rest.png" />
     <None Include="cordova\lib\build.js" />
     <None Include="cordova\lib\clean.js" />
     <None Include="cordova\lib\deploy.js" />
     <None Include="cordova\lib\log.js" />
     <None Include="cordova\lib\target-list.js" />
-    <Content Include="config.xml" />
-    <Content Include="Images\**" />
-    <Content Include="resources\notification-beep.wav" />
     <None Include="cordova\build.bat" />
     <None Include="cordova\clean.bat" />
     <None Include="cordova\lib\install-device.bat" />
@@ -206,60 +259,7 @@
   <ItemGroup>
     <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Plugins\Accelerometer.cs" />
-    <Compile Include="Plugins\AudioFormatsHelper.cs" />
-    <Compile Include="Plugins\AudioPlayer.cs" />
-    <Compile Include="Plugins\Battery.cs" />
-    <Compile Include="Plugins\Camera.cs" />
-    <Compile Include="Plugins\Capture.cs" />
-    <Compile Include="Plugins\Compass.cs" />
-    <Compile Include="Plugins\Contacts.cs" />
-    <Compile Include="Plugins\DebugConsole.cs" />
-    <Compile Include="Plugins\Device.cs" />
-    <Compile Include="Plugins\File.cs" />
-    <Compile Include="Plugins\FileTransfer.cs" />
-    <Compile Include="Plugins\GeoLocation.cs" />
-    <Compile Include="Plugins\Globalization.cs" />
-    <Compile Include="Plugins\ImageExifHelper.cs" />
-    <Compile Include="Plugins\InAppBrowser.cs" />
-    <Compile Include="Plugins\Media.cs" />
-    <Compile Include="Plugins\MimeTypeMapper.cs" />
-    <Compile Include="Plugins\NetworkStatus.cs" />
-    <Compile Include="Plugins\Notification.cs" />
-    <Compile Include="Plugins\UI\AudioCaptureTask.cs" />
-    <Compile Include="Plugins\UI\AudioRecorder.xaml.cs">
-      <DependentUpon>AudioRecorder.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\ImageCapture.xaml.cs">
-      <DependentUpon>ImageCapture.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\NotificationBox.xaml.cs">
-      <DependentUpon>NotificationBox.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Plugins\UI\VideoCaptureTask.cs" />
-    <Compile Include="Plugins\UI\VideoRecorder.xaml.cs">
-      <DependentUpon>VideoRecorder.xaml</DependentUpon>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <Page Include="Plugins\UI\AudioRecorder.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\ImageCapture.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\NotificationBox.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-    <Page Include="Plugins\UI\VideoRecorder.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
diff --git a/wp8/template/MainPage.xaml b/wp8/template/MainPage.xaml
index db0d8e6..8b85fb6 100644
--- a/wp8/template/MainPage.xaml
+++ b/wp8/template/MainPage.xaml
@@ -39,14 +39,6 @@
                    Margin="0,0,0,0"  
                    x:Name="CordovaView" 
                    VerticalAlignment="Stretch" />
-        <Image Source="SplashScreenImage.jpg"
-          x:Name="SplashImage"
-          VerticalAlignment="Center"
-          HorizontalAlignment="Stretch">
-            <Image.Projection>
-                <PlaneProjection x:Name="SplashProjector"  CenterOfRotationX="0"/>
-            </Image.Projection>
-        </Image>
     </Grid>
 
 </phone:PhoneApplicationPage>
diff --git a/wp8/template/MainPage.xaml.cs b/wp8/template/MainPage.xaml.cs
index b9ec7e1..187228c 100644
--- a/wp8/template/MainPage.xaml.cs
+++ b/wp8/template/MainPage.xaml.cs
@@ -48,25 +48,6 @@
         private void CordovaView_Loaded(object sender, RoutedEventArgs e)
         {
             this.CordovaView.Loaded -= CordovaView_Loaded;
-            // first time load will have an animation
-            Storyboard _storyBoard = new Storyboard();
-            DoubleAnimation animation = new DoubleAnimation()
-            {
-                From = 0,
-                Duration = TimeSpan.FromSeconds(0.6),
-                To = 90
-            };
-            Storyboard.SetTarget(animation, SplashProjector);
-            Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
-            _storyBoard.Children.Add(animation);
-            _storyBoard.Begin();
-            _storyBoard.Completed += Splash_Completed;
-        }
-
-        void Splash_Completed(object sender, EventArgs e)
-        {
-            (sender as Storyboard).Completed -= Splash_Completed;
-            LayoutRoot.Children.Remove(SplashImage);
         }
     }
 }
diff --git a/wp8/template/MyTemplate.vstemplate b/wp8/template/MyTemplate.vstemplate
index 3f58dcc..d4a1012 100644
--- a/wp8/template/MyTemplate.vstemplate
+++ b/wp8/template/MyTemplate.vstemplate
@@ -1,133 +1,131 @@
 <VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
-  <TemplateData>
-    <Name>CordovaWP8_2_9_1</Name>
-    <Description>Starter project for building a Cordova app for Windows Phone 8 version: 2.9.0</Description>
-    <ProjectType>CSharp</ProjectType>
-    <ProjectSubType>
-    </ProjectSubType>
-    <SortOrder>1000</SortOrder>
-    <CreateNewFolder>true</CreateNewFolder>
-    <DefaultName>CordovaWP8_2_9_1</DefaultName>
-    <ProvideDefaultName>true</ProvideDefaultName>
-    <LocationField>Enabled</LocationField>
-    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
-    <Icon>__TemplateIcon.png</Icon>
-    <PreviewImage>__PreviewImage.jpg</PreviewImage>
-  </TemplateData>
-  <TemplateContent>
-    <Project TargetFileName="CordovaWP8AppProj.csproj" File="CordovaWP8AppProj.csproj" ReplaceParameters="true">
-      <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
-      <Folder Name="cordova" TargetFolderName="cordova">
-        <ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
-        <Folder Name="lib" TargetFolderName="lib">
-          <ProjectItem ReplaceParameters="true" TargetFileName="build.js">build.js</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="clean.js">clean.js</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="deploy.js">deploy.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="log.js">log.js</ProjectItem>
-          <ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="target-list.js">target-list.js</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
-      </Folder>
-      <Folder Name="cordovalib" TargetFolderName="cordovalib">
-        <ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
-        <Folder Name="Commands" TargetFolderName="Commands">
-          <ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="DOMStorageHelper.cs">DOMStorageHelper.cs</ProjectItem>
-        <Folder Name="JSON" TargetFolderName="JSON">
-          <ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
-      </Folder>
-      <Folder Name="Images" TargetFolderName="Images">
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
-        <ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
-      </Folder>
-      <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
-      <ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
-      <Folder Name="Plugins" TargetFolderName="Plugins">
-        <ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="DebugConsole.cs">DebugConsole.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
-        <Folder Name="UI" TargetFolderName="UI">
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
-          <ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
-        </Folder>
-      </Folder>
-      <Folder Name="Properties" TargetFolderName="Properties">
-        <ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
-        <ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
-      </Folder>
-      <Folder Name="resources" TargetFolderName="resources">
-        <ProjectItem ReplaceParameters="false" TargetFileName="notification-beep.wav">notification-beep.wav</ProjectItem>
-      </Folder>
-      <Folder Name="Service References" TargetFolderName="Service References" />
-      <ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
-      <ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
-      <Folder Name="www" TargetFolderName="www">
-        <ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
-        <Folder Name="css" TargetFolderName="css">
-          <ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
-        </Folder>
-        <Folder Name="img" TargetFolderName="img">
-          <ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
-        </Folder>
-        <ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
-        <Folder Name="js" TargetFolderName="js">
-          <ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
-        </Folder>
-      </Folder>
-    </Project>
-  </TemplateContent>
-</VSTemplate>
\ No newline at end of file
+	<TemplateData>
+		<Name>CordovaWP8_2_9_1</Name>
+		<Description>Starter project for building a Cordova app for Windows Phone 8 version: 2.9.1</Description>
+		<ProjectType>CSharp</ProjectType>
+		<ProjectSubType>
+		</ProjectSubType>
+		<SortOrder>1000</SortOrder>
+		<CreateNewFolder>true</CreateNewFolder>
+		<DefaultName>CordovaWP8_2.9.1</DefaultName>
+		<ProvideDefaultName>true</ProvideDefaultName>
+		<LocationField>Enabled</LocationField>
+		<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+		<Icon>__TemplateIcon.png</Icon>
+		<PreviewImage>__PreviewImage.jpg</PreviewImage>
+	</TemplateData>
+	<TemplateContent>
+		<Project TargetFileName="CordovaWP8AppProj.csproj" File="CordovaWP8AppProj.csproj" ReplaceParameters="true">
+			<ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs">App.xaml.cs</ProjectItem>
+			<ProjectItem ReplaceParameters="false" TargetFileName="ApplicationIcon.png">ApplicationIcon.png</ProjectItem>
+			<ProjectItem ReplaceParameters="false" TargetFileName="Background.png">Background.png</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="config.xml">config.xml</ProjectItem>
+			<Folder Name="cordova" TargetFolderName="cordova">
+				<ProjectItem ReplaceParameters="false" TargetFileName="build.bat">build.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="clean.bat">clean.bat</ProjectItem>
+				<Folder Name="lib" TargetFolderName="lib">
+					<ProjectItem ReplaceParameters="true" TargetFileName="build.js">build.js</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="clean.js">clean.js</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="deploy.js">deploy.js</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="install-device.bat">install-device.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="install-emulator.bat">install-emulator.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="list-devices.bat">list-devices.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="list-emulator-images.bat">list-emulator-images.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="list-started-emulators.bat">list-started-emulators.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="log.js">log.js</ProjectItem>
+					<ProjectItem ReplaceParameters="false" TargetFileName="start-emulator.bat">start-emulator.bat</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="target-list.js">target-list.js</ProjectItem>
+				</Folder>
+				<ProjectItem ReplaceParameters="false" TargetFileName="log.bat">log.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="run.bat">run.bat</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="version.bat">version.bat</ProjectItem>
+			</Folder>
+			<Folder Name="cordovalib" TargetFolderName="cordovalib">
+				<Folder Name="Commands" TargetFolderName="Commands">
+					<ProjectItem ReplaceParameters="true" TargetFileName="BaseCommand.cs">BaseCommand.cs</ProjectItem>
+				</Folder>
+				<Folder Name="JSON" TargetFolderName="JSON">
+					<ProjectItem ReplaceParameters="true" TargetFileName="JsonHelper.cs">JsonHelper.cs</ProjectItem>
+				</Folder>
+				<ProjectItem ReplaceParameters="true" TargetFileName="BrowserMouseHelper.cs">BrowserMouseHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CommandFactory.cs">CommandFactory.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ConfigHandler.cs">ConfigHandler.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ConsoleHelper.cs">ConsoleHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CordovaCommandCall.cs">CordovaCommandCall.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml">CordovaView.xaml</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="CordovaView.xaml.cs">CordovaView.xaml.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="IBrowserDecorator.cs">IBrowserDecorator.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="NativeExecution.cs">NativeExecution.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="OrientationHelper.cs">OrientationHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="PluginResult.cs">PluginResult.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ScriptCallback.cs">ScriptCallback.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="XHRHelper.cs">XHRHelper.cs</ProjectItem>
+			</Folder>
+			<Folder Name="Images" TargetFolderName="Images">
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.back.rest.png">appbar.back.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.close.rest.png">appbar.close.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.feature.video.rest.png">appbar.feature.video.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.next.rest.png">appbar.next.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.save.rest.png">appbar.save.rest.png</ProjectItem>
+				<ProjectItem ReplaceParameters="false" TargetFileName="appbar.stop.rest.png">appbar.stop.rest.png</ProjectItem>
+			</Folder>
+			<ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml">MainPage.xaml</ProjectItem>
+			<ProjectItem ReplaceParameters="true" TargetFileName="MainPage.xaml.cs">MainPage.xaml.cs</ProjectItem>
+			<Folder Name="Properties" TargetFolderName="Properties">
+				<ProjectItem ReplaceParameters="true" TargetFileName="AppManifest.xml">AppManifest.xml</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="WMAppManifest.xml">WMAppManifest.xml</ProjectItem>
+			</Folder>
+			<Folder Name="Service References" TargetFolderName="Service References"/>
+			<ProjectItem ReplaceParameters="false" TargetFileName="SplashScreenImage.jpg">SplashScreenImage.jpg</ProjectItem>
+			<ProjectItem ReplaceParameters="false" TargetFileName="VERSION">VERSION</ProjectItem>
+			<Folder Name="www" TargetFolderName="www">
+				<ProjectItem ReplaceParameters="true" TargetFileName="cordova.js">cordova.js</ProjectItem>
+				<Folder Name="css" TargetFolderName="css">
+					<ProjectItem ReplaceParameters="true" TargetFileName="index.css">index.css</ProjectItem>
+				</Folder>
+				<Folder Name="img" TargetFolderName="img">
+					<ProjectItem ReplaceParameters="false" TargetFileName="logo.png">logo.png</ProjectItem>
+				</Folder>
+				<ProjectItem ReplaceParameters="true" TargetFileName="index.html">index.html</ProjectItem>
+				<Folder Name="js" TargetFolderName="js">
+					<ProjectItem ReplaceParameters="true" TargetFileName="index.js">index.js</ProjectItem>
+				</Folder>
+			</Folder>
+			<Folder Name="Plugins" TargetFolderName="Plugins">
+				<ProjectItem ReplaceParameters="true" TargetFileName="Accelerometer.cs">Accelerometer.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="AudioFormatsHelper.cs">AudioFormatsHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="AudioPlayer.cs">AudioPlayer.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Battery.cs">Battery.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Camera.cs">Camera.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Capture.cs">Capture.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Compass.cs">Compass.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Contacts.cs">Contacts.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Device.cs">Device.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="File.cs">File.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="FileTransfer.cs">FileTransfer.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="GeoLocation.cs">GeoLocation.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Globalization.cs">Globalization.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="ImageExifHelper.cs">ImageExifHelper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="InAppBrowser.cs">InAppBrowser.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Media.cs">Media.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="MimeTypeMapper.cs">MimeTypeMapper.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="NetworkStatus.cs">NetworkStatus.cs</ProjectItem>
+				<ProjectItem ReplaceParameters="true" TargetFileName="Notification.cs">Notification.cs</ProjectItem>
+				<Folder Name="UI" TargetFolderName="UI">
+					<ProjectItem ReplaceParameters="true" TargetFileName="AudioCaptureTask.cs">AudioCaptureTask.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml">AudioRecorder.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="AudioRecorder.xaml.cs">AudioRecorder.xaml.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml">ImageCapture.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="ImageCapture.xaml.cs">ImageCapture.xaml.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml">NotificationBox.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="NotificationBox.xaml.cs">NotificationBox.xaml.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="VideoCaptureTask.cs">VideoCaptureTask.cs</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml">VideoRecorder.xaml</ProjectItem>
+					<ProjectItem ReplaceParameters="true" TargetFileName="VideoRecorder.xaml.cs">VideoRecorder.xaml.cs</ProjectItem>
+				</Folder>
+			</Folder>
+		</Project>
+	</TemplateContent>
+</VSTemplate>
diff --git a/wp8/template/Properties/WMAppManifest.xml b/wp8/template/Properties/WMAppManifest.xml
index 36f2330..9b724a1 100644
--- a/wp8/template/Properties/WMAppManifest.xml
+++ b/wp8/template/Properties/WMAppManifest.xml
@@ -7,21 +7,7 @@
   <App xmlns="" ProductID="{$guid1$}" Title="$safeprojectname$" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="$safeprojectname$ author" BitsPerPixel="32" Description="Apache Cordova for Windows Phone" Publisher="$safeprojectname$" PublisherID="{db093ed5-53b1-45f7-af72-751e8f36ab80}">
     <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
     <Capabilities>
-      <Capability Name="ID_CAP_IDENTITY_DEVICE" />
-      <Capability Name="ID_CAP_IDENTITY_USER" />
-      <Capability Name="ID_CAP_LOCATION" />
-      <Capability Name="ID_CAP_NETWORKING" />
       <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
-      <Capability Name="ID_CAP_APPOINTMENTS" />
-      <Capability Name="ID_CAP_CONTACTS" />
-      <Capability Name="ID_CAP_ISV_CAMERA" />
-      <Capability Name="ID_CAP_MICROPHONE" />
-      <Capability Name="ID_CAP_PHONEDIALER" />
-      <Capability Name="ID_CAP_PUSH_NOTIFICATION" />
-      <Capability Name="ID_CAP_SENSORS" />
-      <Capability Name="ID_CAP_MEDIALIB_AUDIO" />
-      <Capability Name="ID_CAP_MEDIALIB_PHOTO" />
-      <Capability Name="ID_CAP_MEDIALIB_PLAYBACK" />
     </Capabilities>
     <Tasks>
       <DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
diff --git a/wp8/template/config.xml b/wp8/template/config.xml
index d1ef04b..6377b34 100644
--- a/wp8/template/config.xml
+++ b/wp8/template/config.xml
@@ -20,68 +20,54 @@
 #
 -->
 <widget>
+    <access origin="*"/>
 
-  <features>
-    <feature name="Device">
-      <param name="wp-package" value="Device" onload="false"/>
-    </feature>
-    <feature name="Logger">
-      <param name="wp-package" value="Logger"/>
-    </feature>
-    <feature name="Compass">
-      <param name="wp-package" value="Compass" />
-    </feature>
-    <feature name="Accelerometer">
-      <param name="wp-package" value="Accelerometer"/>
-    </feature>
-    <feature name="Camera">
-      <param name="wp-package" value="Camera"/>
-    </feature>
-    <feature name="NetworkStatus">
-      <param name="wp-package" value="NetworkStatus"/>
-    </feature>
-    <feature name="Contacts">
-      <param name="wp-package" value="Contacts"/>
-    </feature>
-    <feature name="DebugConsole">
-      <param name="wp-package" value="DebugConsole"/>
-    </feature>
-    <feature name="Echo">
-      <param name="wp-package" value="Echo"/>
-    </feature>
-    <feature name="File">
-      <param name="wp-package" value="File"/>
-    </feature>
-    <feature name="FileTransfer">
-      <param name="wp-package" value="FileTransfer"/>
-    </feature>
-    <feature name="Geolocation">
-      <param name="wp-package" value="Geolocation"/>
-    </feature>
-    <feature name="Media">
-      <param name="wp-package" value="Media"/>
-    </feature>
-    <feature name="Capture">
-      <param name="wp-package" value="Capture"/>
-    </feature>
-    <feature name="SplashScreen">
-      <param name="wp-package" value="SplashScreen"/>
-    </feature>
-    <feature name="Battery">
-      <param name="wp-package" value="Battery"/>
-    </feature>
-    <feature name="Globalization">
-      <param name="wp-package" value="Globalization"/>
-    </feature>
-    <feature name="InAppBrowser">
-      <param name="wp-package" value="InAppBrowser"/>
-    </feature>
-    <feature name="Notification">
-      <param name="wp-package" value="Notification"/>
-    </feature>
-  </features>
-
-
-  <access origin="*"/>
+    <features>
+        <feature name="Device">
+            <param name="wp-package" value="Device" onload="false"/>
+        </feature>
+        <feature name="Compass">
+            <param name="wp-package" value="Compass" />
+        </feature>
+        <feature name="Accelerometer">
+            <param name="wp-package" value="Accelerometer"/>
+        </feature>
+        <feature name="Camera">
+            <param name="wp-package" value="Camera"/>
+        </feature>
+        <feature name="NetworkStatus">
+            <param name="wp-package" value="NetworkStatus"/>
+        </feature>
+        <feature name="Contacts">
+            <param name="wp-package" value="Contacts"/>
+        </feature>
+        <feature name="File">
+            <param name="wp-package" value="File"/>
+        </feature>
+        <feature name="FileTransfer">
+            <param name="wp-package" value="FileTransfer"/>
+        </feature>
+        <feature name="Geolocation">
+            <param name="wp-package" value="Geolocation"/>
+        </feature>
+        <feature name="Media">
+            <param name="wp-package" value="Media"/>
+        </feature>
+        <feature name="Capture">
+            <param name="wp-package" value="Capture"/>
+        </feature>
+        <feature name="Battery">
+            <param name="wp-package" value="Battery"/>
+        </feature>
+        <feature name="Globalization">
+            <param name="wp-package" value="Globalization"/>
+        </feature>
+        <feature name="InAppBrowser">
+            <param name="wp-package" value="InAppBrowser"/>
+        </feature>
+        <feature name="Notification">
+            <param name="wp-package" value="Notification"/>
+        </feature>
+    </features>
 
 </widget>
diff --git a/wp8/template/cordova/build.bat b/wp8/template/cordova/build.bat
index b48598a..06a321a 100644
--- a/wp8/template/cordova/build.bat
+++ b/wp8/template/cordova/build.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\build.js (
-    cscript "%full_path%lib\build.js" %* //nologo
+SET script_path="%~dp0lib\build.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'build.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/clean.bat b/wp8/template/cordova/clean.bat
index 1bafe1b..f637470 100644
--- a/wp8/template/cordova/clean.bat
+++ b/wp8/template/cordova/clean.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\clean.js (
-    cscript "%full_path%lib\clean.js" %* //nologo
+SET script_path="%~dp0lib\clean.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'clean.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/lib/build.js b/wp8/template/cordova/lib/build.js
index fec2d17..2c6406a 100644
--- a/wp8/template/cordova/lib/build.js
+++ b/wp8/template/cordova/lib/build.js
@@ -66,6 +66,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in build.js : " + command);
         Log(line, true);
         WScript.Quit(2);
     }
@@ -78,7 +79,7 @@
         var proj_files = new Enumerator(proj_folder.Files);
         for (;!proj_files.atEnd(); proj_files.moveNext()) {
             if (fso.GetExtensionName(proj_files.item()) == 'csproj') {
-                return true;  
+                return true;
             }
         }
     }
@@ -100,13 +101,17 @@
 
 // builds the project and .xap in release mode
 function build_xap_release(path) {
+
+    exec_verbose('%comspec% /c "' + path + '\\cordova\\clean"');
+
     Log("Building Cordova-WP8 Project:");
     Log("\tConfiguration : Release");
     Log("\tDirectory : " + path);
-    
+
     wscript_shell.CurrentDirectory = path;
-    exec_verbose('msbuild ' + get_solution_name(path) + ' /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Release');
-    
+    var cmd = 'msbuild "' + get_solution_name(path) + '" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Release';
+    exec_verbose(cmd);
+
     // check if file xap was created
     if (fso.FolderExists(path + '\\Bin\\Release')) {
         var out_folder = fso.GetFolder(path + '\\Bin\\Release');
@@ -114,7 +119,7 @@
         for (;!out_files.atEnd(); out_files.moveNext()) {
             if (fso.GetExtensionName(out_files.item()) == 'xap') {
                 Log("BUILD SUCCESS.");
-                return;  
+                return;
             }
         }
     }
@@ -124,13 +129,17 @@
 
 // builds the project and .xap in debug mode
 function build_xap_debug(path) {
+
+    exec_verbose('%comspec% /c "' + path + '\\cordova\\clean"');
+
     Log("Building Cordova-WP8 Project:");
     Log("\tConfiguration : Debug");
     Log("\tDirectory : " + path);
-    
+
     wscript_shell.CurrentDirectory = path;
-    exec_verbose('msbuild ' + get_solution_name(path) + ' /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Debug');
-    
+    var cmd = 'msbuild "' + get_solution_name(path) + '" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo /p:Configuration=Debug';
+    exec_verbose(cmd);
+
     // check if file xap was created
     if (fso.FolderExists(path + '\\Bin\\Debug')) {
         var out_folder = fso.GetFolder(path + '\\Bin\\Debug');
@@ -138,7 +147,7 @@
         for (;!out_files.atEnd(); out_files.moveNext()) {
             if (fso.GetExtensionName(out_files.item()) == 'xap') {
                 Log("BUILD SUCCESS.");
-                return;  
+                return;
             }
         }
     }
@@ -169,11 +178,9 @@
         }
 
         if (args(0) == "--debug" || args(0) == "-d") {
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\clean');
             build_xap_debug(ROOT);
         }
         else if (args(0) == "--release" || args(0) == "-r") {
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\clean');
             build_xap_release(ROOT);
         }
         else {
diff --git a/wp8/template/cordova/lib/deploy.js b/wp8/template/cordova/lib/deploy.js
index 448fa78..0599765 100644
--- a/wp8/template/cordova/lib/deploy.js
+++ b/wp8/template/cordova/lib/deploy.js
@@ -106,6 +106,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in deploy.js : " + command);
         Log(line, true);
         WScript.Quit(2);
     }
@@ -144,7 +145,7 @@
         if (fso.FolderExists(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\Bin')) {
             fso.DeleteFolder(path + CORDOVA_DEPLOY + '\\CordovaDeploy\\Bin');
         }
-        exec_verbose('msbuild ' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln');
+        exec_verbose('msbuild "' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln"');
 
         if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
             Log('CordovaDeploy.exe compiled, SUCCESS.');
@@ -167,7 +168,7 @@
     if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
         Log('Deploying to device ...');
         //TODO: get device ID from list-devices and deploy to first one
-        exec_verbose('%comspec% /c ' + path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:0');
+        exec_verbose('"' + path + CORDOVA_DEPLOY_EXE + '" "' + path + '" -d:0');
     }
     else
     {
@@ -184,7 +185,7 @@
     if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
         Log('Deploying to emulator ...');
         //TODO: get emulator ID from list-emulators and deploy to first one
-        exec_verbose('%comspec% /c ' + path + CORDOVA_DEPLOY_EXE + ' ' + path + ' -d:1');
+        exec_verbose('"' + path + CORDOVA_DEPLOY_EXE + '" "' + path + '" -d:1');
     }
     else
     {
@@ -239,16 +240,16 @@
 function build(path) {
     switch (build_type) {
         case DEBUG :
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --debug');
+            exec_verbose('%comspec% /c "' + ROOT + '\\cordova\\build" --debug');
             break;
         case RELEASE :
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --release');
+            exec_verbose('%comspec% /c "' + ROOT + '\\cordova\\build" --release');
             break;
         case NO_BUILD :
             break;
         case NONE :
             Log("WARNING: [ --debug | --release | --nobuild ] not specified, defaulting to --debug.");
-            exec_verbose('%comspec% /c ' + ROOT + '\\cordova\\build --debug');
+            exec_verbose('%comspec% /c "' + ROOT + '\\cordova\\build" --debug');
             break;
         default :
             Log("Build option not recognized: " + build_type, true);
diff --git a/wp8/template/cordova/lib/install-device.bat b/wp8/template/cordova/lib/install-device.bat
index 9507c36..b953743 100644
--- a/wp8/template/cordova/lib/install-device.bat
+++ b/wp8/template/cordova/lib/install-device.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%deploy.js (
-    cscript "%full_path%deploy.js" %* --device --nobuild //nologo
+SET script_path="%~dp0deploy.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --device --nobuild //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/lib/install-emulator.bat b/wp8/template/cordova/lib/install-emulator.bat
index b3ee451..5df933b 100644
--- a/wp8/template/cordova/lib/install-emulator.bat
+++ b/wp8/template/cordova/lib/install-emulator.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%deploy.js (
-    cscript "%full_path%deploy.js" %* --emulator --nobuild //nologo
+SET script_path="%~dp0deploy.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --emulator --nobuild //nologo
 ) ELSE (
     ECHO. 
     ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/lib/list-devices.bat b/wp8/template/cordova/lib/list-devices.bat
index bf4492b..d2158c6 100644
--- a/wp8/template/cordova/lib/list-devices.bat
+++ b/wp8/template/cordova/lib/list-devices.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%target-list.js (
-    cscript "%full_path%target-list.js" %* --devices //nologo
+SET script_path="%~dp0target-list.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --devices //nologo
 ) ELSE (
     ECHO. 
     ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/lib/list-emulator-images.bat b/wp8/template/cordova/lib/list-emulator-images.bat
index 3f571c7..44b52ef 100644
--- a/wp8/template/cordova/lib/list-emulator-images.bat
+++ b/wp8/template/cordova/lib/list-emulator-images.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%target-list.js (
-    cscript "%full_path%target-list.js" %* --emulators //nologo
+SET script_path="%~dp0target-list.js"
+IF EXIST %script_path% (
+    cscript %script_path% %* --emulators //nologo
 ) ELSE (
     ECHO. 
     ECHO ERROR: Could not find 'target-list.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/lib/target-list.js b/wp8/template/cordova/lib/target-list.js
index 805eea5..c899a27 100644
--- a/wp8/template/cordova/lib/target-list.js
+++ b/wp8/template/cordova/lib/target-list.js
@@ -70,6 +70,7 @@
     //Check to make sure our scripts did not encounter an error
     if (!oShell.StdErr.AtEndOfStream) {
         var line = oShell.StdErr.ReadAll();
+        Log("ERROR: command failed in target-list.js : " + command);
         Log(line, true);
         WScript.Quit(2);
     }
@@ -167,7 +168,7 @@
         if (fso.FolderExists(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\Bin")) {
             fso.DeleteFolder(path + CORDOVA_DEPLOY + "\\CordovaDeploy\\Bin");
         }
-        exec('msbuild ' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln');
+        exec('msbuild "' + path + CORDOVA_DEPLOY + '\\CordovaDeploy.sln"');
 
         if (fso.FileExists(path + CORDOVA_DEPLOY_EXE)) {
             return;
diff --git a/wp8/template/cordova/run.bat b/wp8/template/cordova/run.bat
index b966856..c8ad0a9 100644
--- a/wp8/template/cordova/run.bat
+++ b/wp8/template/cordova/run.bat
@@ -1,7 +1,7 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST %full_path%lib\deploy.js (
-        cscript "%full_path%lib\deploy.js" %* //nologo
+SET script_path="%~dp0lib\deploy.js"
+IF EXIST %script_path% (
+        cscript %script_path% %* //nologo
 ) ELSE (
     ECHO.
     ECHO ERROR: Could not find 'deploy.js' in cordova/lib, aborting...>&2
diff --git a/wp8/template/cordova/version.bat b/wp8/template/cordova/version.bat
index 714e876..68cf7d1 100644
--- a/wp8/template/cordova/version.bat
+++ b/wp8/template/cordova/version.bat
@@ -1,9 +1,9 @@
 @ECHO OFF
-SET full_path=%~dp0
-IF EXIST "%full_path%..\VERSION" (
-    type "%full_path%..\VERSION"
+SET script_path="%~dp0..\VERSION"
+IF EXIST %script_path% (
+    type %script_path%
 ) ELSE (
     ECHO.
-    ECHO ERROR: Could not find file VERSION in project folder
+    ECHO ERROR: Could not find file VERSION in project folder, path tried was %script_path% >&2
     EXIT /B 1
 )
\ No newline at end of file
diff --git a/wp8/template/cordovalib/ConfigHandler.cs b/wp8/template/cordovalib/ConfigHandler.cs
index f88510f..cfdd007 100644
--- a/wp8/template/cordovalib/ConfigHandler.cs
+++ b/wp8/template/cordovalib/ConfigHandler.cs
@@ -45,12 +45,22 @@
             return Preferences[key];
         }
 
-        protected static string[] AllowedSchemes = { "http", "https", "ftp", "ftps" };
+        protected static string[] AllowedSchemes = {"http","https","ftp","ftps"};
         protected bool SchemeIsAllowed(string scheme)
         {
             return AllowedSchemes.Contains(scheme);
         }
 
+        protected string PathAndQuery(Uri uri)
+        {
+            string result = uri.LocalPath;
+            if (uri.Query.Length > 0)
+            {
+                result +=  uri.Query;
+            }
+            return result;
+        }
+
         protected void AddWhiteListEntry(string origin, bool allowSubdomains)
         {
 
@@ -73,7 +83,7 @@
                 Uri uri = new Uri(origin.Replace("*", "replaced-text"), UriKind.Absolute);
 
                 string tempHostName = uri.Host.Replace("replaced-text", "*");
-                //if (uri.HostNameType == UriHostNameType.Dns){}        
+                //if (uri.HostNameType == UriHostNameType.Dns){}
                 // starts with wildcard match - we make the first '.' optional (so '*.org.apache.cordova' will match 'org.apache.cordova')
                 if (tempHostName.StartsWith("*."))
                 {    //"(\\s{0}|*.)"
@@ -83,9 +93,10 @@
                 {
                     hostName = tempHostName.Replace(".", @"\.").Replace("*", @"\w*");
                 }
+
                 //  "^https?://"
-                hostMatchingRegex = uri.Scheme + "://" + hostName + uri.PathAndQuery;
-                Debug.WriteLine("Adding regex :: " + hostMatchingRegex);
+                hostMatchingRegex = uri.Scheme + "://" + hostName + PathAndQuery(uri);
+                //Debug.WriteLine("Adding regex :: " + hostMatchingRegex);
                 AllowedDomains.Add(hostMatchingRegex);
 
             }
@@ -96,35 +107,35 @@
 
         }
 
-        /**   
-         
+        /**
+
          An access request is granted for a given URI if there exists an item inside the access-request list such that:
 
             - The URI's scheme component is the same as scheme; and
             - if subdomains is false or if the URI's host component is not a domain name (as defined in [RFC1034]), the URI's host component is the same as host; or
             - if subdomains is true, the URI's host component is either the same as host, or is a subdomain of host (as defined in [RFC1034]); and
             - the URI's port component is the same as port.
-         
+
          **/
 
         public bool URLIsAllowed(string url)
         {
             // easy case first
-            if (this.AllowAllDomains)
+            if (AllowAllDomains )
             {
                 return true;
             }
             else
             {
                 // start simple
-                Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
+                Uri uri = new Uri(url,UriKind.RelativeOrAbsolute);
                 if (uri.IsAbsoluteUri)
                 {
                     if (this.SchemeIsAllowed(uri.Scheme))
                     {
                         // additional test because our pattern will always have a trailing '/'
                         string matchUrl = url;
-                        if (uri.PathAndQuery == "/")
+                        if (PathAndQuery(uri) == "/")
                         {
                             matchUrl = url + "/";
                         }
@@ -134,8 +145,8 @@
                             {
                                 // make sure it is at the start, and not part of the query string
                                 // special case :: http://some.other.domain/page.html?x=1&g=http://build.apache.org/
-                                if (Regex.IsMatch(uri.Scheme + "://" + uri.Host + "/", pattern) ||
-                                     (!Regex.IsMatch(uri.PathAndQuery, pattern)))
+                                if ( Regex.IsMatch(uri.Scheme + "://" +  uri.Host + "/", pattern) ||
+                                     (!Regex.IsMatch(PathAndQuery(uri), pattern)))
                                 {
                                     return true;
                                 }
@@ -151,11 +162,6 @@
             return false;
         }
 
-        public bool IsPluginAllowed(string key)
-        {
-            return AllowAllPlugins || AllowedPlugins.Keys.Contains(key);
-        }
-
         public string[] AutoloadPlugins
         {
             get
@@ -164,25 +170,28 @@
                 var res = from results in AllowedPlugins.TakeWhile(p => p.Value.isAutoLoad)
                           select results.Value.Name;
 
-                return new string[] { "", "asd" };
+                return new string[] { "", "" };
             }
         }
 
+        public bool IsPluginAllowed(string key)
+        {
+            return AllowAllPlugins || AllowedPlugins.Keys.Contains(key);
+        }
+
         private void LoadPluginFeatures(XDocument document)
         {
-
-            var plugins = from results in document.Descendants()
-                          where results.Name.LocalName == "plugin"
-                          select results;
-
+            var plugins = from results in document.Descendants("plugin")
+                          select new
+                          {
+                              name = (string)results.Attribute("name"),
+                              autoLoad = results.Attribute("onload")
+                          };
 
             foreach (var plugin in plugins)
             {
-                string name = (string)plugin.Attribute("name");
-                var onload = plugin.Attribute("onload");
-
-                Debug.WriteLine("Warning: Deprecated use of <plugin> by plugin : " + name);
-                PluginConfig pConfig = new PluginConfig(name, onload != null && onload.Value == "true");
+                Debug.WriteLine("Warning: Deprecated use of <plugin> by plugin : " + plugin.name);
+                PluginConfig pConfig = new PluginConfig(plugin.name, plugin.autoLoad != null && plugin.autoLoad.Value == "true");
                 if (pConfig.Name == "*")
                 {
                     AllowAllPlugins = true;
@@ -194,9 +203,10 @@
                 }
             }
 
-            var features = from feats in document.Descendants()
-                           where feats.Name.LocalName == "feature"
-                           select feats;
+            var features = from f in document.Descendants()
+                           where f.Name.LocalName == "feature"
+                           select f;
+
 
             foreach (var feature in features)
             {
@@ -206,12 +216,12 @@
                              select results;
 
                 var value = values.FirstOrDefault();
-                if(value != null)
+                if (value != null)
                 {
                     string key = (string)value.Attribute("value");
                     Debug.WriteLine("Adding feature.value=" + key);
                     var onload = value.Attribute("onload");
-                    PluginConfig pConfig = new PluginConfig(key,onload != null && onload.Value == "true");
+                    PluginConfig pConfig = new PluginConfig(key, onload != null && onload.Value == "true");
                     AllowedPlugins[key] = pConfig;
                 }
             }
@@ -257,8 +267,8 @@
                 }
 
                 var contentsTag = (from results in document.Descendants()
-                                   where results.Name.LocalName == "content"
-                                   select results).FirstOrDefault();
+                                  where results.Name.LocalName == "content"
+                                  select results).FirstOrDefault();
 
                 if (contentsTag != null)
                 {
diff --git a/wp8/template/cordovalib/ConsoleHelper.cs b/wp8/template/cordovalib/ConsoleHelper.cs
new file mode 100644
index 0000000..c7bc8df
--- /dev/null
+++ b/wp8/template/cordovalib/ConsoleHelper.cs
@@ -0,0 +1,37 @@
+using Microsoft.Phone.Controls;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    class ConsoleHelper : IBrowserDecorator
+    {
+
+        public WebBrowser Browser { get; set; }
+
+        public void InjectScript() 
+        {
+            string script = @"(function(win) {
+        function exec(msg) { window.external.Notify('ConsoleLog/' + msg); }
+        var cons = win.console = win.console || {};
+        cons.log = exec;
+        cons.debug = cons.debug || cons.log;
+        cons.info = cons.info   || function(msg) { exec('INFO:' + msg ); };     
+        cons.warn = cons.warn   || function(msg) { exec('WARN:' + msg ); };
+        cons.error = cons.error || function(msg) { exec('ERROR:' + msg ); };
+    })(window);";
+
+           Browser.InvokeScript("execScript", new string[] { script });
+        }
+
+        public bool HandleCommand(string commandStr)
+        {
+            Debug.WriteLine(commandStr.Substring("ConsoleLog/".Length));
+            return true;
+        }
+
+    }
+}
diff --git a/wp8/template/cordovalib/CordovaCommandCall.cs b/wp8/template/cordovalib/CordovaCommandCall.cs
index facc991..a8851fd 100644
--- a/wp8/template/cordovalib/CordovaCommandCall.cs
+++ b/wp8/template/cordovalib/CordovaCommandCall.cs
@@ -44,7 +44,7 @@
         /// <returns>New class instance or null of string does not represent Cordova command</returns>
         public static CordovaCommandCall Parse(string commandStr)
         {
-            System.Diagnostics.Debug.WriteLine("CommandString : " + commandStr);
+            //System.Diagnostics.Debug.WriteLine("CommandString : " + commandStr);
             if (string.IsNullOrEmpty(commandStr))
             {
                 return null;
diff --git a/wp8/template/cordovalib/CordovaView.xaml.cs b/wp8/template/cordovalib/CordovaView.xaml.cs
index 3a88de9..a1d121a 100644
--- a/wp8/template/cordovalib/CordovaView.xaml.cs
+++ b/wp8/template/cordovalib/CordovaView.xaml.cs
@@ -1,15 +1,15 @@
-/*  
-	Licensed 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.
+/*
+    Licensed 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.
 */
 
 using System;
@@ -74,11 +74,11 @@
         private NativeExecution nativeExecution;
 
         protected BrowserMouseHelper bmHelper;
-        protected DOMStorageHelper domStorageHelper;
-        protected OrientationHelper orientationHelper;
 
         private ConfigHandler configHandler;
 
+        private Dictionary<string, IBrowserDecorator> browserDecorators;
+
         public System.Windows.Controls.Grid _LayoutRoot
         {
             get
@@ -95,6 +95,8 @@
             }
         }
 
+
+
         /*
          * Setting StartPageUri only has an effect if called before the view is loaded.
          **/
@@ -122,7 +124,7 @@
                 }
             }
         }
-       
+
         /// <summary>
         /// Gets or sets whether to suppress bouncy scrolling of
         /// the WebBrowser control;
@@ -172,14 +174,38 @@
                 else
                 {
                     this.StartPageUri = new Uri(AppRoot + "www/" + configHandler.ContentSrc, UriKind.Relative);
-                } 
-            }         
+                }
+            }
+
+            browserDecorators = new Dictionary<string, IBrowserDecorator>();
 
             nativeExecution = new NativeExecution(ref this.CordovaBrowser);
             bmHelper = new BrowserMouseHelper(ref this.CordovaBrowser);
+
+
+            CreateDecorators();
         }
 
+        /*
+         *   browserDecorators are a collection of plugin-like classes (IBrowserDecorator) that add some bit of functionality to the browser.
+         *   These are somewhat different than plugins in that they are usually not async and patch a browser feature that we would
+         *   already expect to have.  Essentially these are browser polyfills that are patched from the outside in.
+         * */
+        void CreateDecorators()
+        {
+            XHRHelper xhrProxy = new XHRHelper();
+            xhrProxy.Browser = CordovaBrowser;
+            browserDecorators.Add("XHRLOCAL", xhrProxy);
 
+            OrientationHelper orientHelper = new OrientationHelper();
+            orientHelper.Browser = CordovaBrowser;
+            browserDecorators.Add("Orientation", orientHelper);
+
+            ConsoleHelper console = new ConsoleHelper();
+            console.Browser = CordovaBrowser;
+            browserDecorators.Add("ConsoleLog", console);
+
+        }
 
         void AppClosing(object sender, ClosingEventArgs e)
         {
@@ -231,9 +257,6 @@
             if (this.IsBrowserInitialized) return;
 
 
-
-            this.domStorageHelper = new DOMStorageHelper(this.CordovaBrowser);
-
             try
             {
 
@@ -254,16 +277,14 @@
                     catch (Exception /*ex*/)
                     {
                         deviceUUID = Guid.NewGuid().ToString();
+                        Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
+                        IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
+                        using (StreamWriter writeFile = new StreamWriter(file))
+                        {
+                            writeFile.WriteLine(deviceUUID);
+                            writeFile.Close();
+                        }
                     }
-
-                    Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
-                    IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
-                    using (StreamWriter writeFile = new StreamWriter(file))
-                    {
-                        writeFile.WriteLine(deviceUUID);
-                        writeFile.Close();
-                    }
-
                 }
 
                 /*
@@ -308,7 +329,7 @@
                 //                        appStorage.CreateDirectory(strBaseDir);
                 //                    }
 
-                //                    // This will truncate/overwrite an existing file, or 
+                //                    // This will truncate/overwrite an existing file, or
                 //                    using (IsolatedStorageFileStream outFile = appStorage.OpenFile(AppRoot + file.path, FileMode.Create))
                 //                    {
                 //                        Debug.WriteLine("INFO: Writing data for " + AppRoot + file.path + " and length = " + data.Length);
@@ -347,9 +368,6 @@
                 if (page != null)
                 {
                     page.BackKeyPress += new EventHandler<CancelEventArgs>(page_BackKeyPress);
-
-                    this.orientationHelper = new OrientationHelper(this.CordovaBrowser, page);
-
                 }
             }
         }
@@ -361,7 +379,7 @@
             {
                 try
                 {
-                    CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton');" });
+                    CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton', {}, true);" });
                     e.Cancel = true;
                 }
                 catch (Exception ex)
@@ -392,10 +410,11 @@
 
         void CordovaBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
         {
+            Debug.WriteLine("CordovaBrowser_LoadCompleted");
             string[] autoloadPlugs = this.configHandler.AutoloadPlugins;
             foreach (string plugName in autoloadPlugs)
             {
-               //nativeExecution.ProcessCommand(commandCallParams); 
+                //nativeExecution.ProcessCommand(commandCallParams);
             }
 
             string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire()})();";
@@ -431,25 +450,22 @@
 
         /*
          *  This method does the work of routing commands
-         *  NotifyEventArgs.Value contains a string passed from JS 
+         *  NotifyEventArgs.Value contains a string passed from JS
          *  If the command already exists in our map, we will just attempt to call the method(action) specified, and pass the args along
          *  Otherwise, we create a new instance of the command, add it to the map, and call it ...
          *  This method may also receive JS error messages caught by window.onerror, in any case where the commandStr does not appear to be a valid command
          *  it is simply output to the debugger output, and the method returns.
-         * 
+         *
          **/
         void CordovaBrowser_ScriptNotify(object sender, NotifyEventArgs e)
         {
             string commandStr = e.Value;
 
-            if (commandStr.IndexOf("DOMStorage") == 0)
+            string commandName = commandStr.Split('/').FirstOrDefault();
+
+            if (browserDecorators.ContainsKey(commandName))
             {
-                this.domStorageHelper.HandleStorageCommand(commandStr);
-                return;
-            }
-            else if (commandStr.IndexOf("Orientation") == 0)
-            {
-                this.orientationHelper.HandleCommand(commandStr);
+                browserDecorators[commandName].HandleCommand(commandStr);
                 return;
             }
 
@@ -466,7 +482,7 @@
                 {
                     case "overridebackbutton":
                         string arg0 = JsonHelper.Deserialize<string[]>(commandCallParams.Args)[0];
-                        this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true"); 
+                        this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true");
                         break;
                 }
             }
@@ -478,7 +494,7 @@
                 }
                 else
                 {
-                    Debug.WriteLine("Error::Plugin not allowed in config.xml. " + commandCallParams.Service); 
+                    Debug.WriteLine("Error::Plugin not allowed in config.xml. " + commandCallParams.Service);
                 }
             }
         }
@@ -507,7 +523,10 @@
 
         private void CordovaBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
         {
-            Debug.WriteLine("CordovaBrowser_Navigated :: " + e.Uri.ToString());
+           foreach(IBrowserDecorator iBD in browserDecorators.Values)
+           {
+               iBD.InjectScript();
+           }
         }
 
 
diff --git a/wp8/template/cordovalib/DOMStorageHelper.cs b/wp8/template/cordovalib/DOMStorageHelper.cs
deleted file mode 100644
index 01b6273..0000000
--- a/wp8/template/cordovalib/DOMStorageHelper.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-/*  
-	Licensed 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.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.IO.IsolatedStorage;
-using System.Collections.Generic;
-using Microsoft.Phone.Controls;
-using System.Linq;
-using WPCordovaClassLib.Cordova.JSON;
-
-/*
- * Translates DOMStorage API between JS and Isolated Storage
- * Missing pieces : QUOTA_EXCEEDED_ERR  + StorageEvent  
- * */
-
-namespace WPCordovaClassLib
-{
-    public class DOMStorageHelper
-    {
-        protected WebBrowser webBrowser1;
-
-        public DOMStorageHelper(WebBrowser aBrowser)
-        {
-            this.webBrowser1 = aBrowser;
-            // always clear session at creation
-            UserSettings["sessionStorage"] = new Dictionary<string, string>();
-
-            if (!UserSettings.Contains("localStorage"))
-            {
-                UserSettings["localStorage"] = new Dictionary<string, string>();
-                UserSettings.Save();
-            }
-            Application.Current.Exit += new EventHandler(OnAppExit);
-        }
-
-        void OnAppExit(object sender, EventArgs e)
-        {
-            UserSettings.Remove("sessionStorage");
-            UserSettings.Save();
-        }
-
-        protected IsolatedStorageSettings UserSettings
-        {
-            get
-            {
-                return IsolatedStorageSettings.ApplicationSettings;
-            }
-        }
-
-        protected Dictionary<string, string> getStorageByType(string type)
-        {
-            if (!UserSettings.Contains(type))
-            {
-                UserSettings[type] = new Dictionary<string, string>();
-                UserSettings.Save();
-            }
-            return UserSettings[type] as Dictionary<string, string>;
-        }
-
-
-        public void HandleStorageCommand(string commandStr)
-        {
-
-            string[] split = commandStr.Split('/');
-            if (split.Length > 3)
-            {
-                string api = split[0];
-                string type = split[1]; // localStorage || sessionStorage
-                string command = split[2];
-                string param = split[3];
-
-                Dictionary<string, string> currentStorage = getStorageByType(type);
-
-                switch (command)
-                {
-                    case "get":
-                        {
-
-                            if (currentStorage.Keys.Contains(param))
-                            {
-                                string value = currentStorage[param];
-                                webBrowser1.InvokeScript("execScript", "window." + type + ".onResult('" + param + "','" + value + "');");
-                            }
-                            else
-                            {
-                                webBrowser1.InvokeScript("execScript", "window." + type + ".onResult('" + param + "');");
-                            }
-
-                        }
-                        break;
-                    case "load":
-                        {
-                            string[] keys = currentStorage.Keys.ToArray();
-                            string jsonString = JsonHelper.Serialize(keys);
-                            string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            webBrowser1.InvokeScript("execScript", callbackJS);
-                        }
-                        break;
-                    case "set":
-                        {
-                            // TODO: check that length is not out of bounds
-                            currentStorage[param] = split[4];
-                            UserSettings.Save();
-                            string[] keys = currentStorage.Keys.ToArray();
-                            string jsonString = JsonHelper.Serialize(keys);
-                            string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            webBrowser1.InvokeScript("execScript", callbackJS);
-                        }
-                        break;
-                    case "remove":
-                        currentStorage.Remove(param);
-                        UserSettings.Save();
-                        break;
-                    case "clear":
-                        currentStorage = new Dictionary<string, string>();
-                        UserSettings[type] = currentStorage;
-                        UserSettings.Save();
-                        break;
-                }
-
-            }
-
-        }
-    }
-}
diff --git a/wp8/template/cordovalib/IBrowserDecorator.cs b/wp8/template/cordovalib/IBrowserDecorator.cs
new file mode 100644
index 0000000..5c51680
--- /dev/null
+++ b/wp8/template/cordovalib/IBrowserDecorator.cs
@@ -0,0 +1,16 @@
+using Microsoft.Phone.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    interface IBrowserDecorator
+    {
+        WebBrowser Browser { get; set; }
+        void InjectScript();
+        bool HandleCommand(string cmd);
+    }
+}
diff --git a/wp8/template/cordovalib/NativeExecution.cs b/wp8/template/cordovalib/NativeExecution.cs
index af6b207..45ed7aa 100644
--- a/wp8/template/cordovalib/NativeExecution.cs
+++ b/wp8/template/cordovalib/NativeExecution.cs
@@ -133,17 +133,18 @@
                     }
                 };
 
-                if ((bc is File) || (bc is Accelerometer))
-                {
-                    // Due to some issues with the IsolatedStorage in current version of WP8 SDK we have to run all File Api commands synchronously.
-                    // TODO: test this in WP8 RTM
-                    methodInvokation.Invoke();
-                }
-                else
-                {
-                    new Thread(methodInvokation).Start();
-                }
+                new Thread(methodInvokation).Start();
 
+                //if ((bc is File) || (bc is Accelerometer))
+                //{
+                //    // Due to some issues with the IsolatedStorage in current version of WP8 SDK we have to run all File Api commands synchronously.
+                //    // TODO: test this in WP8 RTM
+                //    methodInvokation.Invoke();
+                //}
+                //else
+                //{
+                //    new Thread(methodInvokation).Start();
+                //}
 
             }
             catch (Exception ex)
diff --git a/wp8/template/cordovalib/OrientationHelper.cs b/wp8/template/cordovalib/OrientationHelper.cs
index 0e29b22..5a298b2 100644
--- a/wp8/template/cordovalib/OrientationHelper.cs
+++ b/wp8/template/cordovalib/OrientationHelper.cs
@@ -23,28 +23,31 @@
 using System.Windows.Media.Animation;
 using System.Windows.Shapes;
 using Microsoft.Phone.Controls;
+using WPCordovaClassLib.CordovaLib;
 
 namespace WPCordovaClassLib.Cordova
 {
-    public class OrientationHelper
+    public class OrientationHelper : IBrowserDecorator
     {
-        protected WebBrowser CordovaBrowser;
-        protected PhoneApplicationPage Page;
+        public WebBrowser Browser { get; set; }
+
+        public PhoneApplicationPage Page
+        {
+            get
+            {
+                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+                if (frame != null)
+                {
+                    return frame.Content as PhoneApplicationPage;
+                }
+                return null;
+            }
+        }
+
         // private PageOrientation CurrentOrientation = PageOrientation.PortraitUp;
         //private PageOrientation[] SupportedOrientations; // TODO:
 
-        public OrientationHelper(WebBrowser browser, PhoneApplicationPage page)
-        {
-            CordovaBrowser = browser;
-            Page = page;
-
-            Page.OrientationChanged += new EventHandler<OrientationChangedEventArgs>(page_OrientationChanged);
-            CordovaBrowser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-
-
-        }
-
-        void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
+        public void InjectScript()
         {
             int i = 0;
 
@@ -65,12 +68,11 @@
                     i = 90;
                     break;
             }
-            // Cordova.fireEvent('orientationchange', window);
             string jsCallback = String.Format("window.orientation = {0};", i);
 
             try
             {
-                CordovaBrowser.InvokeScript("execScript", jsCallback);
+                Browser.InvokeScript("execScript", new string[] { jsCallback });
             }
             catch (Exception)
             {
@@ -104,23 +106,24 @@
             try
             {
 
-                CordovaBrowser.InvokeScript("execScript", jsCallback);
+                Browser.InvokeScript("execScript", new string[] { jsCallback });
 
                 jsCallback = "var evt = document.createEvent('HTMLEvents');";
                 jsCallback += "evt.initEvent( 'orientationchange', true, false );";
                 jsCallback += "window.dispatchEvent(evt);";
                 jsCallback += "if(window.onorientationchange){window.onorientationchange(evt);}";
 
-                CordovaBrowser.InvokeScript("execScript", jsCallback);
+                Browser.InvokeScript("execScript", new string[] {jsCallback});
             }
             catch (Exception)
             {
             }
         }
 
-        public void HandleCommand(string commandStr)
+        public bool HandleCommand(string commandStr)
         {
-
+            // No commands are currently accepted.
+            return true;
         }
     }
 
diff --git a/wp8/template/cordovalib/XHRHelper.cs b/wp8/template/cordovalib/XHRHelper.cs
new file mode 100644
index 0000000..d9945f3
--- /dev/null
+++ b/wp8/template/cordovalib/XHRHelper.cs
@@ -0,0 +1,270 @@
+using Microsoft.Phone.Controls;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Text;
+using System.Windows;
+
+namespace WPCordovaClassLib.CordovaLib
+{
+    public class XHRHelper : IBrowserDecorator
+    {
+
+        public WebBrowser Browser { get; set; }
+        public PhoneApplicationPage Page { get; set; }
+
+        public void InjectScript()
+        {
+
+
+            string script = @"(function(win, doc) {
+
+    var docDomain = null;
+    try {
+        docDomain = doc.domain;
+    } catch (err) {}
+
+    if (!docDomain || docDomain.length === 0) {
+
+        var aliasXHR = win.XMLHttpRequest;
+
+        var XHRShim = function() {};
+        win.XMLHttpRequest = XHRShim;
+        XHRShim.noConflict = aliasXHR;
+        XHRShim.UNSENT = 0;
+        XHRShim.OPENED = 1;
+        XHRShim.HEADERS_RECEIVED = 2;
+        XHRShim.LOADING = 3;
+        XHRShim.DONE = 4;
+        XHRShim.prototype = {
+            isAsync: false,
+            onreadystatechange: null,
+            readyState: 0,
+            _url: '',
+            timeout: 0,
+            withCredentials: false,
+            _requestHeaders: null,
+            open: function (reqType, uri, isAsync, user, password) {
+
+                if (uri && uri.indexOf('http') === 0) {
+                    if (!this.wrappedXHR) {
+                        this.wrappedXHR = new aliasXHR();
+                        var self = this;
+                        if (this.timeout > 0) {
+                            this.wrappedXHR.timeout = this.timeout;
+                        }
+                        Object.defineProperty(this, 'timeout', {
+                            set: function(val) {
+                                this.wrappedXHR.timeout = val;
+                            },
+                            get: function() {
+                                return this.wrappedXHR.timeout;
+                            }
+                        });
+                        if (this.withCredentials) {
+                            this.wrappedXHR.withCredentials = this.withCredentials;
+                        }
+                        Object.defineProperty(this, 'withCredentials', {
+                            set: function(val) {
+                                this.wrappedXHR.withCredentials = val;
+                            },
+                            get: function() {
+                                return this.wrappedXHR.withCredentials;
+                            }
+                        });
+                        Object.defineProperty(this, 'status', {
+                            get: function() {
+                                return this.wrappedXHR.status;
+                            }
+                        });
+                        Object.defineProperty(this, 'responseText', {
+                            get: function() {
+                                return this.wrappedXHR.responseText;
+                            }
+                        });
+                        Object.defineProperty(this, 'statusText', {
+                            get: function() {
+                                return this.wrappedXHR.statusText;
+                            }
+                        });
+                        Object.defineProperty(this, 'responseXML', {
+                            get: function() {
+                                return this.wrappedXHR.responseXML;
+                            }
+                        });
+                        this.getResponseHeader = function(header) {
+                            return this.wrappedXHR.getResponseHeader(header);
+                        };
+                        this.getAllResponseHeaders = function() {
+                            return this.wrappedXHR.getAllResponseHeaders();
+                        };
+                        this.wrappedXHR.onreadystatechange = function() {
+                            self.changeReadyState(self.wrappedXHR.readyState);
+                        };
+                    }
+                    return this.wrappedXHR.open(reqType, uri, isAsync, user, password);
+                }
+                else
+                {
+                    this.isAsync = isAsync;
+                    this.reqType = reqType;
+                    this._url = uri;
+                }
+            },
+            statusText: '',
+            changeReadyState: function(newState) {
+                this.readyState = newState;
+                if (this.onreadystatechange) {
+                    this.onreadystatechange();
+                }
+                if (this.readyState == XHRShim.DONE){
+                    this.onload && this.onload();
+                }
+            },
+            setRequestHeader: function(header, value) {
+                if (this.wrappedXHR) {
+                    this.wrappedXHR.setRequestHeader(header, value);
+                }
+            },
+            getResponseHeader: function(header) {
+                return this.wrappedXHR ? this.wrappedXHR.getResponseHeader(header) : '';
+            },
+            getAllResponseHeaders: function() {
+                return this.wrappedXHR ? this.wrappedXHR.getAllResponseHeaders() : '';
+            },
+            overrideMimeType: function(mimetype) {
+                return this.wrappedXHR ? this.wrappedXHR.overrideMimeType(mimetype) : '';
+            },
+            responseText: '',
+            responseXML: '',
+            onResult: function(res) {
+                this.status = 200;
+                if (typeof res == 'object') {
+                    res = JSON.stringify(res);
+                }
+                this.responseText = res;
+                this.responseXML = res;
+                this.changeReadyState(XHRShim.DONE);
+            },
+            onError: function(err) {
+                this.status = 404;
+                this.changeReadyState(XHRShim.DONE);
+            },
+            abort: function() {
+                if (this.wrappedXHR) {
+                    return this.wrappedXHR.abort();
+                }
+            },
+            send: function(data) {
+                if (this.wrappedXHR) {
+                    return this.wrappedXHR.send(data);
+                }
+                else {
+                    this.changeReadyState(XHRShim.OPENED);
+                    var alias = this;
+
+                    var root = window.location.href.split('#')[0];   // remove hash
+                    var basePath = root.substr(0,root.lastIndexOf('/')) + '/';
+
+                    var resolvedUrl = this._url.split('//').join('/').split('#')[0]; // remove hash
+
+                    var wwwFolderPath = navigator.userAgent.indexOf('MSIE 9.0') > -1 ? 'app/www/' : 'www/';
+
+                    if(resolvedUrl.indexOf('/') == 0) {
+                        //console.log('removing leading /');
+                        resolvedUrl = resolvedUrl.substr(1);
+                    }
+
+                    // handle special case where url is of form app/www but we are loaded just from /www
+                    if( resolvedUrl.indexOf('app/www') == 0 ) {
+                        resolvedUrl = window.location.protocol  + wwwFolderPath + resolvedUrl.substr(7);
+                    }
+                    else if( resolvedUrl.indexOf('www') == 0) {
+                        resolvedUrl = window.location.protocol  + wwwFolderPath + resolvedUrl.substr(4);
+                    }
+
+                    if(resolvedUrl.indexOf(':') < 0) {
+                        resolvedUrl = basePath + resolvedUrl; // consider it relative
+                    }
+
+                    var funk = function () {
+                        window.__onXHRLocalCallback = function (responseCode, responseText) {
+                            alias.status = responseCode;
+                            if (responseCode == '200') {
+                                alias.responseText = responseText;
+                            }
+                            else {
+                                alias.onerror && alias.onerror(responseCode);
+                            }
+
+                            alias.changeReadyState(XHRShim.DONE);
+                        }
+                        alias.changeReadyState(XHRShim.LOADING);
+                        window.external.Notify('XHRLOCAL/' + resolvedUrl);
+                    }
+                    if (this.isAsync) {
+                        setTimeout(funk, 0);
+                    }
+                    else {
+                        funk();
+                    }
+                }
+            },
+            status: 404
+        };
+    }
+})(window, document); ";
+
+
+            Browser.InvokeScript("execScript", new string[] { script });
+        }
+
+        public bool HandleCommand(string commandStr)
+        {
+            if (commandStr.IndexOf("XHRLOCAL") == 0)
+            {
+                string url = commandStr.Replace("XHRLOCAL/", "");
+
+                Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
+
+                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+                {
+                    if (isoFile.FileExists(uri.AbsolutePath))
+                    {
+                        using (TextReader reader = new StreamReader(isoFile.OpenFile(uri.AbsolutePath, FileMode.Open, FileAccess.Read)))
+                        {
+                            string text = reader.ReadToEnd();
+                            Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
+                            return true;
+                        }
+                    }
+                }
+
+                Uri relUri = new Uri(uri.AbsolutePath, UriKind.Relative);
+
+                var resource = Application.GetResourceStream(relUri);
+
+                if (resource == null)
+                {
+                    // 404 ?
+                    Browser.InvokeScript("__onXHRLocalCallback", new string[] { "404" });
+                    return true;
+                }
+                else
+                {
+                    using (StreamReader streamReader = new StreamReader(resource.Stream))
+                    {
+                        string text = streamReader.ReadToEnd();
+                        Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text });
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+    }
+}
diff --git a/wp8/template/cordovalib/resources/notification-beep.wav b/wp8/template/cordovalib/resources/notification-beep.wav
deleted file mode 100644
index d0ad085..0000000
--- a/wp8/template/cordovalib/resources/notification-beep.wav
+++ /dev/null
Binary files differ
diff --git a/wp8/tooling/scripts/createTemplates.js b/wp8/tooling/scripts/createTemplates.js
index c61f34b..37aa1e7 100644
--- a/wp8/tooling/scripts/createTemplates.js
+++ b/wp8/tooling/scripts/createTemplates.js
@@ -36,8 +36,8 @@
 
 var platformRoot = WScript.ScriptFullName.split('\\tooling\\', 1);
 
-//  set with the -install switch, default false 
-var addToVS = false; 
+//  set with the -install switch, default false
+var addToVS = false;
 
 // help function
 function Usage() {
@@ -145,7 +145,7 @@
 function copyCommonItemsToTemplate() {
     var srcPath = repoRoot + '\\common';
     var destPath = platformRoot + templatePath;
-    
+
     var folder = fso.GetFolder(srcPath);
     // iterate over the files in the folder
     for (var files = new Enumerator(folder.files) ; !files.atEnd() ; files.moveNext()) {
@@ -155,7 +155,7 @@
     // iterate over the child folders in the folder
     for (var subFlds = new Enumerator(folder.SubFolders) ; !subFlds.atEnd() ; subFlds.moveNext()) {
         //Log("Folder: " + srcPath + "\\" + subFlds.item().name);
-        exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " " 
+        exec('%comspec% /c xcopy /Y /E /I ' + srcPath + "\\" + subFlds.item().name + " "
             + destPath + "\\" + subFlds.item().name);
     }
 }
@@ -180,7 +180,7 @@
 {
     Log("Creating template .zip files for wp8");
     var templateOutFilename = repoRoot + '\\CordovaWP8_' + versionNum.replace(/\./g, '_') + '.zip';
-    
+
     // clear the destination
     deleteFileIfExists(templateOutFilename);
 
@@ -192,17 +192,67 @@
     deleteFileIfExists(platformRoot + templatePath + "\\CordovaWP8Solution.v11.suo");
 
     //exec('%comspec% /c xcopy /Y /E /I ' + repoRoot + '\\Plugins ' + platformRoot + templatePath + '\\Plugins');
-    
+
     copyCommonItemsToTemplate();
 
     copyFile(repoRoot + '\\VERSION',platformRoot + templatePath);
 
     // update .vstemplate files for the template zips.
-    var name_regex = /CordovaWP8[_](\d+)[_](\d+)[_](\d+)(rc\d)?/g;
-    var discript_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
 
-    replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', name_regex,  'CordovaWP8_' + versionNum.replace(/\./g, '_'));
-    replaceInFile(platformRoot + templatePath + '\\MyTemplate.vstemplate', discript_regex,  "Cordova " + versionNum);
+    var cleanVersionName = "CordovaWP8_" + versionNum.replace(/\./g, '_');
+
+    var projXml = WScript.CreateObject("Microsoft.XMLDOM");
+    projXml.async = false;
+    var fullTemplatePath = platformRoot + templatePath + '\\MyTemplate.vstemplate';
+    if (projXml.load(fullTemplatePath)) {
+
+        // <Name>CordovaWP8_ + versionNum.replace(/\./g, '_')</Name>
+        var xNode = projXml.selectSingleNode("VSTemplate/TemplateData/Name");
+        if(xNode != null)
+        {
+            // Log("replacing version in Name");
+            xNode.text = cleanVersionName;
+        }
+
+        // <DefaultName>CordovaWP8_ + versionNum</DefaultName>
+        xNode = projXml.selectSingleNode("VSTemplate/TemplateData/DefaultName");
+        if(xNode != null)
+        {
+            // Log("replacing version in DefaultName");
+            xNode.text = cleanVersionName  + '_';
+        }
+
+        xNode = projXml.selectSingleNode("VSTemplate/TemplateData/Description");
+        if(xNode != null)
+        {
+           xNode.text = xNode.text.replace("0.0.0", versionNum);
+        }
+        projXml.save(fullTemplatePath);
+
+    }
+
+
+    // Use proper XML-DOM named nodes and replace them with cordova current version
+    var projXml = WScript.CreateObject("Microsoft.XMLDOM");
+    projXml.async = false;
+    if (projXml.load(platformRoot + templatePath + '\\MyTemplate.vstemplate')) {
+
+        // <Name>CordovaWP7_ + versionNum.replace(/\./g, '_')</Name>
+        var xNode = projXml.selectSingleNode("VSTemplate/TemplateData/Name");
+        if(xNode != null)
+        {
+           xNode.text = "CordovaWP8_" + versionNum.replace(/\./g, '_');
+        }
+
+        // <DefaultName>CordovaWP7_ + versionNum</DefaultName>
+        xNode = projXml.selectSingleNode("VSTemplate/TemplateData/DefaultName");
+        if(xNode != null)
+        {
+           xNode.text = "CordovaWP8_" + versionNum;
+        }
+
+        projXml.save(platformRoot + templatePath + '\\MyTemplate.vstemplate');
+    }
 
     zip_project(templateOutFilename, platformRoot + templatePath);
 
@@ -267,8 +317,8 @@
 function parseArgs() {
     if(args.Count() > 0) {
 
-        //Support help flags -help, --help, /? 
-        if(args(0).indexOf("-help") > -1 || 
+        //Support help flags -help, --help, /?
+        if(args(0).indexOf("-help") > -1 ||
            args(0).indexOf("/?") > -1 ) {
             Usage();
             WScript.Quit(1);
diff --git a/wp8/tooling/scripts/dist.js b/wp8/tooling/scripts/dist.js
index 630133d..834546e 100644
--- a/wp8/tooling/scripts/dist.js
+++ b/wp8/tooling/scripts/dist.js
@@ -42,7 +42,7 @@
     //arguments passed in
 var args = WScript.Arguments,
     //Root folder of cordova-wp8 (i.e C:\Cordova\cordova-wp8)
-    ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
+    ROOT = WScript.ScriptFullName.split('\\wp8\\tooling\\', 1),
     // tooling scripts
     SCRIPTS = '\\tooling\\scripts';
     //Get version number
@@ -144,7 +144,7 @@
             WScript.Quit(1);
         }
         else if (args(0) == '-f') {
-          BUILD_DESTINATION = ROOT;
+          BUILD_DESTINATION = ROOT + '\\wp8';
           replace = true;
         }
         else {
diff --git a/wp8/tooling/scripts/reversion.js b/wp8/tooling/scripts/reversion.js
index 702733b..24e7d71 100644
--- a/wp8/tooling/scripts/reversion.js
+++ b/wp8/tooling/scripts/reversion.js
@@ -33,9 +33,9 @@
     //Root folder of cordova-wp8 (i.e C:\Cordova\cordova-wp8)
     ROOT = WScript.ScriptFullName.split('\\tooling\\', 1),
     //Sub folder containing templates
-    TEMPLATES_PATH = '\\templates',
+    TEMPLATE_PATH = '\\template',
     //Sub folder for standalone project
-    STANDALONE_PATH = TEMPLATES_PATH + '\\standalone',
+    STANDALONE_PATH = TEMPLATE_PATH,
     //Sub folder containing framework
     FRAMEWORK_PATH = '\\framework',
     //Subfolder containing example project
@@ -131,7 +131,7 @@
 function updateVersionNumbers() {
     WScript.StdOut.WriteLine("Updating version numbers....");
     var version_regex = /(\d+)[.](\d+)[.](\d+)(rc\d)?/;
-    replaceInFile(BUILD_DESTINATION + '\\VERSION', version_regex,  VERSION);
+    //replaceInFile(BUILD_DESTINATION + '\\VERSION', version_regex,  VERSION);
     // replace assembaly versions in framework
     var framework_regex = /Description\(\"(\d+)[.](\d+)[.](\d+)(rc\d)?\"\)\]/; //Will match ("x.x.x[rcx]")]
     replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Description(\"" + VERSION + "\")]");
@@ -139,21 +139,17 @@
     replaceInFile(BUILD_DESTINATION + FRAMEWORK_PATH + "\\Properties\\AssemblyInfo.cs", framework_regex, "Version(\"" + BASE_VERSION + "\")]");
 
     // update standalone project
-    exec('%comspec% /c copy /Y /V ' + BUILD_DESTINATION + "\\VERSION " + BUILD_DESTINATION + STANDALONE_PATH + "\\VERSION");
+    //exec('%comspec% /c copy /Y /V ' + BUILD_DESTINATION + "\\VERSION " + BUILD_DESTINATION + STANDALONE_PATH + "\\VERSION");
     var cordova_regex = /cordova-(\d+)[.](\d+)[.](\d+)(rc\d)?/g; //Matches *first* cordova-x.x.x[rcx] (just ad g at end to make global)
     version_regex = /return\s*\"(\d+)[.](\d+)[.](\d+)(rc\d)?/; //Matches return "x.x.x[rcx]
-    replaceInFile(BUILD_DESTINATION + CORDOVA_LIB + '\\..\\Plugins\\Device.cs', version_regex,  "return \"" + VERSION);
-
-    // update template discription
-    version_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?\s*Windows/g; //Matches version: x.x.x[rcx]
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\description.txt', version_regex,  "Cordova " + VERSION + " Windows");
+    //replaceInFile(BUILD_DESTINATION + CORDOVA_LIB + '\\..\\Plugins\\Device.cs', version_regex,  "return \"" + VERSION);
 
     // update .vstemplate files for the template zips.
     var name_regex = /CordovaWP8[_](\d+)[_](\d+)[_](\d+)(rc\d)?/g;
-    var discript_regex = /Cordova\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
+    var discript_regex = /version:\s*(\d+)[.](\d+)[.](\d+)(rc\d)?/;
 
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate', name_regex,  'CordovaWP8_' + VERSION.replace(/\./g, '_'));
-    replaceInFile(BUILD_DESTINATION + TEMPLATES_PATH + '\\vs\\MyTemplateStandAlone.vstemplate', discript_regex,  "Cordova " + VERSION);
+    replaceInFile(BUILD_DESTINATION + TEMPLATE_PATH + '\\MyTemplate.vstemplate', name_regex,  'CordovaWP8_' + VERSION.replace(/\./g, '_'));
+    replaceInFile(BUILD_DESTINATION + TEMPLATE_PATH + '\\MyTemplate.vstemplate', discript_regex,  "version: " + VERSION);
 }
 
 // delete all cordova.js and generated files (templates) from old version numbers
@@ -193,24 +189,6 @@
             fso.DeleteFile(BUILD_DESTINATION + '\\' + root_folder.Item(i).Name);
         }
     }
-    // remove old cordova.js
-    var example_www = shell.NameSpace(BUILD_DESTINATION + EXAMPLE_PATH + '\\www').Items();
-    for(i = 0; i < example_www.Count; i++)
-    {
-        if(example_www.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
-        {
-            fso.DeleteFile(BUILD_DESTINATION + EXAMPLE_PATH + '\\www\\' + example_www.Item(i).Name);
-        }
-    }
-
-    var standalone_www = shell.NameSpace(BUILD_DESTINATION + STANDALONE_PATH + '\\www').Items();
-    for(i = 0; i < standalone_www.Count; i++)
-    {
-        if(standalone_www.Item(i).Name.match(/cordova\-(\d+)[.](\d+)[.](\d+)(rc\d)?[.]js/))
-        {
-            fso.DeleteFile(BUILD_DESTINATION + STANDALONE_PATH + '\\www\\' + standalone_www.Item(i).Name);
-        }
-    }
 }