summaryrefslogtreecommitdiff
path: root/www/lib
diff options
context:
space:
mode:
Diffstat (limited to 'www/lib')
-rw-r--r--www/lib/ngCordova/.bower.json55
-rw-r--r--www/lib/ngCordova/CHANGELOG.md478
-rw-r--r--www/lib/ngCordova/LICENSE21
-rw-r--r--www/lib/ngCordova/README.md119
-rw-r--r--www/lib/ngCordova/bower.json45
-rw-r--r--www/lib/ngCordova/dist/ng-cordova-mocks.js2755
-rw-r--r--www/lib/ngCordova/dist/ng-cordova-mocks.min.js7
-rw-r--r--www/lib/ngCordova/dist/ng-cordova.js6822
-rw-r--r--www/lib/ngCordova/dist/ng-cordova.min.js9
-rw-r--r--www/lib/ngCordova/package.json40
10 files changed, 10351 insertions, 0 deletions
diff --git a/www/lib/ngCordova/.bower.json b/www/lib/ngCordova/.bower.json
new file mode 100644
index 00000000..66dd58e4
--- /dev/null
+++ b/www/lib/ngCordova/.bower.json
@@ -0,0 +1,55 @@
+{
+ "name": "ngCordova",
+ "version": "0.1.15-alpha",
+ "homepage": "http://ngCordova.com/",
+ "authors": [
+ "Max Lynch <max@drifty.com>",
+ "Paolo Bernasconi <paolo.enrico.bernasconi@gmail.com>",
+ "Chad Campbell <chad.campbell@ecofic.com>"
+ ],
+ "description": "AngularJS Cordova wrappers for common Cordova plugins.",
+ "main": [
+ "./dist/ng-cordova.js"
+ ],
+ "ignore": [
+ "**/.*",
+ "gulpfile.js",
+ "test",
+ "src",
+ "config",
+ "demo",
+ "CONTRIBUTING.md"
+ ],
+ "dependencies": {
+ "angular": ">= 1.2.23"
+ },
+ "keywords": [
+ "ngCordova",
+ "ng-cordova",
+ "ngcordova",
+ "ng cordova",
+ "cordova",
+ "phonegap",
+ "angular",
+ "angularjs",
+ "ionic",
+ "cordova plugin"
+ ],
+ "license": "MIT",
+ "private": false,
+ "devDependencies": {
+ "angular": ">= 1.2.23",
+ "angular-mocks": ">= 1.2.23",
+ "jquery": "~2.1.1"
+ },
+ "_release": "0.1.15-alpha",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.1.15-alpha",
+ "commit": "dbdfe5b9c716002548bc4a5e8d1fd5dc2de788ed"
+ },
+ "_source": "git://github.com/driftyco/ng-cordova.git",
+ "_target": "~0.1.15-alpha",
+ "_originalSource": "ngCordova",
+ "_direct": true
+}
diff --git a/www/lib/ngCordova/CHANGELOG.md b/www/lib/ngCordova/CHANGELOG.md
new file mode 100644
index 00000000..ad883ab0
--- /dev/null
+++ b/www/lib/ngCordova/CHANGELOG.md
@@ -0,0 +1,478 @@
+# 0.1.11-alpha (01-15-2014)
+
+### New
+- **NPM** - deploy new versions using Travis 081a23f
+- **FileOpener2 plugin** - created module and factory for fileOpener2 plugin 08970d0
+- **inAppBrowser plugin** - refractor into a provider to set default options + override default options in `open()` method daeedd1 8d9e7fb
+- **File Transfer plugin** - refractor out FileTransfer plugin from **File plugin** into its own module 11717fc
+- **Local Notification** - added ` registerPermission()` method for iOS 8 742d961cfd91a19998029aa51d25602387cb4e29
+- **OAuth** -Magento, ADFS, Vkontakte support 8bb4198
+
+
+### Fix
+- **ProgressIndicator** - add the `show()` method that exists for android. show expects one parameter which is the indicator message 67f5f0d f5b220f
+- **OAuth** - fix promise resolve #544 e0b2457
+- **OAuth** - `close()` browser only after login promise is complete 8bb4198
+- **Push Notification** - `onNotification` check + replace `$rootscope.$apply()` with `$timeout` to avoid '$digest already in progress' error 1cb428a
+- **Network** - improve eventListener auto initialized the eventListeners for `offline`, `online`. 8272f28 0c8c0fd 579c18f
+- **Network** - replace `$apply()` with `$timeout()` for online and offline events d0028aa
+- **Social Sharing** -add `shareViaFacebookWithPasteMessageHint` method a5df9db
+- **localNotification** - replace `$rootscope.$apply()` with `$timeout()` to avoid $digest error for events 743ce58
+- **Battery Status** - remove isolated `$rootScope.$new()` and replace with DI injection + check if plugin is installed. If installed, start EventListeners 0c6de57
+- **Battery Status** - refractor out anonymous functions for better memory management + wrap `$broadcast` calls in a `$timeout` function to ensure `$rootscope.$apply()` occurs 600b30e
+
+
+### Demo
+- **Facebook** - FB variables to init.sh d0575a7
+- **Contacts** - add contacts da92644
+- **localNotification** - add detailed localNotification da92644
+
+
+### Breaking Changes
+- **Network** - standardise $broadcast naming 3566b7b
+- **Push Notification** - standardise $broadcast naming dda9e80
+- **Battery Status** - standardise $broadcast naming 6b6739f
+- **Local Notifications** -standardize $broadcast naming 742d961
+- **InAppBrowser** - rename `loadstart`, `loadstop`, `loaderror`, `exit` to `$cordovaInAppBrowser:[event]` for standardisation + refractor to `$rootScope.$broadcast()` to avoid new isolated scope dea2b8e
+- **InAppBrowser** - remove `init()` function - refractor into `$cordovaInAppBrowserProvider.setDefaultOptions(options)` dea2b8e
+
+##### Network
+Before
+```javascript
+$rootScope.$on('networkOffline', function(e,state));
+$rootScope.$on('networkOnline', function(e,state));
+```
+
+Now
+```javascript
+$rootScope.$on('$cordovaNetwork:offline', function(e,state));
+$rootScope.$on('$cordovaNetwork:online', function(e,state));
+```
+
+
+##### Push Notifications
+Before
+```javascript
+$rootScope.$on('pushNotificationReceived', function(e,state));
+```
+
+Now
+```javascript
+$rootScope.$on('$cordovaPush:notificationReceived', function(e,notification));
+```
+
+##### Battery Status
+Before
+```javascript
+$cordovaBatteryStatus.$on('batterystatus', function(e,status));
+$cordovaBatteryStatus.$on('batterycritical', function(e,status));
+$cordovaBatteryStatus.$on('batterylow', function(e,status));
+```
+
+Now
+```javascript
+$rootScope.$on('$cordovaBatteryStatus:status', function(e,status));
+$rootScope.$on('$cordovaBatteryStatus:critical', function(e,status));
+$rootScope.$on('$cordovaBatteryStatus:low', function(e,status));
+```
+
+##### Local Notification
+Before
+```javascript
+$rootScope.$on("localNotification:canceled", function(e,notification));
+$rootScope.$on("localNotification:clicked", function(e,notification));
+$rootScope.$on("localNotification:triggered", function(e,notification));
+$rootScope.$on("localNotification:added", function(e,notification));
+```
+
+Now
+```javascript
+$rootScope.$on("$cordovaLocalNotification:canceled", function(e,notification));
+$rootScope.$on("$cordovaLocalNotification:clicked", function(e,notification));
+$rootScope.$on("$cordovaLocalNotification:triggered", function(e,notification));
+$rootScope.$on("$cordovaLocalNotification:added", function(e,notification));
+```
+
+##### In App Browser
+Before
+```javascript
+inApp.$on('loadstart', function(e, event));
+inApp.$on('loadstop', function(e, event));
+inApp.$on('loaderror', function(e, event));
+inApp.$on('exit', function(e, event));
+
+$cordovaInAppBrowser.init(options);
+```
+
+Now
+```javascript
+$rootScope.$on('$cordovaInAppBrowser:loadstart', function(e, event));
+$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event));
+$rootScope.$on('$cordovaInAppBrowser:loaderror', function(e, event));
+$rootScope.$on('$cordovaInAppBrowser:exit', function(e, event));
+
+$cordovaInAppBrowserProvider.setDefaultOptions(options);
+```
+
+##### File Plugin
+Before
+```javascript
+$cordovaFile.uploadFile(...)
+$cordovaFile.downloadFile(...)
+```
+
+Now
+```javascript
+$cordovaFileTransfer.upload(...)
+$cordovaFileTransfer.download(...)
+```
+
+
+# 0.1.10-alpha (01-4-2014)
+
+This is a relatively small release to reflect more changes to the **FB plugin**. Important additions were made the **network plugin**, which now provides the ability to watch for `online` and `offline` events.
+
+> NOTE: **ngCordova** is arriving at a very stable level and we hope to release the first **BETA** version in the next few weeks, after we complete some important fixes to the **file plugin**, **push notifications** and **local notifications** plugins. Expect 1 - 2 more **ALPHA** releases with changes made to these plugins, and send me an email @ paolo.enrico.bernasconi@gmail.com if you would like to help test these plugins.
+
+### NEW
+
+- **Network Plugin** : adding `$on('online')`, `$on('offline')` events 3cccfe409b44710e9677a3d9434b3efe346e6379
+- **0Auth** : salesforce + strava support e0795ce
+- **Facebook** : make more compliant with original plugin and remove unnecessary `init()` from login method. 64b5aa8036d23dd768a2b47c21e760871feb94dd 2218c4d
+- **mocks** : better file plugin 2404142 78e9410 8bac9eb
+- **docs**: ability to search plugins
+
+### Fix
+- **0Auth** : add code to handle cancel / exit events in the oauth browser flow 4d93e12
+- **Keychain** : check if keychain exists before instantiating 7684643
+
+
+### Breaking Changes
+
+**Facebook Plugin:** (only relevant for browser testing)
+
+**Before**
+```
+.config(function () {
+ $cordovaFacebookProvider.setAppID(appID, version);
+});
+
+```
+
+**After**
+```
+.config(function () {
+ $cordovaFacebookProvider. browserInit(12345678, "v2.0")
+});
+```
+
+
+
+
+# 0.1.9-alpha (12-22-2014)
+
+A new release to reflect a few changes made to the docs and code respectively. Mainly `v0.1.9-alpha` has been released to fix the AngularJS dependency issue, which now resolves to anything higher than `v1.2.23`.
+
+### NEW
+
+- **MAJOR docs refractor**
+- **Brightness** plugin
+- **App Version** plugin
+- **ActionSheet** plugin
+- **Email Composer** plugin
+- **Image Picker** plugin
+
+
+### Fix
+- **App** Rate plugin: add dep injection
+- **Media** plugin: reduce promisifcation
+- **StatusBar** : `isVisible` is not a method, but a value
+- **Bower** -- update dependency to `>= 1.2.23`
+
+
+# 0.1.8-alpha (12-11-2014)
+
+### NEW
+- **App Rate** plugin
+- **In App Browser** plugin
+- **HTTPd** plugin
+- **Video Capture Plus** plugin
+- **GoogleAds** plugin
+- **FacebookAds** plugin
+- **FlurryAds** plugin
+- **iAd** plugin
+- **mMediaAds** plugin
+- **mobfoxAds** plugin
+- **mopubAds** plugin
+- **0Auth** - twitter, reddit, foresquare support
+- **Date Picker** - Insert default options on datePicker
+
+### FIXES
+- **Module** - add zip plugin injection dependency
+- **Push Notification** - wrapping $broadcast in an $apply() statement to bring notification into scope
+- **Local Notification** - Updated localNotification wrapper with hasPermission and promptForPermission methods
+- **Bluetooth Serial** - fix callback from `resolve` to `notify` for constant updates
+- **File** - add timeout option to upload
+
+### Breaking Changes
+
+Changes were made to the promisification of `geolocation`, `deviceOrientation` and `deviceMotion` plugin `watch` methods.
+
+**Before**:
+```
+watch = $cordovaDeviceMotion.watchAcceleration(options);
+
+watch.promise.then(
+ function() {/* unused */},
+ function(err) {},
+ function(acceleration) {
+});
+
+$cordovaDeviceMotion.clearWatch(watch.watchID);
+```
+
+**Now**:
+```
+watch = $cordovaDeviceMotion.watchAcceleration(options).then(
+ function() {/* unused */},
+ function(err) {},
+ function(acceleration) {
+});
+
+watch.clear();
+// or
+$cordovaDeviceMotion.clearWatch(watch);
+```
+
+The same goes for `geolocation` and `DeviceOrientation`.
+
+
+
+
+
+
+# 0.1.7-alpha (11-05-2014)
+
+This is a micro-release to fix the issue with `bower` installing `v0.1.5-alpha`, resolving #418.
+
+### New
+- **Demo** - FB web-dev api is now working ec053ad 71d3961
+- **PushNotifications** - Angular event broadcast for push notifications da0ef69
+- **Contact* - new `pickContact` method 01319b853da56eeb7893abc93fb1ebbb2bb9fbe7
+
+### Fixes
+- **Printer** - fix `isAvailable` method + promise for `print` method ef452ed
+
+
+
+
+# 0.1.6-alpha (10-30-2014)
+
+This is a small release to reflect a few fixes in the **Facebook plugin**. The docs at [ngcordova.com/docs](http://ngcordova.com/docs) are now aligned with the fixes made.
+
+### New
+
+- [Bluetooth Low Energy plugin]() 7540bf2
+- [Badge plugin](https://github.com/katzer/cordova-plugin-badge) 69fe14f
+- AuthO plugin (web based) c775650
+- AppRating plugin (still in development) 9aead73
+
+
+### Fixes
+
+- **Facebook** - refractor appID 48cb327
+- **Facebook** - add version parameter to setAppID method 0e6f7b1
+- **Flashlight** - add toggle method 0e24273
+- **Spinner Dialog** - add `fixed` parameter to stop touch from removing spinner dialog d1a01df
+
+
+# 0.1.5-alpha (10-17-2014)
+
+The Facebook Plugin is now supported with many new plugins added and bugs fixed!
+
+### Highlights
+
+**FB plugin** - The highly demanded Facebook plugin now has docs and a working example in the demo file of ngCordova.
+
+**TouchID** - Add iOS TouchID authentication to your apps easily with the touchid plugin. See the demo app for a working example.
+
+**Travis CI testing** - We've integrated ngCordova into TravisCI, and have builds tested on each commit.
+
+### New
+
+- [TouchID plugin](https://github.com/leecrossley/cordova-plugin-touchid)
+- [ZIP plugin](https://github.com/MobileChromeApps/zip)
+- [Calendar plugin](https://github.com/apache/cordova-plugin-contacts)
+- [Google Analytics plugin](https://github.com/phonegap-build/GAPlugin)
+- Date Picker now has promises
+- PinDialog now has promises
+- Replacing javascript `window` with angular `$window`
+- Testing for many plugins (check the /test folder)
+
+### Fix
+
+- Dialogs plugin : fixed prompt and confirm methods to return button index and input (if exists)
+- Keychain : fix issue where keychain is not initialized properly
+- StatusBar : fix the method overlaysWebView to honour the boolean param
+- Remove ngCordova.min.js from bower for better grunt integration
+- Fixes to the File Plugin (more fixes coming soon)
+
+
+
+
+# 0.1.4-alpha (09-08-2014)
+
+### New
+
+- [Progress Indicator plugin](http://pbernasconi.github.io/cordova-progressIndicator/) d70f387
+- [Clipboard plugin](https://github.com/VersoSolutions/CordovaClipboard) f54bdc8
+- [SMS plugin](https://github.com/aharris88/phonegap-sms-plugin)
+- [Bluetooth Serial plugin](https://github.com/don/BluetoothSerial)
+- [AdMob Plugin](https://github.com/floatinghotpot/cordova-plugin-admob)
+- [Background Geolocation Plugin](https://github.com/christocracy/cordova-plugin-background-geolocation)
+- [Facebook Connect Plugin](https://github.com/Wizcorp/phonegap-facebook-plugin)
+- [Printer Plugin](https://github.com/katzer/cordova-plugin-printer)
+- [Native Audio Plugin](https://github.com/SidneyS/cordova-plugin-nativeaudio) 96f4570
+- [Media plugin](https://github.com/apache/cordova-plugin-media) a235517
+- [Battery Status plugin](org.apache.cordova.battery-status) 897dd65
+- [Keychain plugin](https://github.com/shazron/KeychainPlugin)
+- [Date Picker plugin](https://github.com/VitaliiBlagodir/cordova-plugin-datepicker)
+
+
+
+### Fixes
+
+- **Dialogs** - Adding promise support
+- **Device Orientation** - Fixed compass.clearWatch missing the watchID parameter 9367bcf
+- **Globalization** - Added more methods and endpoints 786ec67
+- **Globalization** - Fixed unnecessary options parameter 4379b81e791c8aefa71ba84fe65cb6ef70b62a7c
+- **File** - Adding writeFile logic for "file" plugin 46bd8b7
+- **File** - Added relative path and filename fbd2e9d
+- **File** - New methods for ReasAs [text, DataURL, BinaryString, ArrayBuffer] 0b30ba1
+- **Printer** - Adding promise support
+- **Social Sharing** - Added the (most important) `share` function
+- **Social Sharing** - Renamed SMS phonenr param to indicate you can pass multiple by separating by a comma
+- **Social Sharing** - Renamed all image params to file, because any file can be shared
+- **Social Sharing** - Fixed `shareViaEmail`, because it was an unadjusted copy-paste of `shareViaSMS`
+- **Social Sharing** - Added `shareVia`
+- **Social Sharing** - Added `canShareViaEmail`
+- **Social Sharing** - Fixed `canShareVia` (subject was missing)
+- **Social Sharing** - Removed some now obsolete TODO's/notes
+
+### New
+
+- A new side-menu for quick navigation
+
+- Flashlight plugin
+- Progress Indicator plugin
+- AdMob plugin
+- AppAvailability plugin
+- Battery Status plugin
+- Clipboard plugin
+- Keychain plugin
+- Media plugin
+- Printer Plugin
+- Contributing guidelines
+- CHANGELOG.md
+
+### Demo
+- **Completely new demos** with many new plugins 49d991f
+- Quick-view the source code in the app
+- Flashlight plugin
+- Statusbar plugin
+- Preferences plugin
+- Barcode Scanner plugin
+
+### Other
+- **ng-cordova-mocks** - Mock are now in ngCordova! Documentation is **coming soon**, with examples in the demo too
+- Adding js-lint testing in gulp 72e513b
+- Adding .editorconfig for better contributing
+- Fix bower.js file and bower install ngCordova
+
+
+
+# 0.1.3-alpha (06-11-2014)
+
+### NEW
+ - API Change for Geolocation, DeviceMotion, and DeviceOrientation plugins. They now return an object of the form:
+```javascript
+{
+ promise: deferrable,
+ watchId: watchId
+}
+```
+
+Where promise is the internal promise, and watchId is the watchId that can be used to clear the watch later.
+
+ - [Capture](https://github.com/apache/cordova-plugin-media-capture) plugin
+ - [Flashlight](https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin) plugin
+ - [AppAvailability](https://github.com/ohh2ahh/AppAvailability) plugin
+ - Cordova preferences plugin
+
+And lots of fixes!
+
+
+
+# 0.1.2-alpha (06-11-2014)
+
+### NEW
+
+- Bower support
+- File Plugin
+- Globalization plugin.
+- Google Analytics plugin
+- Local Notifications Plugin
+- Pin Dialog plugin
+- Push Notifications plugin
+- Social Sharing plugin
+- Spinner Dialog plugin
+- SQLite Plugin
+- Toast Plugin
+
+
+### FEATURES
+
+- Progress event to **File Plugin** `upload()` + `download()`
+- More commands in **Push Notification plugin**
+- Handle `Connection.NONE` in **Network Information Plugin** for is`Offline()`
+- Use `notify` not `resolve` with `watchHeading`
+
+
+### FIXES
+
+- Remove options in **BarcodeScanner** : `scan()`
+- Remove options in **Device Motion** : `getCurrentAcceleration()`
+
+
+
+
+# 0.1.1-alpha (06-03-2014)
+
+### NEW
+- StatusBar
+
+### FIXES
+- Renamed Accelerometer and Compass to deviceMotion and deviceOrientation, respectively
+
+
+
+# 0.1.0-alpha (06-03-2014)
+
+ngCordova is ready for some bleeding edge testing. So far we support the following Cordova plugins:
+
+- org.apache.cordova.console
+- org.apache.cordova.device
+- org.apache.cordova.camera
+- org.apache.cordova.vibration
+- org.apache.cordova.network-information
+- org.apache.cordova.geolocation
+- org.apache.cordova.dialogs
+- org.apache.cordova.device-motion
+- org.apache.cordova.splashscreen
+- org.apache.cordova.device-orientation
+- org.apache.cordova.contacts
+- https://github.com/driftyco/ionic-plugins-keyboard
+- https://github.com/wildabeast/BarcodeScanner
+
+
+Give it a try, and please report lots of issues and contribute PRs. :icecream:
diff --git a/www/lib/ngCordova/LICENSE b/www/lib/ngCordova/LICENSE
new file mode 100644
index 00000000..66680097
--- /dev/null
+++ b/www/lib/ngCordova/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Drifty
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/www/lib/ngCordova/README.md b/www/lib/ngCordova/README.md
new file mode 100644
index 00000000..d64c8424
--- /dev/null
+++ b/www/lib/ngCordova/README.md
@@ -0,0 +1,119 @@
+[ngCordova](http://ngcordova.com/)
+==========
+
+[![Travis](http://img.shields.io/travis/driftyco/ng-cordova.svg?style=flat)](https://travis-ci.org/driftyco/ng-cordova) [![Bower](http://img.shields.io/badge/bower-ngCordova-FFCC2F.svg?style=flat)](http://bower.io/search/?q=ngCordova)
+
+### Cordova with AngularJS Goodness
+
+
+[<img src="http://ionicframework.com/img/ngcordova-context-logo.png" alt="ngCordova Logo" width="210px" height="210px" />](http://ngcordova.com/)
+
+
+ngCordova gives you simple AngularJS wrappers for a massive amount of Cordova plugins. Check out the list below for all of the available plugins, and create an issue for a new request.
+
+Created by the [Ionic Framework](http://ionicframework.com/) team and the community.
+
+| RESOURCE | LINK |
+|------------|---------|
+| **Website** | [ngCordova.com](http://ngcordova.com/) |
+| **Docs** | [ngCordova.com/docs](http://ngcordova.com/docs) |
+| **Requirements** | [AngularJS](https://github.com/angular/angular.js), [Cordova](http://cordova.apache.org/) |
+| **Install** | `bower install ngCordova` or [download zip file](https://github.com/driftyco/ng-cordova/archive/master.zip) |
+| **Custom build** | [ngCordova.com/build](http://ngcordova.com/build/) |
+
+
+## Installation
+
+Install manually, or from bower:
+
+```bash
+$ bower install ngCordova
+```
+
+## Plugins `(63+)`
+
+- [Action Sheet](https://github.com/EddyVerbruggen/cordova-plugin-actionsheet)
+- [AdMob](https://github.com/floatinghotpot/cordova-plugin-admob)
+- [App Availability](https://github.com/ohh2ahh/AppAvailability)
+- [App Preferences](https://github.com/dferrell/plugins-application-preferences)
+- [App Rate](https://github.com/pushandplay/cordova-plugin-apprate)
+- [App Version](https://github.com/whiteoctober/cordova-plugin-app-version)
+- [Background Geolocation](https://github.com/christocracy/cordova-plugin-background-geolocation)
+- [Badge](https://github.com/katzer/cordova-plugin-badge)
+- [Barcode Scanner](https://github.com/wildabeast/BarcodeScanner)
+- [Battery Status](https://github.com/apache/cordova-plugin-battery-status) *
+- [Bluetooth Low Energy](https://github.com/evothings/cordova-ble)
+- [Bluetooth Serial](https://github.com/don/BluetoothSerial)
+- [Brightness](https://github.com/fiscal-cliff/phonegap-plugin-brightness)
+- [Calendar](https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin)
+- [Camera](https://github.com/apache/cordova-plugin-camera) *
+- [Clipboard](https://github.com/VersoSolutions/CordovaClipboard)
+- [Console](https://github.com/apache/cordova-plugin-console) *
+- [Contacts](https://github.com/apache/cordova-plugin-contacts) *
+- [Date Picker](https://github.com/VitaliiBlagodir/cordova-plugin-datepicker)
+- [Device Motion](https://github.com/apache/cordova-plugin-device-motion) *
+- [Device Orientation](https://github.com/apache/cordova-plugin-device-orientation) *
+- [Device](https://github.com/apache/cordova-plugin-device) *
+- [Dialogs](https://github.com/apache/cordova-plugin-dialogs) *
+- [Email Composer](https://github.com/katzer/cordova-plugin-email-composer)
+- [Facebook Connect](https://github.com/Wizcorp/phonegap-facebook-plugin)
+- [Facebook AudienceNetwork Ads](https://github.com/floatinghotpot/cordova-plugin-facebookads)
+- [File](https://github.com/apache/cordova-plugin-file) *
+- [File Transfer](https://github.com/apache/cordova-plugin-file-transfer) *
+- [Flashlight](https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin)
+- [Flurry Ads](https://github.com/floatinghotpot/cordova-plugin-flurry)
+- [Geolocation](https://github.com/apache/cordova-plugin-geolocation) *
+- [Globalization](https://github.com/apache/cordova-plugin-globalization) *
+- [Google Ads](https://github.com/floatinghotpot/cordova-admob-pro)
+- [Google Analytics](https://github.com/danwilson/google-analytics-plugin)
+- [Google Maps]()
+- [HealthKit for iOS](https://github.com/Telerik-Verified-Plugins/HealthKit)
+- [Httpd (Web Server)](https://github.com/floatinghotpot/cordova-httpd)
+- [Apple iAd](https://github.com/floatinghotpot/cordova-iad-pro)
+- [Image Picker](https://github.com/wymsee/cordova-imagePicker)
+- [InAppBrowser](https://github.com/apache/cordova-plugin-inappbrowser)*
+- [Keyboard](https://github.com/driftyco/ionic-plugins-keyboard)
+- [Keychain](https://github.com/shazron/KeychainPlugin)
+- [Local Notifications](https://github.com/katzer/cordova-plugin-local-notifications/)
+- [Media Capture](https://github.com/apache/cordova-plugin-media-capture)
+- [Media](https://github.com/apache/cordova-plugin-media) *
+- [MillennialMedia Ads](https://github.com/floatinghotpot/cordova-plugin-mmedia)
+- [MobFox Ads](https://github.com/floatinghotpot/cordova-mobfox-pro)
+- [MoPub Ads](https://github.com/floatinghotpot/cordova-plugin-mopub)
+- [Native Audio](https://github.com/SidneyS/cordova-plugin-nativeaudio)
+- [Network Information](https://github.com/apache/cordova-plugin-network-information) *
+- [Oauth](https://github.com/nraboy/ng-cordova-oauth)
+- [Pin Dialog](https://github.com/Paldom/PinDialog)
+- [Printer](https://github.com/katzer/cordova-plugin-printer)
+- [Progress Indicator](https://github.com/pbernasconi/cordova-progressIndicator)
+- [Push Notifications](https://github.com/phonegap-build/PushPlugin)
+- [SMS](https://github.com/aharris88/phonegap-sms-plugin)
+- [Social Sharing](https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin)
+- [Spinner Dialog](https://github.com/Paldom/SpinnerDialog)
+- [Splashscreen](https://github.com/apache/cordova-plugin-splashscreen) *
+- [SQLite](https://github.com/brodysoft/Cordova-SQLitePlugin)
+- [StatusBar](https://github.com/apache/cordova-plugin-statusbar) *
+- [Toast](https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin)
+- [Touchid](https://github.com/leecrossley/cordova-plugin-touchid)
+- [Vibration](https://github.com/apache/cordova-plugin-vibration) *
+- [Video Capture Plus](https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin) *
+- [Zip](https://github.com/MobileChromeApps/zip)
+
+`* official Apache Cordova Plugin`
+
+## Authors
+
+#### Max Lynch
+
+- https://twitter.com/maxlynch
+- https://github.com/mlynch
+
+#### Paolo Bernasconi
+
+- https://twitter.com/paolobernasconi
+- https://github.com/pbernasconi
+
+
+## LICENSE
+
+ngCordova is licensed under the MIT Open Source license. For more information, see the LICENSE file in this repository.
diff --git a/www/lib/ngCordova/bower.json b/www/lib/ngCordova/bower.json
new file mode 100644
index 00000000..1b1ce504
--- /dev/null
+++ b/www/lib/ngCordova/bower.json
@@ -0,0 +1,45 @@
+{
+ "name": "ngCordova",
+ "version": "0.1.15-alpha",
+ "homepage": "http://ngCordova.com/",
+ "authors": [
+ "Max Lynch <max@drifty.com>",
+ "Paolo Bernasconi <paolo.enrico.bernasconi@gmail.com>",
+ "Chad Campbell <chad.campbell@ecofic.com>"
+ ],
+ "description": "AngularJS Cordova wrappers for common Cordova plugins.",
+ "main": [
+ "./dist/ng-cordova.js"
+ ],
+ "ignore": [
+ "**/.*",
+ "gulpfile.js",
+ "test",
+ "src",
+ "config",
+ "demo",
+ "CONTRIBUTING.md"
+ ],
+ "dependencies": {
+ "angular": ">= 1.2.23"
+ },
+ "keywords": [
+ "ngCordova",
+ "ng-cordova",
+ "ngcordova",
+ "ng cordova",
+ "cordova",
+ "phonegap",
+ "angular",
+ "angularjs",
+ "ionic",
+ "cordova plugin"
+ ],
+ "license": "MIT",
+ "private": false,
+ "devDependencies": {
+ "angular": ">= 1.2.23",
+ "angular-mocks": ">= 1.2.23",
+ "jquery": "~2.1.1"
+ }
+}
diff --git a/www/lib/ngCordova/dist/ng-cordova-mocks.js b/www/lib/ngCordova/dist/ng-cordova-mocks.js
new file mode 100644
index 00000000..cda8cf4f
--- /dev/null
+++ b/www/lib/ngCordova/dist/ng-cordova-mocks.js
@@ -0,0 +1,2755 @@
+/*!
+ * ngCordova
+ * v0.1.15-alpha
+ * Copyright 2014 Drifty Co. http://drifty.com/
+ * See LICENSE in this repository for license information
+ */
+(function(){
+var ngCordovaMocks = angular.module('ngCordovaMocks', []);
+ngCordovaMocks.factory('$cordovaAppVersion', ['$q', function($q) {
+ var throwsError = false;
+ return {
+ throwsError: throwsError,
+ getAppVersion: function() {
+ var defer = $q.defer();
+ defer.resolve('mock v');
+ return defer.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaBarcodeScanner
+ *
+ * @description
+ * A service for testing barcode scanner features
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaBarcodeScanner', ['$q', function($q) {
+ var throwsError = false;
+
+ var scannedText = '';
+ var scannedFormat = '';
+ var wasCancelled = false;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaBarcodeScanner
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name scannedText
+ * @propertyOf ngCordovaMocks.cordovaBarcodeScanner
+ *
+ * @description
+ * Used to simulate the result.text property of a
+ * successful scan. For more information, see the text at
+ * https://github.com/wildabeast/BarcodeScanner/#using-the-plugin
+ * This property should only be used in automated tests.
+ **/
+ scannedText: scannedText,
+
+ /**
+ * @ngdoc property
+ * @name scannedFormat
+ * @propertyOf ngCordovaMocks.cordovaBarcodeScanner
+ *
+ * @description
+ * Used to simulate the result.format property of a
+ * successful scan. For more information, see the text at
+ * https://github.com/wildabeast/BarcodeScanner/#using-the-plugin
+ * This property should only be used in automated tests.
+ **/
+ scannedFormat: scannedFormat,
+
+ /**
+ * @ngdoc property
+ * @name wasCancelled
+ * @propertyOf ngCordovaMocks.cordovaBarcodeScanner
+ *
+ * @description
+ * Used to simulate the result.cancelled property of a
+ * successful scan. For more information, see the text at
+ * https://github.com/wildabeast/BarcodeScanner/#using-the-plugin
+ * This property should only be used in automated tests.
+ **/
+ wasCancelled: wasCancelled,
+
+ scan: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error scanning.');
+ } else {
+ defer.resolve({text: this.scannedText, format: this.scannedFormat, cancelled: this.wasCancelled });
+ }
+ return defer.promise;
+ },
+
+ encode: function(type, data) {
+ this.scannedFormat = type;
+ this.scannedText = data;
+
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error encoding the data.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaBLE
+ *
+ * @description
+ * A service for ble features
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaBLE', ['$q', '$timeout', function($q, $timeout) {
+ var deviceScan = {
+ "name": "Test Device",
+ "id": "AA:BB:CC:DD:EE:FF",
+ "advertising": [2,1,6,3,3,15,24,8,9,66,97,116,116,101,114,121],
+ "rssi": -55
+ };
+
+ var deviceConnect = {
+ "name": "Test Device",
+ "id": "AA:BB:CC:DD:EE:FF",
+ "advertising": [2,1,6,3,3,15,24,8,9,66,97,116,116,101,114,121],
+ "rssi": -55,
+ "services": [
+ "1800",
+ "1801",
+ "180f"
+ ],
+ "characteristics": [
+ {
+ "service": "1800",
+ "characteristic": "2a00",
+ "properties": [ "Read" ]
+ },
+ {
+ "service": "1800",
+ "characteristic": "2a01",
+ "properties": [ "Read" ]
+ },
+ {
+ "service": "1801",
+ "characteristic": "2a05",
+ "properties": [ "Read" ]
+ },
+ {
+ "service": "180f",
+ "characteristic": "2a19",
+ "properties": [ "Read" ],
+ "descriptors": [ { "uuid": "2901" }, { "uuid": "2904" } ]
+ }
+ ]
+ };
+
+ var readData = new ArrayBuffer(8);
+
+ return {
+
+ scan: function (services, seconds) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(deviceScan);
+ }, seconds*1000);
+ return q.promise;
+ },
+
+ connect: function (deviceID) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(deviceConnect);
+ }, 1500);
+ return q.promise;
+ },
+
+ disconnect: function (deviceID) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(true);
+ }, 500);
+ return q.promise;
+ },
+
+ read: function (deviceID, serviceUUID, characteristicUUID) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(readData);
+ }, 100);
+ return q.promise;
+ },
+
+ write: function (deviceID, serviceUUID, characteristicUUID, data) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(true);
+ }, 100);
+ return q.promise;
+ },
+
+ writeCommand: function (deviceID, serviceUUID, characteristicUUID, data) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(true);
+ }, 100);
+ return q.promise;
+ },
+
+ notify: function (deviceID, serviceUUID, characteristicUUID) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(true);
+ }, 100);
+ return q.promise;
+ },
+
+ indicate: function (deviceID, serviceUUID, characteristicUUID) {
+ var q = $q.defer();
+ $timeout(function () {
+ q.resolve(true);
+ }, 100);
+ return q.promise;
+ },
+
+ isConnected: function (deviceID) {
+ var q = $q.defer();
+ q.resolve(true);
+ return q.promise;
+ },
+
+ isEnabled: function () {
+ var q = $q.defer();
+ q.resolve(true);
+ return q.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaCamera
+ *
+ * @description
+ * A service for testing camera features
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaCamera', ['$q', function($q) {
+ var throwsError = false;
+ var imageData = '';
+
+ return {
+
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaCamera
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name imageData
+ * @propertyOf ngCordovaMocks.cordovaCamera
+ *
+ * @description
+ * The imagedata (e.g. an url) which will be returned from the device.
+ * This property should only be used in automated tests.
+ **/
+ imageData: imageData,
+
+ getPicture: function(options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the picture.');
+ } else {
+ if (options) {
+ options = options; // This is just to get by JSHint.
+ }
+
+ defer.resolve(this.imageData);
+ }
+ return defer.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaCapture
+ *
+ * @description
+ * A service for testing media capture
+ * in an app build with ngCordova.
+ *
+ * @example
+ */
+ngCordovaMocks.factory('$cordovaCapture', ['$q', function($q) {
+ var throwsError = false;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaCapture
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ captureAudio : function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error capturing the audio.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ captureImage: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error capturing the image.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ captureVideo: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error capturing the video.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaContacts
+ *
+ * @description
+ * A service for testing features related with contacts
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaContacts', ['$q', function($q) {
+ var throwsError = false;
+ var contacts = [];
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaContacts
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc contacts
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaContacts
+ *
+ * @description
+ * An in-memory collection of contacts.
+ * This property should only be used in automated tests.
+ **/
+ contacts: contacts,
+
+ save: function(contact) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error saving the contact.');
+ } else {
+ var existingIndex = null;
+ for (var i=0; i<this.contacts.length; i++) {
+ // The actual implementation relies on the entire object match.
+ // we're gong to rely on the ID.
+ if (this.contacts[i].id === contact.id) {
+ existingIndex = i;
+ break;
+ }
+ }
+
+ if (existingIndex === null) {
+ this.contacts.push(contact);
+ defer.resolve();
+ } else {
+ defer.reject('Contact already exists.');
+ }
+ }
+ return defer.promise;
+ },
+
+ remove: function(contact) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error saving the contact.');
+ } else {
+ var toRemove = null;
+ for (var i=0; i<this.contacts.length; i++) {
+ // The actual implementation relies on the entire object match.
+ // we're gong to rely on the ID.
+ if (this.contacts[i].id === contact.id) {
+ toRemove = i;
+ break;
+ }
+ }
+
+ if (toRemove === null) {
+ defer.reject('Unable to find contact.');
+ } else {
+ this.contacts.splice(toRemove, 1);
+ defer.resolve();
+ }
+ }
+ return defer.promise;
+ },
+
+ find: function(options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error finding the contact.');
+ } else {
+ var fields = options.fields || ['id', 'displayName'];
+ delete options.fields;
+
+ if (!fields) {
+ defer.reject('ContactError.INVALID_ARGUMENT_ERROR');
+ } else {
+ if (fields === '*') {
+ defer.resolve(this.contacts);
+ } else {
+ // Implement a very rudimentary search approach for testing purposes.
+ // This is NOT exhaustive.
+ var results = [];
+ for (var i=0; i<this.contacts.length; i++) {
+ for(var key in this.contacts[i]) {
+ var propertyValue = this.contacts[i][key];
+ }
+ }
+ // TODO: Search by individual fields
+ defer.resolve(results);
+ }
+ }
+ }
+ return defer.promise;
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaDatePicker
+ *
+ * @description
+ * A service for testing datepicker features
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaDatePicker', ['$q', function ($q) {
+ return {
+ show: function (options) {
+ var q = $q.defer();
+ options = options || {date: new Date(), mode: 'date'};
+ q.resolve(options.date);
+ return q.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * A service for testing device information
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaDevice', function () {
+ var device = '';
+ var cordova = '';
+ var model = '';
+ var platform = '';
+ var uuid = '';
+ var version = '';
+
+ return {
+ /**
+ * @ngdoc property
+ * @name device
+ * @propertyOf ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * The name of the 'device'.
+ * This property should only be used in automated tests.
+ **/
+ device: device,
+
+ /**
+ * @ngdoc property
+ * @name cordova
+ * @propertyOf ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * The version of cordova in use.
+ * This property should only be used in automated tests.
+ **/
+ cordova: cordova,
+
+ /**
+ * @ngdoc property
+ * @name model
+ * @propertyOf ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * The model of the device using the app.
+ * This property should only be used in automated tests.
+ **/
+ model: model,
+
+ /**
+ * @ngdoc property
+ * @name platform
+ * @propertyOf ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * The name of the operating system in use.
+ * This property should only be used in automated tests.
+ **/
+ platform: platform,
+
+ /**
+ * @ngdoc property
+ * @name uuid
+ * @propertyOf ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * The unique identifier of a device.
+ * This property should only be used in automated tests.
+ **/
+ uuid: uuid,
+
+ /**
+ * @ngdoc property
+ * @name version
+ * @propertyOf ngCordovaMocks.cordovaDevice
+ *
+ * @description
+ * The version of the operating system.
+ * This property should only be used in automated tests.
+ **/
+ version: version,
+
+ getDevice: function () {
+ return this.device;
+ },
+
+ getCordova: function () {
+ return this.cordova;
+ },
+
+ getModel: function () {
+ return this.model;
+ },
+
+ getPlatform: function() {
+ return this.platform;
+ },
+
+ getUUID: function() {
+ return this.uuid;
+ },
+
+ getVersion: function() {
+ return this.version;
+ }
+ };
+});
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaDeviceMotion
+ *
+ * @description
+ * A service for mocking the accelerometer
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaDeviceMotion', ['$interval', '$q', function ($interval, $q) {
+ var currentAcceleration = null;
+ var throwsError = false;
+ var positions = [];
+ var watchIntervals = [];
+
+ return {
+ /**
+ * @ngdoc property
+ * @name currentAcceleration
+ * @propertyOf ngCordovaMocks.cordovaDeviceMotion
+ *
+ * @description
+ * The current acceleration.
+ * This property should only be used in automated tests.
+ **/
+ currentAcceleration: currentAcceleration,
+
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaDeviceMotion
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name positions
+ * @propertyOf ngCordovaMocks.cordovaDeviceMotion
+ *
+ * @description
+ * The collection of 'positions' that have been logged.
+ * This property should only be used in automated tests.
+ **/
+ positions: positions,
+
+ /**
+ * @ngdoc property
+ * @name watchIntervals
+ * @propertyOf ngCordovaMocks.cordovaDeviceMotion
+ *
+ * @description
+ * The collection of watchers that are currently active.
+ * This property should only be used in automated tests.
+ **/
+ watchIntervals: watchIntervals,
+
+ getCurrentAcceleration: function () {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the current acceleration.');
+ } else {
+ defer.resolve(this.currentAcceleration);
+ }
+ return defer.promise;
+ },
+
+ watchAcceleration : function (options) {
+ var defer = $q.defer();
+ var watchId = Math.floor((Math.random() * 1000000) + 1);
+
+ this.positions = [];
+ self = this;
+
+ if (this.throwsError) {
+ defer.reject('There was an error watching the current acceleration.');
+ } else {
+ var delay = 10000; // The default based on https://github.com/apache/cordova-plugin-device-motion/blob/master/doc/index.md
+ if (options && options.frequency) {
+ delay = options.frequency;
+ }
+
+ this.watchIntervals.push($interval(
+ function() {
+ if (self.throwsError) {
+ defer.reject('There was an error watching the acceleration.');
+ }
+
+ // Generate a random position
+ var randomX = Math.floor((Math.random() * 100) + 1);
+ var randomY = Math.floor((Math.random() * 100) + 1);
+ var randomZ = Math.floor((Math.random() * 100) + 1);
+ var result = { x: randomX, y: randomY, z:randomZ, timestamp:Date.now() };
+
+ self.positions.push(result);
+ defer.notify(result);
+ },
+ delay
+ ));
+ }
+
+ return {
+ watchId: watchId,
+ promise: defer.promise
+ };
+ },
+
+ clearWatch: function (watchId) {
+ var defer = $q.defer();
+ if (watchId) {
+ if (this.throwsError) {
+ defer.reject('Unable to clear watch.');
+ } else {
+ var removed = -1;
+ for (var i=0; i<this.watchIntervals.length; i++) {
+ if (this.watchIntervals[i].watchId === watchId) {
+ $interval.cancel(watchIntervals[i].interval);
+ removed = i;
+ break;
+ }
+ }
+
+ if (removed !== -1) {
+ this.watchIntervals.splice(removed, 1);
+ }
+ }
+ } else {
+ defer.reject('Unable to clear watch. No watch ID provided.');
+ }
+ return defer.promise;
+ }
+ };
+}]);
+ /**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaDeviceOrientation
+ *
+ * @description
+ * A service for testing compass fetures
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaDeviceOrientation', ['$interval', '$q', function ($interval, $q) {
+ var currentHeading = null;
+ var throwsError = false;
+ var readings = [];
+ var watchIntervals = [];
+
+ return {
+ /**
+ * @ngdoc property
+ * @name currentHeading
+ * @propertyOf ngCordovaMocks.cordovaDeviceOrientation
+ *
+ * @description
+ * The current heading.
+ * This property should only be used in automated tests.
+ **/
+ currentHeading: currentHeading,
+
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaDeviceOrientation
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name positions
+ * @propertyOf ngCordovaMocks.cordovaDeviceOrientation
+ *
+ * @description
+ * The collection of compass 'readings' that have been logged.
+ * This property should only be used in automated tests.
+ **/
+ readings: readings,
+
+ /**
+ * @ngdoc property
+ * @name watchIntervals
+ * @propertyOf ngCordovaMocks.cordovaDeviceOrientation
+ *
+ * @description
+ * The collection of watchers that are currently active.
+ * This property should only be used in automated tests.
+ **/
+ watchIntervals: watchIntervals,
+
+ getCurrentHeading: function () {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the current heading.');
+ } else {
+ defer.resolve(this.currentHeading);
+ }
+ return defer.promise;
+ },
+
+ watchHeading: function (options) {
+ var defer = $q.defer();
+ var watchID = Math.floor((Math.random() * 1000000) + 1);
+ var self = this;
+
+ self.readings = [];
+
+ if (self.throwsError) {
+ defer.reject('There was an error getting the compass heading.');
+ } else {
+ var delay = 100; // The default based on https://github.com/apache/cordova-plugin-device-orientation/blob/master/doc/index.md
+ if (options && options.frequency) {
+ delay = options.frequency;
+ }
+
+ self.watchIntervals.push({
+ watchID: watchID,
+ interval: $interval(
+ function() {
+ if (self.throwsError) {
+ defer.reject('There was an error watching the acceleration.');
+ }
+
+ // Generate a random position
+ var magneticHeading = (Math.random() * 359.99) + 1;
+ var trueHeading = (Math.random() * 359.99) + 1;
+ var headingAccuracy = Math.floor((Math.random() * 360) + 1);
+ var result = { magneticHeading: magneticHeading, trueHeading: trueHeading, headingAccuracy:headingAccuracy, timestamp:Date.now() };
+
+ self.readings.push(result);
+ defer.notify(result);
+ },
+ delay
+ )
+ });
+ }
+
+ var cancel = function(id) {
+ var removed = -1;
+ for (var i=0; i<self.watchIntervals.length; i++) {
+ if (self.watchIntervals[i].watchID === id) {
+ $interval.cancel(watchIntervals[i].interval);
+ removed = i;
+ break;
+ }
+ }
+
+ if (removed !== -1) {
+ self.watchIntervals.splice(removed, 1);
+ }
+ };
+
+ defer.promise.cancel = function() {
+ cancel(watchID);
+ };
+
+ defer.promise.clearWatch = function(id) {
+ cancel(id || watchID);
+ };
+
+ defer.promise.watchID = watchID;
+
+ return defer.promise;
+ },
+
+ clearWatch: function (watchId) {
+ var defer = $q.defer();
+ if (watchId) {
+ if (this.throwsError) {
+ defer.reject('Unable to clear watch.');
+ } else {
+ var removed = -1;
+ for (var i=0; i<this.watchIntervals.length; i++) {
+ if (this.watchIntervals[i].watchId === watchId) {
+ $interval.cancel(watchIntervals[i].interval);
+ removed = i;
+ break;
+ }
+ }
+
+ if (removed !== -1) {
+ this.watchIntervals.splice(removed, 1);
+ }
+ }
+ } else {
+ defer.reject('Unable to clear watch. No watch ID provided.');
+ }
+ return defer.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * A service for testing dialogs
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaDialogs', ['$q', function ($q) {
+ var dialogText = false;
+ var dialogTitle = '';
+ var defaultValue = '';
+ var promptResponse = '';
+ var beepCount = 0;
+ var useHostAbilities = true;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name dialogText
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * The main content in the dialog.
+ * This property should only be used in automated tests.
+ **/
+ dialogText: dialogText,
+
+ /**
+ * @ngdoc property
+ * @name dialogTitle
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * The title of the dialog.
+ * This property should only be used in automated tests.
+ **/
+ dialogTitle: dialogTitle,
+
+ /**
+ * @ngdoc property
+ * @name defaultValue
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * The default value to be used in a prompt.
+ * This property should only be used in automated tests.
+ **/
+ defaultValue: defaultValue,
+
+ /**
+ * @ngdoc property
+ * @name promptResponse
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * Used to simulate a user's response to a prompt.
+ * This property should only be used in automated tests.
+ **/
+ promptResponse: promptResponse,
+
+ /**
+ * @ngdoc property
+ * @name buttonLabels
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * An array of the text of each button in the dialog.
+ * This property should only be used in automated tests.
+ **/
+ buttonLabels: [],
+
+ /**
+ * @ngdoc property
+ * @name beepCount
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * The number of times a beep has occurred.
+ * This property should only be used in automated tests.
+ **/
+ beepCount: beepCount,
+
+ /**
+ * @ngdoc property
+ * @name useHostAbilities
+ * @propertyOf ngCordovaMocks.cordovaDialogs
+ *
+ * @description
+ * A flag that signals whether or not to try and use the host's
+ * (browser or otherwise) prompting capabilities.
+ * This property should only be used in automated tests.
+ **/
+ useHostAbilities: useHostAbilities,
+
+ alert: function(message, title, buttonName) {
+ var d = $q.defer();
+
+ if (this.useHostAbilities) {
+ // NOTE: The window.alert method doesn't support a title or callbacks.
+ alert(message);
+ d.resolve();
+ } else {
+ this.dialogText = message;
+ this.dialogTitle = title;
+ this.buttonLabels.push(buttonName);
+ d.resolve();
+ }
+
+ return d.promise;
+ },
+
+ confirm: function(message, title, buttonName) {
+ var d = $q.defer();
+
+ if (this.useHostAbilities) {
+ // NOTE: The window.confirm method doesn't support a title or custom button naming.
+ var result = confirm(message);
+ d.resolve(result ? 2 : 1);
+ } else {
+ this.dialogText = message;
+ this.dialogTitle = title;
+ this.buttonLabels.push(buttonName);
+ d.resolve(0);
+ }
+
+ return d.promise;
+ },
+
+ prompt: function(message, title, buttonLabels, defaultText) {
+ var d = $q.defer();
+
+ if (this.useHostAbilities) {
+ // NOTE: The window.prompt method doesn't support a title or custom button naming.
+ var result = prompt(message, defaultText);
+ d.resolve(result);
+ } else {
+ this.dialogText = message;
+ this.dialogTitle = title;
+ this.defaultValue = defaultText;
+
+ for (var i=0; i<buttonLabels.length; i++) {
+ this.buttonLabels.push(buttonLabels[i]);
+ }
+
+ d.resolve(this.promptResponse);
+ }
+
+ return d.promise;
+ },
+
+ beep: function(times) {
+ this.beepCount = times;
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaFile
+ *
+ * @description
+ * A service for testing interaction with device directories and files
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaFile', ['$q', function($q) {
+ var throwsError = false;
+ var fileSystem = {};
+ var shouldMockFiles = false;
+ var files = {};
+
+ var mockIt = function(errorMessage) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject(errorMessage);
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ };
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaFile
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name fileSystem
+ * @propertyOf ngCordovaMocks.cordovaFile
+ *
+ * @description
+ * A fake, in-memory file system. This is incomplete at this time.
+ * This property should only be used in automated tests.
+ **/
+ fileSystem: fileSystem,
+
+ /**
+ * @ngdoc property
+ * @name shouldMockFiles
+ * @propertyOf ngCordovaMocks.cordovaFile
+ *
+ * @description
+ * A flag that signals whether one wish to mock files.
+ * This is useful if you need mocks specific file scenarios.
+ * This property should only be used in automated tests.
+ **/
+ shouldMockFiles: shouldMockFiles,
+
+ /**
+ * @ngdoc property
+ * @name files
+ * @propertyOf ngCordovaMocks.cordovaFile
+ *
+ * @description
+ * An object that may be used for mocking files on the device.
+ * This property should only be used in automated tests.
+ *
+ * **/
+ files : files,
+
+ checkDir: function(directory) {
+ if(this.shouldMockFiles){
+ var defer = $q.defer();
+ if(this.files[directory] && !this.files[directory].isFile){
+ defer.resolve();
+ }
+ else{
+ defer.reject();
+ }
+ return defer.promise;
+ }
+
+ return mockIt.call(this, 'There was an error checking the directory.');
+ },
+
+ createDir: function(directory, overwrite) {
+ if(this.shouldMockFiles ){
+ var defer = $q.defer();
+ this.files[directory] = { isFile : false};
+ defer.resolve();
+ return defer.promise;
+ }
+ return mockIt.call(this, 'There was an error creating the directory.');
+ },
+
+ listDir: function(filePath) {
+ return mockIt.call(this, 'There was an error listing the directory');
+ },
+
+ checkFile: function(filePath) {
+ if(this.shouldMockFiles){
+ var defer = $q.defer();
+ if(this.files[filePath] && this.files[filePath].isFile){
+ defer.resolve();
+ }
+ else{
+ defer.reject();
+ }
+ return defer.promise;
+ }
+ return mockIt.call(this, 'There was an error checking for the file.');
+ },
+
+
+ createFile: function(filePath,overwrite) {
+ if(this.shouldMockFiles){
+ var defer = $q.defer();
+ this.files[filePath] = {
+ isFile : true,
+ fileContent : ''
+ };
+ defer.resolve();
+ return defer.promise;
+ }
+
+ return mockIt.call(this, 'There was an error creating the file.');
+ },
+
+ removeFile: function(directory, file) {
+ return mockIt.call(this,'There was an error removng the file.');
+ },
+
+ writeFile: function(filePath,data,options) {
+ if(this.shouldMockFiles && filePath && data){
+ this.files[filePath] = {
+ isFile : true,
+ fileContent : data
+ };
+ }
+ return mockIt.call(this,'There was an error writing the file.');
+ },
+
+ readFile: function(filePath) {
+ return this.readAsText(filePath);
+ },
+
+ readAsText: function (filePath) {
+ if(this.shouldMockFiles){
+ var defer = $q.defer();
+ if(files[filePath] && files[filePath].isFile){
+ defer.resolve(files[filePath].fileContent);
+ }
+ else{
+ defer.reject();
+ }
+ return defer.promise;
+ }
+ return mockIt.call(this, 'There was an error reading the file as text.');
+ },
+
+ readAsDataURL: function (filePath) {
+ return mockIt.call(this, 'There was an error reading the file as a data url.');
+ },
+
+ readAsBinaryString: function (filePath) {
+ return mockIt.call(this, 'There was an error reading the file as a binary string.');
+ },
+
+ readAsArrayBuffer: function (filePath) {
+ return mockIt.call(this, 'There was an error reading the file as an array buffer.');
+ },
+
+ readFileMetadata: function (filePath) {
+ return mockIt.call(this, 'There was an error reading the file metadata');
+ },
+
+ readFileAbsolute: function (filePath) {
+ return mockIt.call(this, 'There was an error reading the file from the absolute path');
+ },
+
+ readFileMetadataAbsolute: function (filePath) {
+ return mockIt.call(this, 'There was an error reading the file metadta from the absolute path');
+ },
+
+ downloadFile: function(source, filePath, trust, options) {
+ return mockIt.call(this, 'There was an error downloading the file.');
+ },
+
+ uploadFile: function(server, filePath, options) {
+ return mockIt.call(this, 'There was an error uploading the file.');
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaFileOpener2
+ *
+ * @description
+ * A service for testing fileOpener2
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaFileOpener2', ['$q', function ($q) {
+
+ var throwsError = false;
+
+ return {
+
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaFileOpener2
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ open: function (file, type) {
+
+ var defer = $q.defer();
+
+ if(this.throwError) {
+ defer.reject({
+ status: 0,
+ message: 'There was an error capturing the file.'
+ });
+ } else {
+ defer.resolve();
+ }
+
+ return defer.promise;
+
+ },
+
+ uninstall: function (pack) {
+
+ var defer = $q.defer();
+
+ if(this.throwError) {
+ defer.reject({
+ status: 0,
+ message: 'There was an error capturing the packageId.'
+ });
+ } else {
+ defer.resolve();
+ }
+
+ return defer.promise;
+
+ },
+
+ appIsInstalled: function (pack) {
+
+ var defer = $q.defer();
+
+ if(this.throwError) {
+ defer.reject({
+ status: 0,
+ message: 'There was an error capturing the packageId.'
+ });
+ } else {
+ defer.resolve();
+ }
+
+ return defer.promise;
+
+ }
+
+ };
+
+}]);
+
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * A service for testing location services
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaGeolocation', ['$interval', '$q', function($interval, $q) {
+ var throwsError = false;
+ var useHostAbilities = true;
+
+ var watchIntervals = [];
+ var locations = [];
+ var currentPosition = null;
+ var nextPosition = null;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name watchIntervals
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * The collection of watchers that are currently active.
+ * This property should only be used in automated tests.
+ **/
+ watchIntervals: watchIntervals,
+
+ /**
+ * @ngdoc property
+ * @name locations
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * The collection of 'locations' that have been logged.
+ * This property should only be used in automated tests.
+ **/
+ locations: locations,
+
+ /**
+ * @ngdoc property
+ * @name currentPosition
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * The last location logged.
+ * This property should only be used in automated tests.
+ **/
+ currentPosition: currentPosition,
+
+ /**
+ * @ngdoc property
+ * @name nextPosition
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * The position to be logged the next time that a watcher
+ * gets the location.
+ * This property should only be used in automated tests.
+ **/
+ nextPosition: nextPosition,
+
+ /**
+ * @ngdoc property
+ * @name useHostAbilities
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * A flag that signals whether or not to try and use the host's
+ * (browser or otherwise) geolocation capabilities.
+ * This property should only be used in automated tests.
+ **/
+ useHostAbilities: useHostAbilities,
+
+ getCurrentPosition: function(options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the location.');
+ } else {
+ if (options) {
+ options = options; // This is just to get by JSHint.
+ }
+
+ if (this.useHostAbilities) {
+ if (navigator.geolocation) {
+ navigator.geolocation.getCurrentPosition(
+ function(position) {
+ this.currentPosition = position;
+ defer.resolve(this.currentPosition);
+ },
+ function(error) {
+ defer.reject(error);
+ }
+ );
+ } else {
+ defer.reject('Geolocation is not supported by this browser.');
+ }
+ } else {
+ defer.resolve(this.currentPosition);
+ }
+ }
+ return defer.promise;
+ },
+
+ watchPosition: function(options) {
+ var defer = $q.defer();
+ var watchID = Math.floor((Math.random() * 1000000) + 1);
+ var self = this;
+
+ self.locations = [];
+
+ if (self.throwsError) {
+ defer.reject('There was an error getting the geolocation.');
+ } else {
+ var delay = 1000;
+ if (options && options.timeout) {
+ delay = options.timeout;
+ }
+
+ self.watchIntervals.push({
+ watchID: watchID,
+ interval: $interval(
+ function() {
+ if (self.throwsError) {
+ defer.reject('There was an error watching the geolocation.');
+ }
+
+ // Attempt to use nextPosition.
+ var result = self.nextPosition;
+ if (result === null) {
+ // Determine whether to use the host's geolocation capabilities or not
+ if (self.useHostAbilities) {
+ if (navigator.geolocation) {
+ navigator.geolocation.getCurrentPosition(
+ function(position) {
+ self.currentPosition = position;
+ self.locations.push(position);
+ defer.resolve(position);
+ },
+ function(error) {
+ defer.reject(error);
+ }
+ );
+ } else {
+ defer.reject('Geolocation is not supported by this browser.');
+ }
+ } else {
+ result = {
+ coords: {
+ latitude: ((Math.random() * 180) + 1) - 90,
+ longitude: ((Math.random() * 360) + 1) - 180,
+ altitude: ((Math.random() * 100) + 1),
+
+ accuracy: ((Math.random() * 10) + 1),
+ altitudeAccuracy: ((Math.random() * 10) + 1),
+ heading: ((Math.random() * 360) + 1),
+ speed: ((Math.random() * 100) + 1)
+ },
+ timestamp: Date.now()
+ };
+
+ self.currentPosition = result;
+ self.locations.push(result);
+ defer.notify(result);
+ }
+ }
+ },
+ delay
+ )
+ });
+ }
+
+ var cancel = function(id) {
+ var removed = -1;
+ for (var i=0; i<self.watchIntervals.length; i++) {
+ if (self.watchIntervals[i].watchID === id) {
+ $interval.cancel(watchIntervals[i].interval);
+ removed = i;
+ break;
+ }
+ }
+
+ if (removed !== -1) {
+ self.watchIntervals.splice(removed, 1);
+ }
+ };
+
+ defer.promise.cancel = function() {
+ cancel(watchID);
+ };
+
+ defer.promise.clearWatch = function(id) {
+ cancel(id || watchID);
+ };
+
+ defer.promise.watchID = watchID;
+
+ return defer.promise;
+ },
+
+ clearWatch: function (watchID) {
+ var defer = $q.defer();
+ if (watchID) {
+ if (this.throwsError) {
+ defer.reject('Unable to clear watch.');
+ } else {
+ var removed = -1;
+ for (var i=0; i<this.watchIntervals.length; i++) {
+ if (this.watchIntervals[i].watchID === watchID) {
+ $interval.cancel(watchIntervals[i].interval);
+ removed = i;
+ break;
+ }
+ }
+
+ if (removed !== -1) {
+ this.watchIntervals.splice(removed, 1);
+ }
+ }
+ } else {
+ defer.reject('Unable to clear watch. No watch ID provided.');
+ }
+ return defer.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaGlobalization
+ *
+ * @description
+ * A service for testing features related to a user's locale and timezone.
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaGlobalization', ['$q', function($q) {
+ var throwsError = false;
+ var language = (navigator.language) ? navigator.language : "en-US";
+ var preferredLanguage = {value: language};
+ var firstDayOfWeek = 'Sunday';
+ var localeName = {value: language};
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaGlobalization
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name preferredLanguage
+ * @propertyOf ngCordovaMocks.cordovaGlobalization
+ *
+ * @description
+ * The user's preferred language.
+ * This property should only be used in automated tests.
+ **/
+ preferredLanguage: preferredLanguage,
+
+ /**
+ * @ngdoc property
+ * @name localeName
+ * @propertyOf ngCordovaMocks.cordovaGlobalization
+ *
+ * @description
+ * The name of the user's locale.
+ * This property should only be used in automated tests.
+ **/
+ localeName: localeName,
+
+ /**
+ * @ngdoc property
+ * @name firstDayOfWeek
+ * @propertyOf ngCordovaMocks.cordovaGlobalization
+ *
+ * @description
+ * The first day of the week based on the user's locale.
+ * This property should only be used in automated tests.
+ **/
+ firstDayOfWeek: firstDayOfWeek,
+
+ getPreferredLanguage: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the preferred language.');
+ } else {
+ defer.resolve(this.preferredLanguage);
+ }
+ return defer.promise;
+ },
+
+ getLocaleName: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the locale name.');
+ } else {
+ defer.resolve(this.localeName);
+ }
+ return defer.promise;
+ },
+
+ getFirstDayOfWeek: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the first day of week.');
+ } else {
+ defer.resolve(this.firstDayOfWeek);
+ }
+ return defer.promise;
+ },
+
+ dateToString: function(date, options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the string from the date.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ date = date;
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ stringToDate: function(dateString, options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the date from the string.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ dateString = dateString;
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ getDatePattern: function(options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the date pattern.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ getDateNames: function(options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting the date names.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ isDayLightSavingsTime: function(date) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error getting if this is in daylight savings time mode.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ date = date;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ numberToString: function(number, options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error convertng the number to a string.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ number = number;
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ stringToNumber: function(numberString, options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error convertng the string to a number.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ getNumberPattern: function(options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error convertng the string to a number.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ options = options;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ },
+
+ getCurrencyPattern: function(currencyCode) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error convertng the string to a number.');
+ } else {
+ var result = '';
+
+ // TODO: Review
+ currencyCode = currencyCode;
+ // END TODO: Review
+
+ defer.resolve(result);
+ }
+ return defer.promise;
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaGoogleAnalytics
+ *
+ * @description
+ * A service for testing google analytics services
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaGoogleAnalytics', ['$q', function($q) {
+ var throwsError = false;
+ var methods = {};
+
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaGeolocation
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ methods.throwsError = throwsError;
+
+ var methodsName = [
+ 'startTrackerWithId',
+ 'setUserId',
+ 'debugMode',
+ 'trackView',
+ 'addCustomDimension',
+ 'trackEvent',
+ 'addTransaction',
+ 'addTransactionItem'
+ ];
+
+ methodsName.forEach(function(funcName) {
+ methods[funcName] = function() {
+ var defer = $q.defer();
+
+ (this.throwsError) ?
+ defer.reject() :
+ defer.resolve();
+
+ return defer.promise;
+ };
+ });
+
+ return methods;
+}]);
+
+'use strict';
+
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.googlePlayGame
+ *
+ * @description
+ * A service for testing Google Play Game features
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaGooglePlayGame', ['$q', function ($q) {
+ var throwsError = false;
+ var isSignedIn = false;
+ var displayName = '';
+
+ return {
+
+ /**
+ * @ngdoc property
+ * @name _throwsError
+ * @propertyOf ngCordovaMocks.googlePlayGame
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ _throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name _isSignedIn
+ * @propertyOf ngCordovaMocks.googlePlayGame
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ _isSignedIn: isSignedIn,
+
+ /**
+ * @ngdoc property
+ * @name _displayName
+ * @propertyOf ngCordovaMocks.googlePlayGame
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ _displayName: displayName,
+
+ auth: function() {
+ var defer = $q.defer();
+ if (this._throwsError) {
+ defer.reject('There was a auth error.');
+ } else {
+ this.isSignedIn = true;
+ defer.resolve('SIGN IN SUCCESS');
+ }
+ return defer.promise;
+ },
+ signout: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was a signout error.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ isSignedIn: function() {
+ var defer = $q.defer();
+ if (this._throwsError) {
+ defer.reject('There was a isSignedIn error.');
+ } else {
+ defer.resolve({
+ 'isSignedIn': this._isSignedIn
+ });
+ }
+ return defer.promise;
+ },
+ showPlayer: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was a showPlayer error.');
+ } else {
+ defer.resolve({
+ 'displayName': this._displayName
+ });
+ }
+ return defer.promise;
+ },
+ submitScore: function(data) {
+ var defer = $q.defer();
+ if (this._throwsError) {
+ defer.reject('There was a submitScore error.');
+ } else {
+ defer.resolve('OK');
+ }
+ return defer.promise;
+ },
+ showAllLeaderboards: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was a showAllLeaderboards error.');
+ } else {
+ defer.resolve('OK');
+ }
+ return defer.promise;
+ },
+ showLeaderboard: function(data) {
+ var defer = $q.defer();
+ if (this._throwsError) {
+ defer.reject('There was a showLeaderboard error.');
+ } else {
+ defer.resolve('OK');
+ }
+ return defer.promise;
+ },
+ unlockAchievement: function(data) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was a unlockAchievement error.');
+ } else {
+ defer.resolve('OK');
+ }
+ return defer.promise;
+ },
+ incrementAchievement: function(data) {
+ var defer = $q.defer();
+ if (this._throwsError) {
+ defer.reject('There was a incrementAchievement error.');
+ } else {
+ defer.resolve('OK');
+ }
+ return defer.promise;
+ },
+ showAchievements: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was a showAchievements error.');
+ } else {
+ defer.resolve('OK');
+ }
+ return defer.promise;
+ }
+ };
+
+ }]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaKeyboard
+ *
+ * @description
+ * A service for testing device keyboard features
+ * in an app build with ngCordova.
+**/
+ngCordovaMocks.factory('$cordovaKeyboard', function() {
+ var isVisible=false;
+
+ return {
+ hideAccessoryBar: function (bool) {
+ },
+
+ close: function () {
+ isVisible = false;
+ },
+
+ show: function () {
+ isVisible = true;
+ },
+
+ disableScroll: function (bool) {
+ },
+
+ isVisible: function () {
+ return isVisible;
+ }
+
+ };
+});
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaKeychain
+ *
+ * @description
+ * A service for testing Keychain features
+ * in an app built with ngCordova.
+ **/
+ngCordovaMocks.factory('$cordovaKeychain', ['$q', function($q) {
+ var keychains = {};
+
+ return {
+ /**
+ * @ngdoc property
+ * @name keychains
+ * @propertyOf ngCordovaMocks.cordovaKeychain
+ *
+ * @description
+ * The collection of 'keychains' that have been saved.
+ * This property should only be used in automated tests.
+ **/
+ keychains: keychains,
+
+ getForKey: function (key, serviceName) {
+ var defer = $q.defer();
+
+ if (this.keychains[serviceName]) {
+ defer.resolve(this.keychains[serviceName][key]);
+ } else {
+ defer.reject();
+ }
+
+ return defer.promise;
+ },
+
+ setForKey: function (key, serviceName, value) {
+ var defer = $q.defer();
+
+ if (!this.keychains[serviceName]) {
+ this.keychains[serviceName] = {};
+ }
+
+ this.keychains[serviceName][key] = value;
+
+ defer.resolve();
+
+ return defer.promise;
+ },
+
+ removeForKey: function (key, serviceName) {
+ var defer = $q.defer();
+
+ if (this.keychains[serviceName]) {
+ delete this.keychains[serviceName][key];
+ }
+
+ defer.resolve();
+
+ return defer.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaNetwork
+ *
+ * @description
+ * A service for testing networked fetures
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaNetwork', function () {
+ var connectionType = 'WiFi connection';
+ var isConnected = true;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name connectionType
+ * @propertyOf ngCordovaMocks.cordovaNetwork
+ *
+ * @description
+ * They type of connection. Values should match those found at
+ * https://github.com/apache/cordova-plugin-network-information/blob/master/doc/index.md
+ * This property should only be used in automated tests.
+ **/
+ connectionType: connectionType,
+
+ /**
+ * @ngdoc property
+ * @name isConnected
+ * @propertyOf ngCordovaMocks.cordovaNetwork
+ *
+ * @description
+ * A flag that signals whether the app is connected to a network.
+ * This property should only be used in automated tests.
+ **/
+ isConnected: isConnected,
+
+ getNetwork: function () {
+ return this.connectionType;
+ },
+
+ isOnline: function () {
+ return this.isConnected;
+ },
+
+ isOffline: function () {
+ return !this.isConnected;
+ }
+ };
+});
+'use strict';
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaPush
+ *
+ * @description
+ * A service for testing push notifications features
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaPush', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
+ var throwsError = false;
+
+ var deviceToken = '';
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaPush
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name deviceToken
+ * @propertyOf ngCordovaMocks.cordovaPush
+ *
+ * @description
+ * Token send when service register device
+ * This property should only be used in automated tests.
+ **/
+ deviceToken: deviceToken,
+
+ onNotification: function (notification) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaPush:notificationReceived', notification);
+ });
+ },
+
+ register: function (config) {
+ var _self = this;
+ var defer = $q.defer();
+ if (config !== undefined && config.ecb === undefined) {
+ config.ecb = this.onNotification;
+ }
+
+ if (this.throwsError) {
+ defer.reject('There was a register error.');
+ } else {
+ defer.resolve(this.deviceToken);
+ if (config && config.ecb) {
+ config.ecb({
+ event: 'registered',
+ regid: _self.deviceToken
+ });
+ }
+ }
+ return defer.promise;
+ },
+
+ unregister: function (options) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was a register error.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * A service for testing via social services
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaSocialSharing', ['$q', function($q) {
+ var throwsError = false;
+ var message = '';
+ var image = '';
+ var link = '';
+ var number = '';
+
+ var socialService = '';
+ var subject = '';
+ var toAddresses = [];
+ var bccAddresses = [];
+ var attachments = [];
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ /**
+ * @ngdoc property
+ * @name message
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * The message to be shared via a social service.
+ * This property should only be used in automated tests.
+ **/
+ message: message,
+
+ /**
+ * @ngdoc property
+ * @name image
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * An image to be shared via a social service.
+ * This property should only be used in automated tests.
+ **/
+ image: image,
+
+ /**
+ * @ngdoc property
+ * @name link
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * A link to be shared via a social service.
+ * This property should only be used in automated tests.
+ **/
+ link: link,
+
+ /**
+ * @ngdoc property
+ * @name number
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * A comma-delimited list of phone numbers to send a social message to.
+ * This property should only be used in automated tests.
+ **/
+ number: number,
+
+ /**
+ * @ngdoc property
+ * @name subject
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * The subject of an email.
+ * This property should only be used in automated tests.
+ **/
+ subject: subject,
+
+ /**
+ * @ngdoc property
+ * @name toAddresses
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * An array of email addresses to send an email to.
+ * This property should only be used in automated tests.
+ **/
+ toAddresses: toAddresses,
+
+ /**
+ * @ngdoc property
+ * @name bccAddresses
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * An array of email addresses to blind carbon-copy an email to.
+ * This property should only be used in automated tests.
+ **/
+ bccAddresses: bccAddresses,
+
+ /**
+ * @ngdoc property
+ * @name socialService
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * The name of a social service to share content through.
+ * This property should only be used in automated tests.
+ **/
+ socialService: socialService,
+
+ /**
+ * @ngdoc property
+ * @name attachments
+ * @propertyOf ngCordovaMocks.cordovaSocialSharing
+ *
+ * @description
+ * An array of attachments to include with an email to be sent.
+ * This property should only be used in automated tests.
+ **/
+ attachments: attachments,
+
+ shareViaTwitter: function(message, image, link) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via Twitter.');
+ } else {
+ this.message = message;
+ this.image = image;
+ this.link = link;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ shareViaWhatsApp: function(message, image, link) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via WhatsApp.');
+ } else {
+ this.message = message;
+ this.image = image;
+ this.link = link;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ shareViaFacebook: function(message, image, link) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via Facebook.');
+ } else {
+ this.message = message;
+ this.image = image;
+ this.link = link;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ shareViaSMS: function(message, number) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via SMS.');
+ } else {
+ this.message = message;
+ this.number = number;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ shareViaEmail: function(message, subject, toArr, bccArr, file) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via SMS.');
+ } else {
+ // These are added to get by JSHINT for now
+ this.message = message;
+ this.subject = subject;
+ this.toAddresses = toArr;
+ this.bccAddressesc = bccArr;
+ this.attachments = file;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ canShareViaEmail: function() {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject(false);
+ } else {
+ defer.resolve(true);
+ }
+ return defer.promise;
+ },
+
+ canShareVia: function(via, message, subject, file, link) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via SMS.');
+ } else {
+ // These are added to get by JSHINT for now
+ this.message = message;
+ this.socialService = via;
+ this.subject = subject;
+ this.attachments = file;
+ this.link = link;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ shareVia: function(via, message, subject, file, link) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via SMS.');
+ } else {
+ this.socialService = via;
+ this.message = message;
+ this.subject = subject;
+ this.attachments = file;
+ this.link = link;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+
+ share: function(message, subject, file, link) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error sharing via SMS.');
+ } else {
+ this.message = message;
+ this.subject = subject;
+ this.attachments = file;
+ this.link = link;
+
+ defer.resolve();
+ }
+ return defer.promise;
+ }
+ };
+}]);
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaSplashscreen
+ *
+ * @description
+ * A service for testing the splash screen
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaSplashscreen', function() {
+ var isVisible = false;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name isVisible
+ * @propertyOf ngCordovaMocks.cordovaSplashscreen
+ *
+ * @description
+ * A flag that signals whether the splash screen is visible or not.
+ * This property should only be used in automated tests.
+ **/
+ isVisible: isVisible,
+
+ hide: function() {
+ // do nothing. everything happens behind the scenes in this case.
+ // its a stub that is present for completeness.
+ this.isVisible = false;
+ return true;
+ },
+ show: function() {
+ // do nothing. everything happens behind the scenes in this case.
+ // its a stub that is present for completeness.
+ this.isVisible = true;
+ return true;
+ }
+ };
+});
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaStatusbar
+ *
+ * @description
+ * A service for testing the status bar
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaStatusbar', function() {
+ var isStatusBarVisible = true;
+ var canOverlayWebView = true;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name isStatusBarVisible
+ * @propertyOf ngCordovaMocks.cordovaStatusbar
+ *
+ * @description
+ * A flag that signals whether the status bar is visible or not.
+ * This property should only be used in automated tests.
+ **/
+ isStatusBarVisible: isStatusBarVisible,
+
+ /**
+ * @ngdoc property
+ * @name canOverlayWebView
+ * @propertyOf ngCordovaMocks.cordovaStatusbar
+ *
+ * @description
+ * A flag that signals whether the status bar can overlay the web view.
+ * This property should only be used in automated tests.
+ **/
+ canOverlayWebView: canOverlayWebView,
+
+ overlaysWebView: function(bool) {
+ this.canOverlayWebView = bool;
+ },
+
+ style: function(style) {
+ // TODO: Review
+ return style;
+ },
+
+ styleHex: function(colorHex) {
+ // TODO: review
+ return colorHex;
+ },
+
+ styleColor: function(color) {
+ // TODO: review
+ return color;
+ },
+
+ hide: function() {
+ this.isStatusBarVisible = false;
+ },
+
+ show: function() {
+ this.isStatusBarVisible = true;
+ },
+
+ isVisible: function () {
+ return this.isStatusBarVisible;
+ }
+ };
+});
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaToast
+ *
+ * @description
+ * A service for testing toasts
+ * in an app build with ngCordova.
+ *
+ * @example
+ */
+ngCordovaMocks.factory('$cordovaToast', ['$q', function ($q) {
+ var throwsError = false;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name throwsError
+ * @propertyOf ngCordovaMocks.cordovaToast
+ *
+ * @description
+ * A flag that signals whether a promise should be rejected or not.
+ * This property should only be used in automated tests.
+ **/
+ throwsError: throwsError,
+
+ showShortTop: function (message) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ showShortCenter: function (message) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ showShortBottom: function (message) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ showLongTop: function (message) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ showLongCenter: function (message) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ showLongBottom: function (message) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ },
+ show: function (message, duration, position) {
+ var defer = $q.defer();
+ if (this.throwsError) {
+ defer.reject('There was an error showing the toast.');
+ } else {
+ defer.resolve();
+ }
+ return defer.promise;
+ }
+ };
+}]);
+
+/**
+ * @ngdoc service
+ * @name ngCordovaMocks.cordovaVibration
+ *
+ * @description
+ * A service for testing vibration
+ * in an app build with ngCordova.
+ */
+ngCordovaMocks.factory('$cordovaVibration', ['$timeout', function($timeout) {
+ var isVibrating = false;
+ var vibrateTimer = null;
+
+ return {
+ /**
+ * @ngdoc property
+ * @name vibrateTimer
+ * @propertyOf ngCordovaMocks.cordovaVibration
+ *
+ * @description
+ * Access to the timer associated with vibration.
+ * This property should only be used in automated tests.
+ **/
+ vibrateTimer: vibrateTimer,
+
+ /**
+ * @ngdoc property
+ * @name isVibrating
+ * @propertyOf ngCordovaMocks.cordovaVibration
+ *
+ * @description
+ * A flag that signals whether vibration is active.
+ * This property should only be used in automated tests.
+ **/
+ isVibrating: isVibrating,
+
+ vibrate: function(time) {
+ if (time > 0) {
+ this.isVibrating = true;
+ self = this;
+
+ if (time instanceof Array) {
+ // TODO: Implement pattern here.
+ // The following is a temporary timer that just looks at the first value
+ this.vibrateTimer = $timeout(
+ function() {
+ self.isVibrating = false;
+ self.vibrateTimer = null;
+ },
+ time[0]
+ );
+ } else {
+ this.vibrateTimer = $timeout(
+ function() {
+ self.isVibrating = false;
+ self.vibrateTimer = null;
+ },
+ time
+ );
+ }
+ }
+ },
+
+ /* jshint ignore:start */
+ vibrateWithPattern: function(pattern, repeat) {
+ // Based on the documentation (https://github.com/apache/cordova-plugin-vibration/blob/master/doc/index.md)
+ // This method is deprecated. For that reason, this isn't implemented at this time.
+ },
+ /* jshint ignore:end */
+
+ cancelVibration: function() {
+ if (this.vibrateTimer !== null) {
+ if (this.isVibrating === true) {
+ $timeout.cancel(this.vibrateTimer);
+ this.isVibrating = false;
+ }
+ }
+ }
+ };
+}]);
+})();
diff --git a/www/lib/ngCordova/dist/ng-cordova-mocks.min.js b/www/lib/ngCordova/dist/ng-cordova-mocks.min.js
new file mode 100644
index 00000000..1d6d9a5d
--- /dev/null
+++ b/www/lib/ngCordova/dist/ng-cordova-mocks.min.js
@@ -0,0 +1,7 @@
+/*!
+ * ngCordova
+ * v0.1.15-alpha
+ * Copyright 2014 Drifty Co. http://drifty.com/
+ * See LICENSE in this repository for license information
+ */
+!function(){var r=angular.module("ngCordovaMocks",[]);r.factory("$cordovaAppVersion",["$q",function(r){var e=!1;return{throwsError:e,getAppVersion:function(){var e=r.defer();return e.resolve("mock v"),e.promise}}}]),r.factory("$cordovaBarcodeScanner",["$q",function(r){var e=!1,t="",o="",i=!1;return{throwsError:e,scannedText:t,scannedFormat:o,wasCancelled:i,scan:function(){var e=r.defer();return this.throwsError?e.reject("There was an error scanning."):e.resolve({text:this.scannedText,format:this.scannedFormat,cancelled:this.wasCancelled}),e.promise},encode:function(e,t){this.scannedFormat=e,this.scannedText=t;var o=r.defer();return this.throwsError?o.reject("There was an error encoding the data."):o.resolve(),o.promise}}}]),r.factory("$cordovaBLE",["$q","$timeout",function(r,e){var t={name:"Test Device",id:"AA:BB:CC:DD:EE:FF",advertising:[2,1,6,3,3,15,24,8,9,66,97,116,116,101,114,121],rssi:-55},o={name:"Test Device",id:"AA:BB:CC:DD:EE:FF",advertising:[2,1,6,3,3,15,24,8,9,66,97,116,116,101,114,121],rssi:-55,services:["1800","1801","180f"],characteristics:[{service:"1800",characteristic:"2a00",properties:["Read"]},{service:"1800",characteristic:"2a01",properties:["Read"]},{service:"1801",characteristic:"2a05",properties:["Read"]},{service:"180f",characteristic:"2a19",properties:["Read"],descriptors:[{uuid:"2901"},{uuid:"2904"}]}]},i=new ArrayBuffer(8);return{scan:function(o,i){var n=r.defer();return e(function(){n.resolve(t)},1e3*i),n.promise},connect:function(){var t=r.defer();return e(function(){t.resolve(o)},1500),t.promise},disconnect:function(){var t=r.defer();return e(function(){t.resolve(!0)},500),t.promise},read:function(){var t=r.defer();return e(function(){t.resolve(i)},100),t.promise},write:function(){var t=r.defer();return e(function(){t.resolve(!0)},100),t.promise},writeCommand:function(){var t=r.defer();return e(function(){t.resolve(!0)},100),t.promise},notify:function(){var t=r.defer();return e(function(){t.resolve(!0)},100),t.promise},indicate:function(){var t=r.defer();return e(function(){t.resolve(!0)},100),t.promise},isConnected:function(){var e=r.defer();return e.resolve(!0),e.promise},isEnabled:function(){var e=r.defer();return e.resolve(!0),e.promise}}}]),r.factory("$cordovaCamera",["$q",function(r){var e=!1,t="";return{throwsError:e,imageData:t,getPicture:function(e){var t=r.defer();return this.throwsError?t.reject("There was an error getting the picture."):(e&&(e=e),t.resolve(this.imageData)),t.promise}}}]),r.factory("$cordovaCapture",["$q",function(r){var e=!1;return{throwsError:e,captureAudio:function(){var e=r.defer();return this.throwsError?e.reject("There was an error capturing the audio."):e.resolve(),e.promise},captureImage:function(){var e=r.defer();return this.throwsError?e.reject("There was an error capturing the image."):e.resolve(),e.promise},captureVideo:function(){var e=r.defer();return this.throwsError?e.reject("There was an error capturing the video."):e.resolve(),e.promise}}}]),r.factory("$cordovaContacts",["$q",function(r){var e=!1,t=[];return{throwsError:e,contacts:t,save:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error saving the contact.");else{for(var o=null,i=0;i<this.contacts.length;i++)if(this.contacts[i].id===e.id){o=i;break}null===o?(this.contacts.push(e),t.resolve()):t.reject("Contact already exists.")}return t.promise},remove:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error saving the contact.");else{for(var o=null,i=0;i<this.contacts.length;i++)if(this.contacts[i].id===e.id){o=i;break}null===o?t.reject("Unable to find contact."):(this.contacts.splice(o,1),t.resolve())}return t.promise},find:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error finding the contact.");else{var o=e.fields||["id","displayName"];if(delete e.fields,o)if("*"===o)t.resolve(this.contacts);else{for(var i=[],n=0;n<this.contacts.length;n++)for(var s in this.contacts[n])var a=this.contacts[n][s];t.resolve(i)}else t.reject("ContactError.INVALID_ARGUMENT_ERROR")}return t.promise}}}]),r.factory("$cordovaDatePicker",["$q",function(r){return{show:function(e){var t=r.defer();return e=e||{date:new Date,mode:"date"},t.resolve(e.date),t.promise}}}]),r.factory("$cordovaDevice",function(){var r="",e="",t="",o="",i="",n="";return{device:r,cordova:e,model:t,platform:o,uuid:i,version:n,getDevice:function(){return this.device},getCordova:function(){return this.cordova},getModel:function(){return this.model},getPlatform:function(){return this.platform},getUUID:function(){return this.uuid},getVersion:function(){return this.version}}}),r.factory("$cordovaDeviceMotion",["$interval","$q",function(r,e){var t=null,o=!1,i=[],n=[];return{currentAcceleration:t,throwsError:o,positions:i,watchIntervals:n,getCurrentAcceleration:function(){var r=e.defer();return this.throwsError?r.reject("There was an error getting the current acceleration."):r.resolve(this.currentAcceleration),r.promise},watchAcceleration:function(t){var o=e.defer(),i=Math.floor(1e6*Math.random()+1);if(this.positions=[],self=this,this.throwsError)o.reject("There was an error watching the current acceleration.");else{var n=1e4;t&&t.frequency&&(n=t.frequency),this.watchIntervals.push(r(function(){self.throwsError&&o.reject("There was an error watching the acceleration.");var r=Math.floor(100*Math.random()+1),e=Math.floor(100*Math.random()+1),t=Math.floor(100*Math.random()+1),i={x:r,y:e,z:t,timestamp:Date.now()};self.positions.push(i),o.notify(i)},n))}return{watchId:i,promise:o.promise}},clearWatch:function(t){var o=e.defer();if(t)if(this.throwsError)o.reject("Unable to clear watch.");else{for(var i=-1,s=0;s<this.watchIntervals.length;s++)if(this.watchIntervals[s].watchId===t){r.cancel(n[s].interval),i=s;break}-1!==i&&this.watchIntervals.splice(i,1)}else o.reject("Unable to clear watch. No watch ID provided.");return o.promise}}}]),r.factory("$cordovaDeviceOrientation",["$interval","$q",function(r,e){var t=null,o=!1,i=[],n=[];return{currentHeading:t,throwsError:o,readings:i,watchIntervals:n,getCurrentHeading:function(){var r=e.defer();return this.throwsError?r.reject("There was an error getting the current heading."):r.resolve(this.currentHeading),r.promise},watchHeading:function(t){var o=e.defer(),i=Math.floor(1e6*Math.random()+1),s=this;if(s.readings=[],s.throwsError)o.reject("There was an error getting the compass heading.");else{var a=100;t&&t.frequency&&(a=t.frequency),s.watchIntervals.push({watchID:i,interval:r(function(){s.throwsError&&o.reject("There was an error watching the acceleration.");var r=359.99*Math.random()+1,e=359.99*Math.random()+1,t=Math.floor(360*Math.random()+1),i={magneticHeading:r,trueHeading:e,headingAccuracy:t,timestamp:Date.now()};s.readings.push(i),o.notify(i)},a)})}var c=function(e){for(var t=-1,o=0;o<s.watchIntervals.length;o++)if(s.watchIntervals[o].watchID===e){r.cancel(n[o].interval),t=o;break}-1!==t&&s.watchIntervals.splice(t,1)};return o.promise.cancel=function(){c(i)},o.promise.clearWatch=function(r){c(r||i)},o.promise.watchID=i,o.promise},clearWatch:function(t){var o=e.defer();if(t)if(this.throwsError)o.reject("Unable to clear watch.");else{for(var i=-1,s=0;s<this.watchIntervals.length;s++)if(this.watchIntervals[s].watchId===t){r.cancel(n[s].interval),i=s;break}-1!==i&&this.watchIntervals.splice(i,1)}else o.reject("Unable to clear watch. No watch ID provided.");return o.promise}}}]),r.factory("$cordovaDialogs",["$q",function(r){var e=!1,t="",o="",i="",n=0,s=!0;return{dialogText:e,dialogTitle:t,defaultValue:o,promptResponse:i,buttonLabels:[],beepCount:n,useHostAbilities:s,alert:function(e,t,o){var i=r.defer();return this.useHostAbilities?(alert(e),i.resolve()):(this.dialogText=e,this.dialogTitle=t,this.buttonLabels.push(o),i.resolve()),i.promise},confirm:function(e,t,o){var i=r.defer();if(this.useHostAbilities){var n=confirm(e);i.resolve(n?2:1)}else this.dialogText=e,this.dialogTitle=t,this.buttonLabels.push(o),i.resolve(0);return i.promise},prompt:function(e,t,o,i){var n=r.defer();if(this.useHostAbilities){var s=prompt(e,i);n.resolve(s)}else{this.dialogText=e,this.dialogTitle=t,this.defaultValue=i;for(var a=0;a<o.length;a++)this.buttonLabels.push(o[a]);n.resolve(this.promptResponse)}return n.promise},beep:function(r){this.beepCount=r}}}]),r.factory("$cordovaFile",["$q",function(r){var e=!1,t={},o=!1,i={},n=function(e){var t=r.defer();return this.throwsError?t.reject(e):t.resolve(),t.promise};return{throwsError:e,fileSystem:t,shouldMockFiles:o,files:i,checkDir:function(e){if(this.shouldMockFiles){var t=r.defer();return this.files[e]&&!this.files[e].isFile?t.resolve():t.reject(),t.promise}return n.call(this,"There was an error checking the directory.")},createDir:function(e){if(this.shouldMockFiles){var t=r.defer();return this.files[e]={isFile:!1},t.resolve(),t.promise}return n.call(this,"There was an error creating the directory.")},listDir:function(){return n.call(this,"There was an error listing the directory")},checkFile:function(e){if(this.shouldMockFiles){var t=r.defer();return this.files[e]&&this.files[e].isFile?t.resolve():t.reject(),t.promise}return n.call(this,"There was an error checking for the file.")},createFile:function(e){if(this.shouldMockFiles){var t=r.defer();return this.files[e]={isFile:!0,fileContent:""},t.resolve(),t.promise}return n.call(this,"There was an error creating the file.")},removeFile:function(){return n.call(this,"There was an error removng the file.")},writeFile:function(r,e){return this.shouldMockFiles&&r&&e&&(this.files[r]={isFile:!0,fileContent:e}),n.call(this,"There was an error writing the file.")},readFile:function(r){return this.readAsText(r)},readAsText:function(e){if(this.shouldMockFiles){var t=r.defer();return i[e]&&i[e].isFile?t.resolve(i[e].fileContent):t.reject(),t.promise}return n.call(this,"There was an error reading the file as text.")},readAsDataURL:function(){return n.call(this,"There was an error reading the file as a data url.")},readAsBinaryString:function(){return n.call(this,"There was an error reading the file as a binary string.")},readAsArrayBuffer:function(){return n.call(this,"There was an error reading the file as an array buffer.")},readFileMetadata:function(){return n.call(this,"There was an error reading the file metadata")},readFileAbsolute:function(){return n.call(this,"There was an error reading the file from the absolute path")},readFileMetadataAbsolute:function(){return n.call(this,"There was an error reading the file metadta from the absolute path")},downloadFile:function(){return n.call(this,"There was an error downloading the file.")},uploadFile:function(){return n.call(this,"There was an error uploading the file.")}}}]),r.factory("$cordovaFileOpener2",["$q",function(r){var e=!1;return{throwsError:e,open:function(){var e=r.defer();return this.throwError?e.reject({status:0,message:"There was an error capturing the file."}):e.resolve(),e.promise},uninstall:function(){var e=r.defer();return this.throwError?e.reject({status:0,message:"There was an error capturing the packageId."}):e.resolve(),e.promise},appIsInstalled:function(){var e=r.defer();return this.throwError?e.reject({status:0,message:"There was an error capturing the packageId."}):e.resolve(),e.promise}}}]),r.factory("$cordovaGeolocation",["$interval","$q",function(r,e){var t=!1,o=!0,i=[],n=[],s=null,a=null;return{throwsError:t,watchIntervals:i,locations:n,currentPosition:s,nextPosition:a,useHostAbilities:o,getCurrentPosition:function(r){var t=e.defer();return this.throwsError?t.reject("There was an error getting the location."):(r&&(r=r),this.useHostAbilities?navigator.geolocation?navigator.geolocation.getCurrentPosition(function(r){this.currentPosition=r,t.resolve(this.currentPosition)},function(r){t.reject(r)}):t.reject("Geolocation is not supported by this browser."):t.resolve(this.currentPosition)),t.promise},watchPosition:function(t){var o=e.defer(),n=Math.floor(1e6*Math.random()+1),s=this;if(s.locations=[],s.throwsError)o.reject("There was an error getting the geolocation.");else{var a=1e3;t&&t.timeout&&(a=t.timeout),s.watchIntervals.push({watchID:n,interval:r(function(){s.throwsError&&o.reject("There was an error watching the geolocation.");var r=s.nextPosition;null===r&&(s.useHostAbilities?navigator.geolocation?navigator.geolocation.getCurrentPosition(function(r){s.currentPosition=r,s.locations.push(r),o.resolve(r)},function(r){o.reject(r)}):o.reject("Geolocation is not supported by this browser."):(r={coords:{latitude:180*Math.random()+1-90,longitude:360*Math.random()+1-180,altitude:100*Math.random()+1,accuracy:10*Math.random()+1,altitudeAccuracy:10*Math.random()+1,heading:360*Math.random()+1,speed:100*Math.random()+1},timestamp:Date.now()},s.currentPosition=r,s.locations.push(r),o.notify(r)))},a)})}var c=function(e){for(var t=-1,o=0;o<s.watchIntervals.length;o++)if(s.watchIntervals[o].watchID===e){r.cancel(i[o].interval),t=o;break}-1!==t&&s.watchIntervals.splice(t,1)};return o.promise.cancel=function(){c(n)},o.promise.clearWatch=function(r){c(r||n)},o.promise.watchID=n,o.promise},clearWatch:function(t){var o=e.defer();if(t)if(this.throwsError)o.reject("Unable to clear watch.");else{for(var n=-1,s=0;s<this.watchIntervals.length;s++)if(this.watchIntervals[s].watchID===t){r.cancel(i[s].interval),n=s;break}-1!==n&&this.watchIntervals.splice(n,1)}else o.reject("Unable to clear watch. No watch ID provided.");return o.promise}}}]),r.factory("$cordovaGlobalization",["$q",function(r){var e=!1,t=navigator.language?navigator.language:"en-US",o={value:t},i="Sunday",n={value:t};return{throwsError:e,preferredLanguage:o,localeName:n,firstDayOfWeek:i,getPreferredLanguage:function(){var e=r.defer();return this.throwsError?e.reject("There was an error getting the preferred language."):e.resolve(this.preferredLanguage),e.promise},getLocaleName:function(){var e=r.defer();return this.throwsError?e.reject("There was an error getting the locale name."):e.resolve(this.localeName),e.promise},getFirstDayOfWeek:function(){var e=r.defer();return this.throwsError?e.reject("There was an error getting the first day of week."):e.resolve(this.firstDayOfWeek),e.promise},dateToString:function(e,t){var o=r.defer();if(this.throwsError)o.reject("There was an error getting the string from the date.");else{var i="";e=e,t=t,o.resolve(i)}return o.promise},stringToDate:function(e,t){var o=r.defer();if(this.throwsError)o.reject("There was an error getting the date from the string.");else{var i="";e=e,t=t,o.resolve(i)}return o.promise},getDatePattern:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error getting the date pattern.");else{var o="";e=e,t.resolve(o)}return t.promise},getDateNames:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error getting the date names.");else{var o="";e=e,t.resolve(o)}return t.promise},isDayLightSavingsTime:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error getting if this is in daylight savings time mode.");else{var o="";e=e,t.resolve(o)}return t.promise},numberToString:function(e,t){var o=r.defer();if(this.throwsError)o.reject("There was an error convertng the number to a string.");else{var i="";e=e,t=t,o.resolve(i)}return o.promise},stringToNumber:function(e,t){var o=r.defer();if(this.throwsError)o.reject("There was an error convertng the string to a number.");else{var i="";t=t,o.resolve(i)}return o.promise},getNumberPattern:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error convertng the string to a number.");else{var o="";e=e,t.resolve(o)}return t.promise},getCurrencyPattern:function(e){var t=r.defer();if(this.throwsError)t.reject("There was an error convertng the string to a number.");else{var o="";e=e,t.resolve(o)}return t.promise}}}]),r.factory("$cordovaGoogleAnalytics",["$q",function(r){var e=!1,t={};t.throwsError=e;var o=["startTrackerWithId","setUserId","debugMode","trackView","addCustomDimension","trackEvent","addTransaction","addTransactionItem"];return o.forEach(function(e){t[e]=function(){var e=r.defer();return this.throwsError?e.reject():e.resolve(),e.promise}}),t}]),r.factory("$cordovaGooglePlayGame",["$q",function(r){var e=!1,t=!1,o="";return{_throwsError:e,_isSignedIn:t,_displayName:o,auth:function(){var e=r.defer();return this._throwsError?e.reject("There was a auth error."):(this.isSignedIn=!0,e.resolve("SIGN IN SUCCESS")),e.promise},signout:function(){var e=r.defer();return this.throwsError?e.reject("There was a signout error."):e.resolve(),e.promise},isSignedIn:function(){var e=r.defer();return this._throwsError?e.reject("There was a isSignedIn error."):e.resolve({isSignedIn:this._isSignedIn}),e.promise},showPlayer:function(){var e=r.defer();return this.throwsError?e.reject("There was a showPlayer error."):e.resolve({displayName:this._displayName}),e.promise},submitScore:function(){var e=r.defer();return this._throwsError?e.reject("There was a submitScore error."):e.resolve("OK"),e.promise},showAllLeaderboards:function(){var e=r.defer();return this.throwsError?e.reject("There was a showAllLeaderboards error."):e.resolve("OK"),e.promise},showLeaderboard:function(){var e=r.defer();return this._throwsError?e.reject("There was a showLeaderboard error."):e.resolve("OK"),e.promise},unlockAchievement:function(){var e=r.defer();return this.throwsError?e.reject("There was a unlockAchievement error."):e.resolve("OK"),e.promise},incrementAchievement:function(){var e=r.defer();return this._throwsError?e.reject("There was a incrementAchievement error."):e.resolve("OK"),e.promise},showAchievements:function(){var e=r.defer();return this.throwsError?e.reject("There was a showAchievements error."):e.resolve("OK"),e.promise}}}]),r.factory("$cordovaKeyboard",function(){var r=!1;return{hideAccessoryBar:function(){},close:function(){r=!1},show:function(){r=!0},disableScroll:function(){},isVisible:function(){return r}}}),r.factory("$cordovaKeychain",["$q",function(r){var e={};return{keychains:e,getForKey:function(e,t){var o=r.defer();return this.keychains[t]?o.resolve(this.keychains[t][e]):o.reject(),o.promise},setForKey:function(e,t,o){var i=r.defer();return this.keychains[t]||(this.keychains[t]={}),this.keychains[t][e]=o,i.resolve(),i.promise},removeForKey:function(e,t){var o=r.defer();return this.keychains[t]&&delete this.keychains[t][e],o.resolve(),o.promise}}}]),r.factory("$cordovaNetwork",function(){var r="WiFi connection",e=!0;return{connectionType:r,isConnected:e,getNetwork:function(){return this.connectionType},isOnline:function(){return this.isConnected},isOffline:function(){return!this.isConnected}}}),r.factory("$cordovaPush",["$q","$timeout","$rootScope",function(r,e,t){var o=!1,i="";return{throwsError:o,deviceToken:i,onNotification:function(r){e(function(){t.$broadcast("$cordovaPush:notificationReceived",r)})},register:function(e){var t=this,o=r.defer();return void 0!==e&&void 0===e.ecb&&(e.ecb=this.onNotification),this.throwsError?o.reject("There was a register error."):(o.resolve(this.deviceToken),e&&e.ecb&&e.ecb({event:"registered",regid:t.deviceToken})),o.promise},unregister:function(){var e=r.defer();return this.throwsError?e.reject("There was a register error."):e.resolve(),e.promise}}}]),r.factory("$cordovaSocialSharing",["$q",function(r){var e=!1,t="",o="",i="",n="",s="",a="",c=[],h=[],u=[];return{throwsError:e,message:t,image:o,link:i,number:n,subject:a,toAddresses:c,bccAddresses:h,socialService:s,attachments:u,shareViaTwitter:function(e,t,o){var i=r.defer();return this.throwsError?i.reject("There was an error sharing via Twitter."):(this.message=e,this.image=t,this.link=o,i.resolve()),i.promise},shareViaWhatsApp:function(e,t,o){var i=r.defer();return this.throwsError?i.reject("There was an error sharing via WhatsApp."):(this.message=e,this.image=t,this.link=o,i.resolve()),i.promise},shareViaFacebook:function(e,t,o){var i=r.defer();return this.throwsError?i.reject("There was an error sharing via Facebook."):(this.message=e,this.image=t,this.link=o,i.resolve()),i.promise},shareViaSMS:function(e,t){var o=r.defer();return this.throwsError?o.reject("There was an error sharing via SMS."):(this.message=e,this.number=t,o.resolve()),o.promise},shareViaEmail:function(e,t,o,i,n){var s=r.defer();return this.throwsError?s.reject("There was an error sharing via SMS."):(this.message=e,this.subject=t,this.toAddresses=o,this.bccAddressesc=i,this.attachments=n,s.resolve()),s.promise},canShareViaEmail:function(){var e=r.defer();return this.throwsError?e.reject(!1):e.resolve(!0),e.promise},canShareVia:function(e,t,o,i,n){var s=r.defer();return this.throwsError?s.reject("There was an error sharing via SMS."):(this.message=t,this.socialService=e,this.subject=o,this.attachments=i,this.link=n,s.resolve()),s.promise},shareVia:function(e,t,o,i,n){var s=r.defer();return this.throwsError?s.reject("There was an error sharing via SMS."):(this.socialService=e,this.message=t,this.subject=o,this.attachments=i,this.link=n,s.resolve()),s.promise},share:function(e,t,o,i){var n=r.defer();return this.throwsError?n.reject("There was an error sharing via SMS."):(this.message=e,this.subject=t,this.attachments=o,this.link=i,n.resolve()),n.promise}}}]),r.factory("$cordovaSplashscreen",function(){var r=!1;return{isVisible:r,hide:function(){return this.isVisible=!1,!0},show:function(){return this.isVisible=!0,!0}}}),r.factory("$cordovaStatusbar",function(){var r=!0,e=!0;return{isStatusBarVisible:r,canOverlayWebView:e,overlaysWebView:function(r){this.canOverlayWebView=r},style:function(r){return r},styleHex:function(r){return r},styleColor:function(r){return r},hide:function(){this.isStatusBarVisible=!1},show:function(){this.isStatusBarVisible=!0},isVisible:function(){return this.isStatusBarVisible}}}),r.factory("$cordovaToast",["$q",function(r){var e=!1;return{throwsError:e,showShortTop:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise},showShortCenter:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise},showShortBottom:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise},showLongTop:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise},showLongCenter:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise},showLongBottom:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise},show:function(){var e=r.defer();return this.throwsError?e.reject("There was an error showing the toast."):e.resolve(),e.promise}}}]),r.factory("$cordovaVibration",["$timeout",function(r){var e=!1,t=null;return{vibrateTimer:t,isVibrating:e,vibrate:function(e){e>0&&(this.isVibrating=!0,self=this,this.vibrateTimer=e instanceof Array?r(function(){self.isVibrating=!1,self.vibrateTimer=null},e[0]):r(function(){self.isVibrating=!1,self.vibrateTimer=null},e))},vibrateWithPattern:function(){},cancelVibration:function(){null!==this.vibrateTimer&&this.isVibrating===!0&&(r.cancel(this.vibrateTimer),this.isVibrating=!1)}}}])}();
diff --git a/www/lib/ngCordova/dist/ng-cordova.js b/www/lib/ngCordova/dist/ng-cordova.js
new file mode 100644
index 00000000..76f3fa6e
--- /dev/null
+++ b/www/lib/ngCordova/dist/ng-cordova.js
@@ -0,0 +1,6822 @@
+/*!
+ * ngCordova
+ * v0.1.15-alpha
+ * Copyright 2014 Drifty Co. http://drifty.com/
+ * See LICENSE in this repository for license information
+ */
+(function(){
+
+angular.module('ngCordova', [
+ 'ngCordova.plugins'
+]);
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-actionsheet.git
+// link : https://github.com/EddyVerbruggen/cordova-plugin-actionsheet
+
+angular.module('ngCordova.plugins.actionSheet', [])
+
+ .factory('$cordovaActionSheet', ['$q', '$window', function ($q, $window) {
+
+ return {
+ show: function (options) {
+ var q = $q.defer();
+
+ $window.plugins.actionsheet.show(options, function (result) {
+ q.resolve(result);
+ });
+
+ return q.promise;
+ },
+
+ hide: function () {
+ return $window.plugins.actionsheet.hide();
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-plugin-admob.git
+// link : https://github.com/floatinghotpot/cordova-plugin-admob
+
+angular.module('ngCordova.plugins.adMob', [])
+
+ .factory('$cordovaAdMob', ['$q', '$window', function ($q, $window) {
+
+ return {
+ createBannerView: function (options) {
+ var d = $q.defer();
+
+ $window.plugins.AdMob.createBannerView(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createInterstitialView: function (options) {
+ var d = $q.defer();
+
+ $window.plugins.AdMob.createInterstitialView(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ requestAd: function (options) {
+ var d = $q.defer();
+
+ $window.plugins.AdMob.requestAd(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showAd: function (options) {
+ var d = $q.defer();
+
+ $window.plugins.AdMob.showAd(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ requestInterstitialAd: function (options) {
+ var d = $q.defer();
+
+ $window.plugins.AdMob.requestInterstitialAd(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/ohh2ahh/AppAvailability.git
+// link : https://github.com/ohh2ahh/AppAvailability
+
+angular.module('ngCordova.plugins.appAvailability', [])
+
+ .factory('$cordovaAppAvailability', ['$q', function ($q) {
+
+ return {
+ check: function (urlScheme) {
+ var q = $q.defer();
+
+ appAvailability.check(urlScheme, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/pushandplay/cordova-plugin-apprate.git
+// link : https://github.com/pushandplay/cordova-plugin-apprate
+
+angular.module('ngCordova.plugins.appRate', [])
+
+ .provider("$cordovaAppRate", [function () {
+
+
+ this.setPreferences = function (defaults) {
+ if (!defaults || !angular.isObject(defaults)) {
+ return;
+ }
+
+ AppRate.preferences.useLanguage = defaults.language || null;
+ AppRate.preferences.displayAppName = defaults.appName || "";
+ AppRate.preferences.promptAgainForEachNewVersion = defaults.promptForNewVersion || true;
+ AppRate.preferences.openStoreInApp = defaults.openStoreInApp || false;
+ AppRate.preferences.usesUntilPrompt = defaults.usesUntilPrompt || 3;
+ AppRate.preferences.useCustomRateDialog = defaults.useCustomRateDialog || false;
+ AppRate.preferences.storeAppURL.ios = defaults.iosURL || null;
+ AppRate.preferences.storeAppURL.android = defaults.androidURL || null;
+ AppRate.preferences.storeAppURL.blackberry = defaults.blackberryURL || null;
+ AppRate.preferences.storeAppURL.windows8 = defaults.windowsURL || null;
+ };
+
+
+ this.setCustomLocale = function (customObj) {
+ var strings = {
+ title: 'Rate %@',
+ message: 'If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!',
+ cancelButtonLabel: 'No, Thanks',
+ laterButtonLabel: 'Remind Me Later',
+ rateButtonLabel: 'Rate It Now'
+ };
+
+ strings = angular.extend(strings, customObj);
+
+ AppRate.preferences.customLocale = strings;
+ };
+
+ this.$get = ['$q', function ($q) {
+ return {
+ promptForRating: function (immediate) {
+ var q = $q.defer();
+ var prompt = AppRate.promptForRating(immediate);
+ q.resolve(prompt);
+
+ return q.promise;
+ },
+
+ navigateToAppStore: function () {
+ var q = $q.defer();
+ var navigate = AppRate.navigateToAppStore();
+ q.resolve(navigate);
+
+ return q.promise;
+ },
+
+ onButtonClicked: function (cb) {
+ AppRate.onButtonClicked = function (buttonIndex) {
+ cb.call(this, buttonIndex);
+ };
+ },
+
+ onRateDialogShow: function (cb) {
+ AppRate.onRateDialogShow = cb();
+ }
+ };
+ }];
+ }]);
+
+// install : cordova plugin add https://github.com/whiteoctober/cordova-plugin-app-version.git
+// link : https://github.com/whiteoctober/cordova-plugin-app-version
+
+angular.module('ngCordova.plugins.appVersion', [])
+
+ .factory('$cordovaAppVersion', ['$q', function ($q) {
+
+ return {
+ getAppVersion: function () {
+ var q = $q.defer();
+ cordova.getAppVersion(function (version) {
+ q.resolve(version);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/christocracy/cordova-plugin-background-geolocation.git
+// link : https://github.com/christocracy/cordova-plugin-background-geolocation
+
+angular.module('ngCordova.plugins.backgroundGeolocation', [])
+
+ .factory('$cordovaBackgroundGeolocation', ['$q', '$window', function ($q, $window) {
+
+ return {
+
+ init: function () {
+ $window.navigator.geolocation.getCurrentPosition(function (location) {
+ return location;
+ });
+ },
+
+ configure: function (options) {
+
+ this.init();
+ var q = $q.defer();
+
+ $window.plugins.backgroundGeoLocation.configure(
+ function (result) {
+ q.notify(result);
+ $window.plugins.backgroundGeoLocation.finish();
+ },
+ function (err) {
+ q.reject(err);
+ }, options);
+
+ this.start();
+
+ return q.promise;
+ },
+
+ start: function () {
+ var q = $q.defer();
+
+ $window.plugins.backgroundGeoLocation.start(
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ stop: function () {
+ var q = $q.defer();
+
+ $window.plugins.backgroundGeoLocation.stop(
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }
+ ]);
+
+// install : cordova plugin add de.appplant.cordova.plugin.badge
+// link : https://github.com/katzer/cordova-plugin-badge
+
+angular.module('ngCordova.plugins.badge', [])
+
+ .factory('$cordovaBadge', ['$q', function ($q) {
+
+ return {
+ hasPermission: function () {
+ var q = $q.defer();
+ cordova.plugins.notification.badge.hasPermission(function (permission) {
+ if (permission) {
+ q.resolve(true);
+ }
+ else {
+ q.reject("You do not have permission");
+ }
+ });
+
+ return q.promise;
+ },
+
+ promptForPermission: function () {
+ return cordova.plugins.notification.badge.promptForPermission();
+ },
+
+ set: function (number) {
+ var q = $q.defer();
+
+ cordova.plugins.notification.badge.hasPermission(function (permission) {
+ if (permission) {
+ q.resolve(cordova.plugins.notification.badge.set(number));
+ }
+ else {
+ q.reject("You do not have permission to set Badge");
+ }
+ });
+ return q.promise;
+ },
+
+ get: function () {
+ var q = $q.defer();
+ cordova.plugins.notification.badge.hasPermission(function (permission) {
+ if (permission) {
+ cordova.plugins.notification.badge.get(function (badge) {
+ q.resolve(badge);
+ });
+ } else {
+ q.reject("You do not have permission to get Badge");
+ }
+ });
+
+ return q.promise;
+ },
+
+ clear: function () {
+ var q = $q.defer();
+
+ cordova.plugins.notification.badge.hasPermission(function (permission) {
+ if (permission) {
+ q.resolve(cordova.plugins.notification.badge.clear());
+ }
+ else {
+ q.reject("You do not have permission to clear Badge");
+ }
+ });
+ return q.promise;
+ },
+
+ configure: function (config) {
+ return cordova.plugins.notification.badge.configure(config);
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/wildabeast/BarcodeScanner.git
+// link : https://github.com/wildabeast/BarcodeScanner/#using-the-plugin
+
+angular.module('ngCordova.plugins.barcodeScanner', [])
+
+ .factory('$cordovaBarcodeScanner', ['$q', function ($q) {
+
+ return {
+ scan: function (config) {
+ var q = $q.defer();
+
+ cordova.plugins.barcodeScanner.scan(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ }, config);
+
+ return q.promise;
+ },
+
+ encode: function (type, data) {
+ var q = $q.defer();
+ type = type || "TEXT_TYPE";
+
+ cordova.plugins.barcodeScanner.encode(type, data, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.battery-status
+// link : https://github.com/apache/cordova-plugin-battery-status/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.batteryStatus', [])
+
+ .factory('$cordovaBatteryStatus', ['$rootScope', '$window', '$timeout', function ($rootScope, $window, $timeout) {
+
+ var batteryStatus = function (status) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaBatteryStatus:status', status);
+ });
+ };
+
+ var batteryCritical = function (status) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaBatteryStatus:critical', status);
+ });
+ };
+
+ var batteryLow = function (status) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaBatteryStatus:low', status);
+ });
+ };
+
+ document.addEventListener("deviceready", function () {
+ if (navigator.battery) {
+ $window.addEventListener('batterystatus', batteryStatus, false);
+ $window.addEventListener('batterycritical', batteryCritical, false);
+ $window.addEventListener('batterylow', batteryLow, false);
+
+ }
+ }, false);
+ return true;
+ }])
+ .run(['$cordovaBatteryStatus', function ($cordovaBatteryStatus) {
+ }]);
+
+// install : cordova plugin add https://github.com/don/cordova-plugin-ble-central#:/plugin
+// link : https://github.com/don/cordova-plugin-ble-central
+
+angular.module('ngCordova.plugins.ble', [])
+
+ .factory('$cordovaBLE', ['$q', function ($q) {
+
+ return {
+ scan: function (services, seconds) {
+ var q = $q.defer();
+ ble.scan(services, seconds, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ connect: function (deviceID) {
+ var q = $q.defer();
+ ble.connect(deviceID, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ disconnect: function (deviceID) {
+ var q = $q.defer();
+ ble.disconnect(deviceID, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ read: function (deviceID, serviceUUID, characteristicUUID) {
+ var q = $q.defer();
+ ble.read(deviceID, serviceUUID, characteristicUUID, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ write: function (deviceID, serviceUUID, characteristicUUID, data) {
+ var q = $q.defer();
+ ble.write(deviceID, serviceUUID, characteristicUUID, data, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ writeCommand: function (deviceID, serviceUUID, characteristicUUID, data) {
+ var q = $q.defer();
+ ble.writeCommand(deviceID, serviceUUID, characteristicUUID, data, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ notify: function (deviceID, serviceUUID, characteristicUUID) {
+ var q = $q.defer();
+ ble.notify(deviceID, serviceUUID, characteristicUUID, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ indicate: function (deviceID, serviceUUID, characteristicUUID) {
+ var q = $q.defer();
+ ble.indicate(deviceID, serviceUUID, characteristicUUID, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ isConnected: function (deviceID) {
+ var q = $q.defer();
+ ble.isConnected(deviceID, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ isEnabled: function () {
+ var q = $q.defer();
+ ble.isEnabled(function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add com.megster.cordova.bluetoothserial
+// link : https://github.com/don/BluetoothSerial
+
+angular.module('ngCordova.plugins.bluetoothSerial', [])
+
+ .factory('$cordovaBluetoothSerial', ['$q', '$window', function ($q, $window) {
+
+ return {
+ connect: function (address) {
+ var q = $q.defer();
+ $window.bluetoothSerial.connect(address, function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ // not supported on iOS
+ connectInsecure: function (address) {
+ var q = $q.defer();
+ $window.bluetoothSerial.connectInsecure(address, function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ disconnect: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.disconnect(function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ list: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.list(function (data) {
+ q.resolve(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ discoverUnpaired: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.discoverUnpaired(function (data) {
+ q.resolve(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ setDeviceDiscoveredListener: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.setDeviceDiscoveredListener(function (data) {
+ q.notify(data);
+ });
+ return q.promise;
+ },
+
+ clearDeviceDiscoveredListener: function() {
+ $window.bluetoothSerial.clearDeviceDiscoveredListener();
+ },
+
+
+ showBluetoothSettings: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.showBluetoothSettings(function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ isEnabled: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.isEnabled(function () {
+ q.resolve();
+ }, function () {
+ q.reject();
+ });
+ return q.promise;
+ },
+
+
+ enable: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.enable(function () {
+ q.resolve();
+ }, function () {
+ q.reject();
+ });
+ return q.promise;
+ },
+
+
+ isConnected: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.isConnected(function () {
+ q.resolve();
+ }, function () {
+ q.reject();
+ });
+ return q.promise;
+ },
+
+
+ available: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.available(function (data) {
+ q.resolve(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ read: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.read(function (data) {
+ q.resolve(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ readUntil: function (delimiter) {
+ var q = $q.defer();
+ $window.bluetoothSerial.readUntil(delimiter, function (data) {
+ q.resolve(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ write: function (data) {
+ var q = $q.defer();
+ $window.bluetoothSerial.write(data, function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ subscribe: function (delimiter) {
+ var q = $q.defer();
+ $window.bluetoothSerial.subscribe(delimiter, function (data) {
+ q.notify(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ subscribeRawData: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.subscribeRawData(function (data) {
+ q.notify(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ unsubscribe: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.unsubscribe(function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ unsubscribeRawData: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.unsubscribeRawData(function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ clear: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.clear(function () {
+ q.resolve();
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ readRSSI: function () {
+ var q = $q.defer();
+ $window.bluetoothSerial.readRSSI(function (data) {
+ q.resolve(data);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/fiscal-cliff/phonegap-plugin-brightness.git
+// link : https://github.com/fiscal-cliff/phonegap-plugin-brightness
+
+angular.module('ngCordova.plugins.brightness', [])
+
+ .factory('$cordovaBrightness', ['$q', '$window', function ($q, $window) {
+
+ return {
+ get: function () {
+ var q = $q.defer();
+
+ $window.cordova.plugins.brightness.getBrightness(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ set: function (data) {
+ var q = $q.defer();
+
+ $window.cordova.plugins.brightness.setBrightness(data, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ setKeepScreenOn: function (bool) {
+ var q = $q.defer();
+
+ $window.cordova.plugins.brightness.setKeepScreenOn(bool, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+
+
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin.git
+// link : https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin
+
+angular.module('ngCordova.plugins.calendar', [])
+
+ .factory('$cordovaCalendar', ['$q', '$window', function ($q, $window) {
+ return {
+ createCalendar: function (options) {
+ var d = $q.defer(),
+ createCalOptions = $window.plugins.calendar.getCreateCalendarOptions();
+
+ if (typeof options === 'string') {
+ createCalOptions.calendarName = options;
+ } else {
+ createCalOptions = angular.extend(createCalOptions, options);
+ }
+
+ $window.plugins.calendar.createCalendar(createCalOptions, function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ deleteCalendar: function (calendarName) {
+ var d = $q.defer();
+
+ $window.plugins.calendar.deleteCalendar(calendarName, function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ createEvent: function (options) {
+ var d = $q.defer(),
+ defaultOptions = {
+ title: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null
+ };
+
+ defaultOptions = angular.extend(defaultOptions, options);
+
+ $window.plugins.calendar.createEvent(
+ defaultOptions.title,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ },
+
+ createEventWithOptions: function (options) {
+ var d = $q.defer(),
+ defaultOptionKeys = [],
+ calOptions = window.plugins.calendar.getCalendarOptions(),
+ defaultOptions = {
+ title: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null
+ };
+
+ defaultOptionKeys = Object.keys(defaultOptions);
+
+ for (var key in options) {
+ if (defaultOptionKeys.indexOf(key) === -1) {
+ calOptions[key] = options[key];
+ } else {
+ defaultOptions[key] = options[key];
+ }
+ }
+
+ $window.plugins.calendar.createEventWithOptions(
+ defaultOptions.title,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ calOptions,
+ function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ },
+
+ createEventInteractively: function (options) {
+ var d = $q.defer(),
+ defaultOptions = {
+ title: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null
+ };
+
+ defaultOptions = angular.extend(defaultOptions, options);
+
+ $window.plugins.calendar.createEventInteractively(
+ defaultOptions.title,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ },
+
+ createEventInNamedCalendar: function (options) {
+ var d = $q.defer(),
+ defaultOptions = {
+ title: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null,
+ calendarName: null
+ };
+
+ defaultOptions = angular.extend(defaultOptions, options);
+
+ $window.plugins.calendar.createEventInNamedCalendar(
+ defaultOptions.title,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ defaultOptions.calendarName,
+ function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ },
+
+ findEvent: function (options) {
+ var d = $q.defer(),
+ defaultOptions = {
+ title: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null
+ };
+
+ defaultOptions = angular.extend(defaultOptions, options);
+
+ $window.plugins.calendar.findEvent(
+ defaultOptions.title,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ function (foundEvent) {
+ d.resolve(foundEvent);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ },
+
+ listEventsInRange: function (startDate, endDate) {
+ var d = $q.defer();
+
+ $window.plugins.calendar.listEventsInRange(startDate, endDate, function (events) {
+ d.resolve(events);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ listCalendars: function () {
+ var d = $q.defer();
+
+ $window.plugins.calendar.listCalendars(function (calendars) {
+ d.resolve(calendars);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ findAllEventsInNamedCalendar: function (calendarName) {
+ var d = $q.defer();
+
+ $window.plugins.calendar.findAllEventsInNamedCalendar(calendarName, function (events) {
+ d.resolve(events);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ modifyEvent: function (options) {
+ var d = $q.defer(),
+ defaultOptions = {
+ title: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null,
+ newTitle: null,
+ newLocation: null,
+ newNotes: null,
+ newStartDate: null,
+ newEndDate: null
+ };
+
+ defaultOptions = angular.extend(defaultOptions, options);
+
+ $window.plugins.calendar.modifyEvent(
+ defaultOptions.title,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ defaultOptions.newTitle,
+ defaultOptions.newLocation,
+ defaultOptions.newNotes,
+ new Date(defaultOptions.newStartDate),
+ new Date(defaultOptions.newEndDate),
+ function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ },
+
+ deleteEvent: function (options) {
+ var d = $q.defer(),
+ defaultOptions = {
+ newTitle: null,
+ location: null,
+ notes: null,
+ startDate: null,
+ endDate: null
+ };
+
+ defaultOptions = angular.extend(defaultOptions, options);
+
+ $window.plugins.calendar.deleteEvent(
+ defaultOptions.newTitle,
+ defaultOptions.location,
+ defaultOptions.notes,
+ new Date(defaultOptions.startDate),
+ new Date(defaultOptions.endDate),
+ function (message) {
+ d.resolve(message);
+ }, function (error) {
+ d.reject(error);
+ }
+ );
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.camera
+// link : https://github.com/apache/cordova-plugin-camera/blob/master/doc/index.md#orgapachecordovacamera
+
+angular.module('ngCordova.plugins.camera', [])
+
+ .factory('$cordovaCamera', ['$q', function ($q) {
+
+ return {
+ getPicture: function (options) {
+ var q = $q.defer();
+
+ if (!navigator.camera) {
+ q.resolve(null);
+ return q.promise;
+ }
+
+ navigator.camera.getPicture(function (imageData) {
+ q.resolve(imageData);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ return q.promise;
+ },
+
+ cleanup: function () {
+ var q = $q.defer();
+
+ navigator.camera.cleanup(function () {
+ q.resolve();
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.media-capture
+// link : https://github.com/apache/cordova-plugin-media-capture/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.capture', [])
+
+ .factory('$cordovaCapture', ['$q', function ($q) {
+
+ return {
+ captureAudio: function (options) {
+ var q = $q.defer();
+
+ if (!navigator.device.capture) {
+ q.resolve(null);
+ return q.promise;
+ }
+
+ navigator.device.capture.captureAudio(function (audioData) {
+ q.resolve(audioData);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ return q.promise;
+ },
+ captureImage: function (options) {
+ var q = $q.defer();
+
+ if (!navigator.device.capture) {
+ q.resolve(null);
+ return q.promise;
+ }
+
+ navigator.device.capture.captureImage(function (imageData) {
+ q.resolve(imageData);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ return q.promise;
+ },
+ captureVideo: function (options) {
+ var q = $q.defer();
+
+ if (!navigator.device.capture) {
+ q.resolve(null);
+ return q.promise;
+ }
+
+ navigator.device.capture.captureVideo(function (videoData) {
+ q.resolve(videoData);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/VersoSolutions/CordovaClipboard
+// link : https://github.com/VersoSolutions/CordovaClipboard
+
+angular.module('ngCordova.plugins.clipboard', [])
+
+ .factory('$cordovaClipboard', ['$q', '$window', function ($q, $window) {
+
+ return {
+ copy: function (text) {
+ var q = $q.defer();
+
+ $window.cordova.plugins.clipboard.copy(text,
+ function () {
+ q.resolve();
+ }, function () {
+ q.reject();
+ });
+
+ return q.promise;
+ },
+
+ paste: function () {
+ var q = $q.defer();
+
+ $window.cordova.plugins.clipboard.paste(function (text) {
+ q.resolve(text);
+ }, function () {
+ q.reject();
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.contacts
+// link : https://github.com/apache/cordova-plugin-contacts/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.contacts', [])
+
+ .factory('$cordovaContacts', ['$q', function ($q) {
+
+ return {
+ save: function (contact) {
+ var q = $q.defer();
+ var deviceContact = navigator.contacts.create(contact);
+
+ deviceContact.save(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ remove: function (contact) {
+ var q = $q.defer();
+ var deviceContact = navigator.contacts.create(contact);
+
+ deviceContact.remove(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ clone: function (contact) {
+ var deviceContact = navigator.contacts.create(contact);
+ return deviceContact.clone(contact);
+ },
+
+ find: function (options) {
+ var q = $q.defer();
+ var fields = options.fields || ['id', 'displayName'];
+ delete options.fields;
+
+ navigator.contacts.find(fields, function (results) {
+ q.resolve(results);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ return q.promise;
+ },
+
+ pickContact: function () {
+ var q = $q.defer();
+
+ navigator.contacts.pickContact(function (contact) {
+ q.resolve(contact);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+
+ // TODO: method to set / get ContactAddress
+ // TODO: method to set / get ContactError
+ // TODO: method to set / get ContactField
+ // TODO: method to set / get ContactName
+ // TODO: method to set / get ContactOrganization
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/VitaliiBlagodir/cordova-plugin-datepicker.git
+// link : https://github.com/VitaliiBlagodir/cordova-plugin-datepicker
+
+angular.module('ngCordova.plugins.datePicker', [])
+ .factory('$cordovaDatePicker', ['$window', '$q', function ($window, $q) {
+ return {
+ show: function (options) {
+ var q = $q.defer();
+ options = options || {date: new Date(), mode: 'date'};
+ $window.datePicker.show(options, function (date) {
+ q.resolve(date);
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.device
+// link : https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.device', [])
+
+ .factory('$cordovaDevice', [function () {
+
+ return {
+ /**
+ * Returns the whole device object.
+ * @see https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md
+ * @returns {Object} The device object.
+ */
+ getDevice: function () {
+ return device;
+ },
+
+ /**
+ * Returns the Cordova version.
+ * @see https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md#devicecordova
+ * @returns {String} The Cordova version.
+ */
+ getCordova: function () {
+ return device.cordova;
+ },
+
+ /**
+ * Returns the name of the device's model or product.
+ * @see https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md#devicemodel
+ * @returns {String} The name of the device's model or product.
+ */
+ getModel: function () {
+ return device.model;
+ },
+
+ /**
+ * @deprecated device.name is deprecated as of version 2.3.0. Use device.model instead.
+ * @returns {String}
+ */
+ getName: function () {
+ return device.name;
+ },
+
+ /**
+ * Returns the device's operating system name.
+ * @see https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md#deviceplatform
+ * @returns {String} The device's operating system name.
+ */
+ getPlatform: function () {
+ return device.platform;
+ },
+
+ /**
+ * Returns the device's Universally Unique Identifier.
+ * @see https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md#deviceuuid
+ * @returns {String} The device's Universally Unique Identifier
+ */
+ getUUID: function () {
+ return device.uuid;
+ },
+
+ /**
+ * Returns the operating system version.
+ * @see https://github.com/apache/cordova-plugin-device/blob/master/doc/index.md#deviceversion
+ * @returns {String}
+ */
+ getVersion: function () {
+ return device.version;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.device-motion
+// link : https://github.com/apache/cordova-plugin-device-motion/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.deviceMotion', [])
+
+ .factory('$cordovaDeviceMotion', ['$q', function ($q) {
+
+ return {
+ getCurrentAcceleration: function () {
+ var q = $q.defer();
+
+ navigator.accelerometer.getCurrentAcceleration(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ watchAcceleration: function (options) {
+ var q = $q.defer();
+
+ var watchID = navigator.accelerometer.watchAcceleration(function (result) {
+ q.notify(result);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ q.promise.cancel = function () {
+ navigator.accelerometer.clearWatch(watchID);
+ };
+
+ q.promise.clearWatch = function (id) {
+ navigator.accelerometer.clearWatch(id || watchID);
+ };
+
+ q.promise.watchID = watchID;
+
+ return q.promise;
+ },
+
+ clearWatch: function (watchID) {
+ return navigator.accelerometer.clearWatch(watchID);
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.device-orientation
+// link : https://github.com/apache/cordova-plugin-device-orientation/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.deviceOrientation', [])
+
+ .factory('$cordovaDeviceOrientation', ['$q', function ($q) {
+
+ return {
+ getCurrentHeading: function () {
+ var q = $q.defer();
+
+ navigator.compass.getCurrentHeading(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ watchHeading: function (options) {
+ var q = $q.defer();
+
+ var watchID = navigator.compass.watchHeading(function (result) {
+ q.notify(result);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ q.promise.cancel = function () {
+ navigator.compass.clearWatch(watchID);
+ };
+
+ q.promise.clearWatch = function (id) {
+ navigator.compass.clearWatch(id || watchID);
+ };
+
+ q.promise.watchID = watchID;
+
+ return q.promise;
+ },
+
+ clearWatch: function (watchID) {
+ return navigator.compass.clearWatch(watchID);
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.dialogs
+// link : https://github.com/apache/cordova-plugin-dialogs/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.dialogs', [])
+
+ .factory('$cordovaDialogs', ['$q', '$window', function ($q, $window) {
+
+ return {
+ alert: function (message, title, buttonName) {
+ var q = $q.defer();
+
+ if (!$window.navigator.notification) {
+ $window.alert(message);
+ q.resolve();
+ }
+ else {
+ navigator.notification.alert(message, function () {
+ q.resolve();
+ }, title, buttonName);
+ }
+
+ return q.promise;
+ },
+
+ confirm: function (message, title, buttonLabels) {
+ var q = $q.defer();
+
+ if (!$window.navigator.notification) {
+ if ($window.confirm(message)) {
+ q.resolve(1);
+ }
+ else {
+ q.resolve(2);
+ }
+ }
+ else {
+ navigator.notification.confirm(message, function (buttonIndex) {
+ q.resolve(buttonIndex);
+ }, title, buttonLabels);
+ }
+
+ return q.promise;
+ },
+
+ prompt: function (message, title, buttonLabels, defaultText) {
+ var q = $q.defer();
+
+ if (!$window.navigator.notification) {
+ var res = $window.prompt(message, defaultText);
+ if (res !== null) {
+ q.resolve({input1: res, buttonIndex: 1});
+ }
+ else {
+ q.resolve({input1: res, buttonIndex: 2});
+ }
+ }
+ else {
+ navigator.notification.prompt(message, function (result) {
+ q.resolve(result);
+ }, title, buttonLabels, defaultText);
+ }
+ return q.promise;
+ },
+
+ beep: function (times) {
+ return navigator.notification.beep(times);
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/katzer/cordova-plugin-email-composer.git@0.8.2
+// link : https://github.com/katzer/cordova-plugin-email-composer
+
+angular.module('ngCordova.plugins.emailComposer', [])
+
+ .factory('$cordovaEmailComposer', ['$q', function ($q) {
+
+ return {
+ isAvailable: function () {
+ var q = $q.defer();
+
+ cordova.plugins.email.isAvailable(function (isAvailable) {
+ isAvailable ? q.resolve() : q.reject();
+ });
+
+ return q.promise;
+ },
+
+ open: function (properties) {
+ var q = $q.defer();
+
+ cordova.plugins.email.open(properties, function () {
+ q.reject(); // user closed email composer
+ });
+
+ return q.promise;
+ },
+
+ addAlias: function (app, schema) {
+ cordova.plugins.email.addAlias(app, schema);
+ }
+ };
+ }]);
+
+// install : cordova -d plugin add /Users/your/path/here/phonegap-facebook-plugin --variable APP_ID="123456789" --variable APP_NAME="myApplication"
+// link : https://github.com/Wizcorp/phonegap-facebook-plugin
+
+angular.module('ngCordova.plugins.facebook', [])
+
+ .provider('$cordovaFacebook', [function () {
+
+ this.browserInit = function (id, version) {
+ this.appID = id;
+ this.appVersion = version || "v2.0";
+ facebookConnectPlugin.browserInit(this.appID, this.appVersion);
+ };
+
+ this.$get = ['$q', function ($q) {
+ return {
+ login: function (permissions) {
+ var q = $q.defer();
+ facebookConnectPlugin.login(permissions, function (res) {
+ q.resolve(res);
+ }, function (res) {
+ q.reject(res);
+ });
+
+ return q.promise;
+ },
+
+ showDialog: function (options) {
+ var q = $q.defer();
+ facebookConnectPlugin.showDialog(options, function (res) {
+ q.resolve(res);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ api: function (path, permissions) {
+ var q = $q.defer();
+ facebookConnectPlugin.api(path, permissions, function (res) {
+ q.resolve(res);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ getAccessToken: function () {
+ var q = $q.defer();
+ facebookConnectPlugin.getAccessToken(function (res) {
+ q.resolve(res);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ getLoginStatus: function () {
+ var q = $q.defer();
+ facebookConnectPlugin.getLoginStatus(function (res) {
+ q.resolve(res);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ logout: function () {
+ var q = $q.defer();
+ facebookConnectPlugin.logout(function (res) {
+ q.resolve(res);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ }
+ };
+ }];
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-plugin-facebookads.git
+// link : https://github.com/floatinghotpot/cordova-plugin-facebookads
+
+angular.module('ngCordova.plugins.facebookAds', [])
+ .factory('$cordovaFacebookAds', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.FacebookAds.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.FacebookAds.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.FacebookAds.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.FacebookAds.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.FacebookAds.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.FacebookAds.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.FacebookAds.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.FacebookAds.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.file
+// link : https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.file', [])
+
+ .constant("$cordovaFileError", {
+ 1: 'NOT_FOUND_ERR',
+ 2: 'SECURITY_ERR',
+ 3: 'ABORT_ERR',
+ 4: 'NOT_READABLE_ERR',
+ 5: 'ENCODING_ERR',
+ 6: 'NO_MODIFICATION_ALLOWED_ERR',
+ 7: 'INVALID_STATE_ERR',
+ 8: 'SYNTAX_ERR',
+ 9: 'INVALID_MODIFICATION_ERR',
+ 10: 'QUOTA_EXCEEDED_ERR',
+ 11: 'TYPE_MISMATCH_ERR',
+ 12: 'PATH_EXISTS_ERR'
+ })
+
+ .provider('$cordovaFile', [function () {
+
+ this.$get = ['$q', '$window', '$cordovaFileError', function ($q, $window, $cordovaFileError) {
+
+ return {
+
+ getFreeDiskSpace: function() {
+ var q = $q.defer();
+ cordova.exec(function(result) {
+ q.resolve(result);
+ }, function(error) {
+ q.reject(error);
+ }, "File", "getFreeDiskSpace", []);
+ return q.promise;
+ },
+
+ checkDir: function (path, dir) {
+ var q = $q.defer();
+
+ if ((/^\//.test(dir))) {
+ q.reject("directory cannot start with \/")
+ }
+
+ try {
+ var directory = path + dir;
+ $window.resolveLocalFileSystemURL(directory, function (fileSystem) {
+ if (fileSystem.isDirectory === true) {
+ q.resolve(fileSystem);
+ } else {
+ q.reject({code: 13, message: "input is not a directory"});
+ }
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ } catch (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ }
+
+ return q.promise;
+ },
+
+
+ checkFile: function (path, file) {
+ var q = $q.defer();
+
+ if ((/^\//.test(file))) {
+ q.reject("directory cannot start with \/")
+ }
+
+ try {
+ var directory = path + file;
+ $window.resolveLocalFileSystemURL(directory, function (fileSystem) {
+ if (fileSystem.isFile === true) {
+ q.resolve(fileSystem);
+ } else {
+ q.reject({code: 13, message: "input is not a file"});
+ }
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ } catch (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ }
+
+ return q.promise;
+ },
+
+ createDir: function (path, dirName, replaceBool) {
+ var q = $q.defer();
+
+ if ((/^\//.test(dirName))) {
+ q.reject("directory cannot start with \/")
+ }
+
+ replaceBool = replaceBool ? false : true;
+
+ var options = {
+ create: true,
+ exclusive: replaceBool
+ };
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getDirectory(dirName, options, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+ createFile: function (path, fileName, replaceBool) {
+ var q = $q.defer();
+
+ if ((/^\//.test(fileName))) {
+ q.reject("file-name cannot start with \/")
+ }
+
+ replaceBool = replaceBool ? false : true;
+
+ var options = {
+ create: true,
+ exclusive: replaceBool
+ };
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(fileName, options, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+
+ removeDir: function (path, dirName) {
+ var q = $q.defer();
+
+ if ((/^\//.test(dirName))) {
+ q.reject("file-name cannot start with \/")
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getDirectory(dirName, {create: false}, function (dirEntry) {
+ dirEntry.remove(function () {
+ q.resolve({success: true, fileRemoved: dirEntry});
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ }, function (er) {
+ er.message = $cordovaFileError[er.code];
+ q.reject(er);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+ removeFile: function (path, fileName) {
+ var q = $q.defer();
+
+ if ((/^\//.test(fileName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(fileName, {create: false}, function (fileEntry) {
+ fileEntry.remove(function () {
+ q.resolve({success: true, fileRemoved: fileEntry});
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ }, function (er) {
+ er.message = $cordovaFileError[er.code];
+ q.reject(er);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+ removeRecursively: function (path, dirName) {
+ var q = $q.defer();
+
+ if ((/^\//.test(dirName))) {
+ q.reject("file-name cannot start with \/")
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getDirectory(dirName, {create: false}, function (dirEntry) {
+ dirEntry.removeRecursively(function () {
+ q.resolve({success: true, fileRemoved: dirEntry});
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ }, function (er) {
+ er.message = $cordovaFileError[er.code];
+ q.reject(er);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+ writeFile: function (path, fileName, text, replaceBool) {
+ var q = $q.defer();
+
+ if ((/^\//.test(fileName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ replaceBool = replaceBool ? false : true;
+
+ var options = {
+ create: true,
+ exclusive: replaceBool
+ };
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(fileName, options, function (fileEntry) {
+ fileEntry.createWriter(function (writer) {
+ if (options.append === true) {
+ writer.seek(writer.length);
+ }
+
+ if (options.truncate) {
+ writer.truncate(options.truncate);
+ }
+
+ writer.onwriteend = function (evt) {
+ if (this.error) {
+ q.reject(this.error);
+ }
+ else {
+ q.resolve(evt);
+ }
+ };
+
+ writer.write(text);
+
+ q.promise.abort = function () {
+ writer.abort();
+ };
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+
+ writeExistingFile: function (path, fileName, text) {
+ var q = $q.defer();
+
+ if ((/^\//.test(fileName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(fileName, {create: false}, function (fileEntry) {
+ fileEntry.createWriter(function (writer) {
+ writer.seek(writer.length);
+
+ writer.onwriteend = function (evt) {
+ if (this.error) {
+ q.reject(this.error);
+ }
+ else {
+ q.resolve(evt);
+ }
+ };
+
+ writer.write(text);
+
+ q.promise.abort = function () {
+ writer.abort();
+ };
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+
+ readAsText: function (path, file) {
+ var q = $q.defer();
+
+ if ((/^\//.test(file))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(file, {create: false}, function (fileEntry) {
+ fileEntry.file(function (fileData) {
+ var reader = new FileReader();
+
+ reader.onloadend = function (evt) {
+ if (evt.target._result !== undefined || evt.target._result !== null) {
+ q.resolve(evt.target._result);
+ }
+ else if (evt.target._error !== undefined || evt.target._error !== null) {
+ q.reject(evt.target._error);
+ }
+ else {
+ q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
+ }
+ };
+
+ reader.readAsText(fileData);
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+
+ readAsDataURL: function (path, file) {
+ var q = $q.defer();
+
+ if ((/^\//.test(file))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(file, {create: false}, function (fileEntry) {
+ fileEntry.file(function (fileData) {
+ var reader = new FileReader();
+ reader.onloadend = function (evt) {
+ if (evt.target._result !== undefined || evt.target._result !== null) {
+ q.resolve(evt.target._result);
+ }
+ else if (evt.target._error !== undefined || evt.target._error !== null) {
+ q.reject(evt.target._error);
+ }
+ else {
+ q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
+ }
+ };
+ reader.readAsDataURL(fileData);
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+ readAsBinaryString: function (path, file) {
+ var q = $q.defer();
+
+ if ((/^\//.test(file))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(file, {create: false}, function (fileEntry) {
+ fileEntry.file(function (fileData) {
+ var reader = new FileReader();
+ reader.onloadend = function (evt) {
+ if (evt.target._result !== undefined || evt.target._result !== null) {
+ q.resolve(evt.target._result);
+ }
+ else if (evt.target._error !== undefined || evt.target._error !== null) {
+ q.reject(evt.target._error);
+ }
+ else {
+ q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
+ }
+ };
+ reader.readAsBinaryString(fileData);
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+ readAsArrayBuffer: function (path, file) {
+ var q = $q.defer();
+
+ if ((/^\//.test(file))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(file, {create: false}, function (fileEntry) {
+ fileEntry.file(function (fileData) {
+ var reader = new FileReader();
+ reader.onloadend = function (evt) {
+ if (evt.target._result !== undefined || evt.target._result !== null) {
+ q.resolve(evt.target._result);
+ }
+ else if (evt.target._error !== undefined || evt.target._error !== null) {
+ q.reject(evt.target._error);
+ }
+ else {
+ q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
+ }
+ };
+ reader.readAsArrayBuffer(fileData);
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+
+ moveFile: function (path, fileName, newPath, newFileName) {
+ var q = $q.defer();
+
+ newFileName = newFileName || fileName;
+
+ if ((/^\//.test(fileName)) || (/^\//.test(newFileName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(fileName, {create: false}, function (fileEntry) {
+ $window.resolveLocalFileSystemURL(newPath, function (newFileEntry) {
+ fileEntry.moveTo(newFileEntry, newFileName, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ }, function (err) {
+ q.reject(err);
+ });
+ }, function (err) {
+ q.reject(err);
+ });
+ }, function (er) {
+ q.reject(er);
+ });
+ } catch (e) {
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+ moveDir: function (path, dirName, newPath, newDirName) {
+ var q = $q.defer();
+
+ newDirName = newDirName || dirName;
+
+ if (/^\//.test(dirName) || (/^\//.test(newDirName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getDirectory(dirName, {create: false}, function (dirEntry) {
+ $window.resolveLocalFileSystemURL(newPath, function (newDirEntry) {
+ dirEntry.moveTo(newDirEntry, newDirName, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ });
+ }, function (erro) {
+ q.reject(erro);
+ });
+ }, function (err) {
+ q.reject(err);
+ });
+ }, function (er) {
+ q.reject(er);
+ });
+ } catch (e) {
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+
+ copyDir: function (path, dirName, newPath, newDirName) {
+ var q = $q.defer();
+
+ newDirName = newDirName || dirName;
+
+ if (/^\//.test(dirName) || (/^\//.test(newDirName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getDirectory(dirName, {create: false, exclusive: false}, function (dirEntry) {
+
+ $window.resolveLocalFileSystemURL(newPath, function (newDirEntry) {
+ dirEntry.copyTo(newDirEntry, newDirName, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (erro) {
+ erro.message = $cordovaFileError[erro.code];
+ q.reject(erro);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ }, function (er) {
+ er.message = $cordovaFileError[er.code];
+ q.reject(er);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+ return q.promise;
+ },
+
+ copyFile: function (path, fileName, newPath, newFileName) {
+ var q = $q.defer();
+
+ newFileName = newFileName || fileName;
+
+ if ((/^\//.test(fileName))) {
+ q.reject("file-name cannot start with \/");
+ }
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getFile(fileName, {create: false, exclusive: false}, function (fileEntry) {
+
+ $window.resolveLocalFileSystemURL(newPath, function (newFileEntry) {
+ fileEntry.copyTo(newFileEntry, newFileName, function (result) {
+ q.resolve(result);
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (erro) {
+ erro.message = $cordovaFileError[erro.code];
+ q.reject(erro);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ }, function (er) {
+ er.message = $cordovaFileError[er.code];
+ q.reject(er);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+ return q.promise;
+ }
+
+ /*
+ listFiles: function (path, dir) {
+
+ },
+
+ listDir: function (path, dirName) {
+ var q = $q.defer();
+
+ try {
+ $window.resolveLocalFileSystemURL(path, function (fileSystem) {
+ fileSystem.getDirectory(dirName, options, function (parent) {
+ var reader = parent.createReader();
+ reader.readEntries(function (entries) {
+ q.resolve(entries);
+ }, function () {
+ q.reject('DIR_READ_ERROR : ' + path + dirName);
+ });
+ }, function (error) {
+ error.message = $cordovaFileError[error.code];
+ q.reject(error);
+ });
+ }, function (err) {
+ err.message = $cordovaFileError[err.code];
+ q.reject(err);
+ });
+ } catch (e) {
+ e.message = $cordovaFileError[e.code];
+ q.reject(e);
+ }
+
+ return q.promise;
+ },
+
+ readFileMetadata: function (filePath) {
+ //return getFile(filePath, {create: false});
+ }
+ */
+ };
+
+ }];
+ }]);
+
+// install : cordova plugin add https://github.com/pwlin/cordova-plugin-file-opener2
+// link : https://github.com/pwlin/cordova-plugin-file-opener2
+
+angular.module('ngCordova.plugins.fileOpener2', [])
+
+ .factory('$cordovaFileOpener2', ['$q', function ($q) {
+
+ return {
+ open: function (file, type) {
+ var q = $q.defer();
+ cordova.plugins.fileOpener2.open(file, type, {
+ error: function (e) {
+ q.reject(e);
+ }, success: function () {
+ q.resolve();
+ }
+ });
+ return q.promise;
+ },
+
+ uninstall: function (pack) {
+ var q = $q.defer();
+ cordova.plugins.fileOpener2.uninstall(pack, {
+ error: function (e) {
+ q.reject(e);
+ }, success: function () {
+ q.resolve();
+ }
+ });
+ return q.promise;
+ },
+
+ appIsInstalled: function (pack) {
+ var q = $q.defer();
+ cordova.plugins.fileOpener2.appIsInstalled(pack, {
+ success: function (res) {
+ q.resolve(res);
+ }
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.file-transfer
+// link : https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.fileTransfer', [])
+
+ .factory('$cordovaFileTransfer', ['$q', '$timeout', function ($q, $timeout) {
+ return {
+ download: function (source, filePath, options, trustAllHosts) {
+ var q = $q.defer();
+ var ft = new FileTransfer();
+ var uri = (options && options.encodeURI === false) ? source : encodeURI(source);
+
+ if (options && options.timeout !== undefined && options.timeout !== null) {
+ $timeout(function () {
+ ft.abort();
+ }, options.timeout);
+ options.timeout = null;
+ }
+
+ ft.onprogress = function (progress) {
+ q.notify(progress);
+ };
+
+ q.promise.abort = function () {
+ ft.abort();
+ };
+
+ ft.download(uri, filePath, q.resolve, q.reject, trustAllHosts, options);
+ return q.promise;
+ },
+
+ upload: function (server, filePath, options, trustAllHosts) {
+ var q = $q.defer();
+ var ft = new FileTransfer();
+ var uri = (options && options.encodeURI === false) ? server : encodeURI(server);
+
+ if (options && options.timeout !== undefined && options.timeout !== null) {
+ $timeout(function () {
+ ft.abort();
+ }, options.timeout);
+ options.timeout = null;
+ }
+
+ ft.onprogress = function (progress) {
+ q.notify(progress);
+ };
+
+ q.promise.abort = function () {
+ ft.abort();
+ };
+
+ ft.upload(filePath, uri, q.resolve, q.reject, options, trustAllHosts);
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin.git
+// link : https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin
+
+angular.module('ngCordova.plugins.flashlight', [])
+
+ .factory('$cordovaFlashlight', ['$q', '$window', function ($q, $window) {
+
+ return {
+ available: function () {
+ var q = $q.defer();
+ $window.plugins.flashlight.available(function (isAvailable) {
+ q.resolve(isAvailable);
+ });
+ return q.promise;
+ },
+
+ switchOn: function () {
+ var q = $q.defer();
+ $window.plugins.flashlight.switchOn(function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ switchOff: function () {
+ var q = $q.defer();
+ $window.plugins.flashlight.switchOff(function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ toggle: function () {
+ var q = $q.defer();
+ $window.plugins.flashlight.toggle(function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-plugin-flurry.git
+// link : https://github.com/floatinghotpot/cordova-plugin-flurry
+
+angular.module('ngCordova.plugins.flurryAds', [])
+ .factory('$cordovaFlurryAds', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.FlurryAds.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.FlurryAds.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.FlurryAds.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.FlurryAds.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.FlurryAds.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.FlurryAds.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.FlurryAds.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.FlurryAds.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/phonegap-build/GAPlugin.git
+// link : https://github.com/phonegap-build/GAPlugin
+
+angular.module('ngCordova.plugins.ga', [])
+
+ .factory('$cordovaGA', ['$q', '$window', function ($q, $window) {
+
+ return {
+ init: function (id, mingap) {
+ var q = $q.defer();
+ mingap = (mingap >= 0) ? mingap : 10;
+ $window.plugins.gaPlugin.init(function (result) {
+ q.resolve(result);
+ },
+ function (error) {
+ q.reject(error);
+ },
+ id, mingap);
+ return q.promise;
+ },
+
+ trackEvent: function (success, fail, category, eventAction, eventLabel, eventValue) {
+ var q = $q.defer();
+ $window.plugins.gaPlugin.trackEvent(function (result) {
+ q.resolve(result);
+ },
+ function (error) {
+ q.reject(error);
+ },
+ category, eventAction, eventLabel, eventValue);
+ return q.promise;
+ },
+
+ trackPage: function (success, fail, pageURL) {
+ var q = $q.defer();
+ $window.plugins.gaPlugin.trackPage(function (result) {
+ q.resolve(result);
+ },
+ function (error) {
+ q.reject(error);
+ },
+ pageURL);
+ return q.promise;
+ },
+
+ setVariable: function (success, fail, index, value) {
+ var q = $q.defer();
+ $window.plugins.gaPlugin.setVariable(function (result) {
+ q.resolve(result);
+ },
+ function (error) {
+ q.reject(error);
+ },
+ index, value);
+ return q.promise;
+ },
+
+ exit: function (success, fail) {
+ var q = $q.defer();
+ $window.plugins.gaPlugin.exit(function (result) {
+ q.resolve(result);
+ },
+ function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.geolocation
+// link : https://github.com/apache/cordova-plugin-geolocation/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.geolocation', [])
+
+ .factory('$cordovaGeolocation', ['$q', function ($q) {
+
+ return {
+ getCurrentPosition: function (options) {
+ var q = $q.defer();
+
+ navigator.geolocation.getCurrentPosition(function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ return q.promise;
+ },
+
+ watchPosition: function (options) {
+ var q = $q.defer();
+
+ var watchID = navigator.geolocation.watchPosition(function (result) {
+ q.notify(result);
+ }, function (err) {
+ q.reject(err);
+ }, options);
+
+ q.promise.cancel = function () {
+ navigator.geolocation.clearWatch(watchID);
+ };
+
+ q.promise.clearWatch = function (id) {
+ navigator.geolocation.clearWatch(id || watchID);
+ };
+
+ q.promise.watchID = watchID;
+
+ return q.promise;
+ },
+
+ clearWatch: function (watchID) {
+ return navigator.geolocation.clearWatch(watchID);
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.globalization
+// link : https://github.com/apache/cordova-plugin-globalization/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.globalization', [])
+
+ .factory('$cordovaGlobalization', ['$q', function ($q) {
+
+ return {
+ getPreferredLanguage: function () {
+ var q = $q.defer();
+
+ navigator.globalization.getPreferredLanguage(function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ getLocaleName: function () {
+ var q = $q.defer();
+
+ navigator.globalization.getLocaleName(function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ getFirstDayOfWeek: function () {
+ var q = $q.defer();
+
+ navigator.globalization.getFirstDayOfWeek(function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ // "date" parameter must be a JavaScript Date Object.
+ dateToString: function (date, options) {
+ var q = $q.defer();
+
+ navigator.globalization.dateToString(
+ date,
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ stringToDate: function (dateString, options) {
+ var q = $q.defer();
+
+ navigator.globalization.stringToDate(
+ dateString,
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ getDatePattern: function (options) {
+ var q = $q.defer();
+
+ navigator.globalization.getDatePattern(
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ getDateNames: function (options) {
+ var q = $q.defer();
+
+ navigator.globalization.getDateNames(
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ // "date" parameter must be a JavaScript Date Object.
+ isDayLightSavingsTime: function (date) {
+ var q = $q.defer();
+
+ navigator.globalization.isDayLightSavingsTime(
+ date,
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ numberToString: function (number, options) {
+ var q = $q.defer();
+
+ navigator.globalization.numberToString(
+ number,
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ stringToNumber: function (numberString, options) {
+ var q = $q.defer();
+
+ navigator.globalization.stringToNumber(
+ numberString,
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ getNumberPattern: function (options) {
+ var q = $q.defer();
+
+ navigator.globalization.getNumberPattern(
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ },
+ options);
+ return q.promise;
+ },
+
+ getCurrencyPattern: function (currencyCode) {
+ var q = $q.defer();
+
+ navigator.globalization.getCurrencyPattern(
+ currencyCode,
+ function (result) {
+ q.resolve(result);
+ },
+ function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ }
+
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-admob-pro.git
+// link : https://github.com/floatinghotpot/cordova-admob-pro
+
+angular.module('ngCordova.plugins.googleAds', [])
+ .factory('$cordovaGoogleAds', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.AdMob.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.AdMob.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.AdMob.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.AdMob.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.AdMob.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.AdMob.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.AdMob.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.AdMob.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/danwilson/google-analytics-plugin.git
+// link : https://github.com/danwilson/google-analytics-plugin
+
+angular.module('ngCordova.plugins.googleAnalytics', [])
+
+ .factory('$cordovaGoogleAnalytics', ['$q', '$window', function ($q, $window) {
+
+ return {
+ startTrackerWithId: function (id) {
+ var d = $q.defer();
+
+ $window.analytics.startTrackerWithId(id, function (response) {
+ d.resolve(response);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ setUserId: function (id) {
+ var d = $q.defer();
+
+ $window.analytics.setUserId(id, function (response) {
+ d.resolve(response);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ debugMode: function () {
+ var d = $q.defer();
+
+ $window.analytics.debugMode(function (response) {
+ d.resolve(response);
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ trackView: function (screenName) {
+ var d = $q.defer();
+
+ $window.analytics.trackView(screenName, function (response) {
+ d.resolve(response);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ addCustomDimension: function (key, value) {
+ var d = $q.defer();
+
+ $window.analytics.addCustomDimension(key, value, function () {
+ d.resolve();
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ trackEvent: function (category, action, label, value) {
+ var d = $q.defer();
+
+ $window.analytics.trackEvent(category, action, label, value, function (response) {
+ d.resolve(response);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ addTransaction: function (transactionId, affiliation, revenue, tax, shipping, currencyCode) {
+ var d = $q.defer();
+
+ $window.analytics.addTransaction(transactionId, affiliation, revenue, tax, shipping, currencyCode, function (response) {
+ d.resolve(response);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ },
+
+ addTransactionItem: function (transactionId, name, sku, category, price, quantity, currencyCode) {
+ var d = $q.defer();
+
+ $window.analytics.addTransactionItem(transactionId, name, sku, category, price, quantity, currencyCode, function (response) {
+ d.resolve(response);
+ }, function (error) {
+ d.reject(error);
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install :
+// link :
+
+// Google Maps needs ALOT of work!
+// Not for production use
+
+angular.module('ngCordova.plugins.googleMap', [])
+
+ .factory('$cordovaGoogleMap', ['$q', '$window', function ($q, $window) {
+
+ var map = null;
+
+ return {
+ getMap: function (options) {
+ var q = $q.defer();
+
+ if (!$window.plugin.google.maps) {
+ q.reject(null);
+ }
+ else {
+ var div = document.getElementById("map_canvas");
+ map = $window.plugin.google.maps.Map.getMap(options);
+ map.setDiv(div);
+ q.resolve(map);
+ }
+ return q.promise;
+ },
+
+
+ isMapLoaded: function () { // check if an instance of the map exists
+ return !!map;
+ },
+ addMarker: function (markerOptions) { // add a marker to the map with given markerOptions
+ var q = $q.defer();
+ map.addMarker(markerOptions, function (marker) {
+ q.resolve(marker);
+ });
+
+ return q.promise;
+ },
+ getMapTypeIds: function () {
+ return $window.plugin.google.maps.mapTypeId;
+ },
+ setVisible: function (isVisible) {
+ var q = $q.defer();
+ map.setVisible(isVisible);
+ return q.promise;
+ },
+ // I don't know how to deallocate te map and the google map plugin.
+ cleanup: function () {
+ map = null;
+ // delete map;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/ptgamr/cordova-google-play-game.git --variable APP_ID=123456789
+// link : https://github.com/ptgamr/cordova-google-play-game
+
+angular.module('ngCordova.plugins.googlePlayGame', [])
+
+ .factory('$cordovaGooglePlayGame', ['$q', function ($q) {
+
+ return {
+
+ auth: function() {
+ var q = $q.defer();
+
+ googleplaygame.auth(function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ signout: function() {
+ var q = $q.defer();
+
+ googleplaygame.signout(function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ isSignedIn: function() {
+ var q = $q.defer();
+
+ googleplaygame.isSignedIn(function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ showPlayer: function() {
+ var q = $q.defer();
+
+ googleplaygame.showPlayer(function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ submitScore: function(data) {
+ var q = $q.defer();
+
+ googleplaygame.submitScore(data, function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ showAllLeaderboards: function() {
+ var q = $q.defer();
+
+ googleplaygame.showAllLeaderboards(function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ showLeaderboard: function(data) {
+ var q = $q.defer();
+
+ googleplaygame.showLeaderboard(data, function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ unlockAchievement: function(data) {
+ var q = $q.defer();
+
+ googleplaygame.unlockAchievement(data, function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ incrementAchievement: function(data) {
+ var q = $q.defer();
+
+ googleplaygame.incrementAchievement(data, function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ },
+ showAchievements: function() {
+ var q = $q.defer();
+
+ googleplaygame.showAchievements(function(success) {
+ return q.resolve(success);
+ }, function(err) {
+ return q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+
+ }]);
+// install : cordova plugin add nl.x-services.plugins.googleplus
+// link : https://github.com/EddyVerbruggen/cordova-plugin-googleplus
+
+ angular.module('ngCordova.plugins.googleplus', [])
+
+ .factory('$cordovaGooglePlus', ['$q', '$window', function ($q, $window) {
+
+ return {
+ login: function(iosKey){
+ if(iosKey === undefined){
+ iosKey = {};
+ }
+ var q = $q.defer();
+ $window.plugins.googleplus.login(
+ {
+ 'iOSApiKey': iosKey
+ // there is no API key for Android; you app is wired to the Google+ API by
+ //listing your package name in the google dev console and signing your apk
+ },
+ function (response) {
+ q.resolve(response)
+ },
+ function (error) {
+ q.reject(error)
+ }
+ );
+
+ return q.promise;
+ },
+
+ silentLogin: function(iosKey){
+
+ if(iosKey === undefined){
+ iosKey = {};
+ }
+ var q = $q.defer();
+ $window.plugins.googleplus.trySilentLogin(
+ {
+ 'iOSApiKey': iosKey
+ // there is no API key for Android; you app is wired to the Google+ API by
+ //listing your package name in the google dev console and signing your apk
+ },
+ function (response) {
+ q.resolve(response)
+ },
+ function (error) {
+ q.reject(error)
+ }
+ );
+
+ return q.promise;
+ },
+
+ logout: function(){
+ var q = $q.defer();
+ $window.plugins.googleplus.logout(
+ function (response) {
+ q.resolve(response);
+ }
+ );
+ },
+
+ disconnect: function(){
+ var q = $q.defer();
+ $window.plugins.googleplus.disconnect(
+ function (response) {
+ q.resolve(response);
+ }
+ );
+ }
+ };
+
+ }]);
+
+// install : cordova plugin add https://github.com/Telerik-Verified-Plugins/HealthKit
+// link : https://github.com/Telerik-Verified-Plugins/HealthKit
+
+angular.module('ngCordova.plugins.healthKit', [])
+
+ .factory('$cordovaHealthKit', ['$q', '$window', function ($q, $window) {
+
+ return {
+ isAvailable: function () {
+ var q = $q.defer();
+
+ $window.plugins.healthkit.available(function (success) {
+ q.resolve(success);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ /**
+ * Check whether or not the user granted your app access to a specific HealthKit type.
+ * Reference for possible types:
+ * https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Constants/
+ */
+ checkAuthStatus: function (type) {
+ var q = $q.defer();
+
+ type = type || 'HKQuantityTypeIdentifierHeight';
+
+ $window.plugins.healthkit.checkAuthStatus({
+ 'type': type
+ }, function (success) {
+ q.resolve(success);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ /**
+ * Request authorization to access HealthKit data. See the full HealthKit constants
+ * reference for possible read and write types:
+ * https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Constants/
+ */
+ requestAuthorization: function (readTypes, writeTypes) {
+ var q = $q.defer();
+
+ readTypes = readTypes || [
+ 'HKCharacteristicTypeIdentifierDateOfBirth', 'HKQuantityTypeIdentifierActiveEnergyBurned', 'HKQuantityTypeIdentifierHeight'
+ ];
+ writeTypes = writeTypes || [
+ 'HKQuantityTypeIdentifierActiveEnergyBurned', 'HKQuantityTypeIdentifierHeight', 'HKQuantityTypeIdentifierDistanceCycling'
+ ];
+
+ $window.plugins.healthkit.requestAuthorization({
+ 'readTypes': readTypes,
+ 'writeTypes': writeTypes
+ }, function (success) {
+ q.resolve(success);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ readDateOfBirth: function () {
+ var q = $q.defer();
+ $window.plugins.healthkit.readDateOfBirth(
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+
+ return q.promise;
+ },
+
+ readGender: function () {
+ var q = $q.defer();
+ $window.plugins.healthkit.readGender(
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+
+ return q.promise;
+ },
+
+ saveWeight: function (value, units, date) {
+ var q = $q.defer();
+ $window.plugins.healthkit.saveWeight({
+ 'unit': units || 'lb',
+ 'amount': value,
+ 'date': date || new Date()
+ },
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+ return q.promise;
+ },
+
+ readWeight: function (units) {
+ var q = $q.defer();
+ $window.plugins.healthkit.readWeight({
+ 'unit': units || 'lb'
+ },
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+
+ return q.promise;
+ },
+ saveHeight: function (value, units, date) {
+ var q = $q.defer();
+ $window.plugins.healthkit.saveHeight({
+ 'unit': units || 'in',
+ 'amount': value,
+ 'date': date || new Date()
+ },
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+ return q.promise;
+ },
+ readHeight: function (units) {
+ var q = $q.defer();
+ $window.plugins.healthkit.readHeight({
+ 'unit': units || 'in'
+ },
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+
+ return q.promise;
+ },
+
+ findWorkouts: function () {
+ var q = $q.defer();
+ $window.plugins.healthkit.findWorkouts({},
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+ return q.promise;
+ },
+
+ /**
+ * Save a workout.
+ *
+ * Workout param should be of the format:
+ {
+ 'activityType': 'HKWorkoutActivityTypeCycling', // HKWorkoutActivityType constant (https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HKWorkout_Class/#//apple_ref/c/tdef/HKWorkoutActivityType)
+ 'quantityType': 'HKQuantityTypeIdentifierDistanceCycling',
+ 'startDate': new Date(), // mandatory
+ 'endDate': null, // optional, use either this or duration
+ 'duration': 3600, // in seconds, optional, use either this or endDate
+ 'energy': 300, //
+ 'energyUnit': 'kcal', // J|cal|kcal
+ 'distance': 11, // optional
+ 'distanceUnit': 'km' // probably useful with the former param
+ // 'extraData': "", // Not sure how necessary this is
+ },
+ */
+ saveWorkout: function (workout) {
+ var q = $q.defer();
+ $window.plugins.healthkit.saveWorkout(workout,
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+ return q.promise;
+ },
+
+ /**
+ * Sample any kind of health data through a given date range.
+ * sampleQuery of the format:
+ {
+ 'startDate': yesterday, // mandatory
+ 'endDate': tomorrow, // mandatory
+ 'sampleType': 'HKQuantityTypeIdentifierHeight',
+ 'unit' : 'cm'
+ },
+ */
+ querySampleType: function (sampleQuery) {
+ var q = $q.defer();
+ $window.plugins.healthkit.querySampleType(sampleQuery,
+ function (success) {
+ q.resolve(success);
+ },
+ function (err) {
+ q.resolve(err);
+ }
+ );
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-httpd.git
+// link : https://github.com/floatinghotpot/cordova-httpd
+
+angular.module('ngCordova.plugins.httpd', [])
+ .factory('$cordovaHttpd', ['$q', function ($q) {
+
+ return {
+ startServer: function (options) {
+ var d = $q.defer();
+
+ cordova.plugins.CorHttpd.startServer(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ stopServer: function () {
+ var d = $q.defer();
+
+ cordova.plugins.CorHttpd.stopServer(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ getURL: function () {
+ var d = $q.defer();
+
+ cordova.plugins.CorHttpd.getURL(function (url) {
+ d.resolve(url);
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ getLocalPath: function () {
+ var d = $q.defer();
+
+ cordova.plugins.CorHttpd.getLocalPath(function (path) {
+ d.resolve(path);
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-plugin-iad.git
+// link : https://github.com/floatinghotpot/cordova-plugin-iad
+
+angular.module('ngCordova.plugins.iAd', [])
+ .factory('$cordovaiAd', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.iAd.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.iAd.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.iAd.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.iAd.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.iAd.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.iAd.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.iAd.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.iAd.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/wymsee/cordova-imagePicker.git
+// link : https://github.com/wymsee/cordova-imagePicker
+
+angular.module('ngCordova.plugins.imagePicker', [])
+
+ .factory('$cordovaImagePicker', ['$q', '$window', function ($q, $window) {
+
+ return {
+ getPictures: function (options) {
+ var q = $q.defer();
+
+ $window.imagePicker.getPictures(function (results) {
+ q.resolve(results);
+ }, function (error) {
+ q.reject(error);
+ }, options);
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.inappbrowser
+// link : https://github.com/apache/cordova-plugin-inappbrowser/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.inAppBrowser', [])
+
+ .provider('$cordovaInAppBrowser', [function () {
+
+ var ref;
+ var defaultOptions = this.defaultOptions = {};
+
+ this.setDefaultOptions = function (config) {
+ defaultOptions = angular.extend(defaultOptions, config);
+ };
+
+ this.$get = ['$rootScope', '$q', '$window', '$timeout', function ($rootScope, $q, $window, $timeout) {
+ return {
+ open: function (url, target, requestOptions) {
+ var q = $q.defer();
+
+ if (requestOptions && !angular.isObject(requestOptions)) {
+ q.reject("options must be an object");
+ return q.promise;
+ }
+
+ var options = angular.extend({}, defaultOptions, requestOptions);
+
+ var opt = [];
+ angular.forEach(options, function (value, key) {
+ opt.push(key + '=' + value);
+ });
+ var optionsString = opt.join();
+
+ ref = $window.open(url, target, optionsString);
+
+ ref.addEventListener('loadstart', function (event) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaInAppBrowser:loadstart', event);
+ });
+ }, false);
+
+ ref.addEventListener('loadstop', function (event) {
+ q.resolve(event);
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaInAppBrowser:loadstop', event);
+ });
+ }, false);
+
+ ref.addEventListener('loaderror', function (event) {
+ q.reject(event);
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaInAppBrowser:loaderror', event);
+ });
+ }, false);
+
+ ref.addEventListener('exit', function (event) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaInAppBrowser:exit', event);
+ });
+ }, false);
+
+ return q.promise;
+ },
+
+ close: function () {
+ ref.close();
+ ref = null;
+ },
+
+ show: function () {
+ ref.show();
+ },
+
+ executeScript: function (details) {
+ var q = $q.defer();
+
+ ref.executeScript(details, function (result) {
+ q.resolve(result);
+ });
+
+ return q.promise;
+ },
+
+ insertCSS: function (details) {
+ var q = $q.defer();
+
+ ref.insertCSS(details, function (result) {
+ q.resolve(result);
+ });
+
+ return q.promise;
+ }
+ };
+ }];
+ }]);
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin.git
+// link : https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin
+angular.module('ngCordova.plugins.insomnia', [])
+
+ .factory('$cordovaInsomnia', ['$window', function ($window) {
+
+ return {
+ keepAwake: function () {
+ return $window.plugins.insomnia.keepAwake();
+ },
+ allowSleepAgain: function () {
+ return $window.plugins.insomnia.allowSleepAgain();
+ }
+ }
+
+ }]);
+// install : cordova plugins add https://github.com/vstirbu/InstagramPlugin
+// link : https://github.com/vstirbu/InstagramPlugin
+
+angular.module('ngCordova.plugins.instagram', [])
+
+.factory('$cordovaInstagram', ['$q', function ($q) {
+
+ return {
+ share: function (options) {
+ var q = $q.defer();
+
+ if (!window.Instagram) {
+ console.error('Tried to call Instagram.share but the Instagram plugin isn\'t installed!');
+ q.resolve(null);
+ return q.promise;
+ }
+
+ Instagram.share(options.image, options.caption, function(err) {
+ if(err) {
+ q.reject(err);
+ } else {
+ q.resolve(true);
+ }
+ });
+ return q.promise;
+ },
+ isInstalled: function () {
+ var q = $q.defer();
+
+ if (!window.Instagram) {
+ console.error('Tried to call Instagram.isInstalled but the Instagram plugin isn\'t installed!');
+ q.resolve(null);
+ return q.promise;
+ }
+
+ Instagram.isInstalled(function (err, installed) {
+ if (err) {
+ q.reject(err);
+ } else {
+ q.resolve(installed || true);
+ }
+ });
+ return q.promise;
+ }
+ };
+}]);
+
+// install : cordova plugin add https://github.com/driftyco/ionic-plugins-keyboard.git
+// link : https://github.com/driftyco/ionic-plugins-keyboard
+
+angular.module('ngCordova.plugins.keyboard', [])
+
+ .factory('$cordovaKeyboard', [function () {
+
+ var keyboardShowEvent = function () {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaKeyboard:show');
+ });
+ };
+
+ var keyboardHideEvent = function () {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaKeyboard:hide');
+ });
+ };
+
+ document.addEventListener("deviceready", function () {
+ if (cordova.plugins.Keyboard) {
+ window.addEventListener("native.keyboardshow", keyboardShowEvent, false);
+ window.addEventListener("native.keyboardhide", keyboardHideEvent, false);
+ }
+ });
+
+ return {
+ hideAccessoryBar: function (bool) {
+ return cordova.plugins.Keyboard.hideKeyboardAccessoryBar(bool);
+ },
+
+ close: function () {
+ return cordova.plugins.Keyboard.close();
+ },
+
+ disableScroll: function (bool) {
+ return cordova.plugins.Keyboard.disableScroll(bool);
+ },
+
+ isVisible: function () {
+ return cordova.plugins.Keyboard.isVisible;
+ },
+
+ clearShowWatch: function () {
+ document.removeEventListener("native.keyboardshow", keyboardShowEvent);
+ $rootScope.$$listeners["$cordovaKeyboard:show"] = [];
+ },
+
+ clearHideWatch: function () {
+ document.removeEventListener("native.keyboardhide", keyboardHideEvent);
+ $rootScope.$$listeners["$cordovaKeyboard:hide"] = [];
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/shazron/KeychainPlugin.git
+// link : https://github.com/shazron/KeychainPlugin
+
+angular.module('ngCordova.plugins.keychain', [])
+
+ .factory('$cordovaKeychain', ['$q', '$window', function ($q, $window) {
+
+ if ('Keychain' in $window) {
+ var kc = new Keychain();
+ }
+
+ return {
+ getForKey: function (key, serviceName) {
+ var defer = $q.defer();
+
+ kc.getForKey(defer.resolve, defer.reject, key, serviceName);
+
+ return defer.promise;
+ },
+
+ setForKey: function (key, serviceName, value) {
+ var defer = $q.defer();
+
+ kc.setForKey(defer.resolve, defer.reject, key, serviceName, value);
+
+ return defer.promise;
+ },
+
+ removeForKey: function (key, serviceName) {
+ var defer = $q.defer();
+
+ kc.removeForKey(defer.resolve, defer.reject, key, serviceName);
+
+ return defer.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add de.appplant.cordova.plugin.local-notification
+// link : https://github.com/katzer/cordova-plugin-local-notifications/
+
+angular.module('ngCordova.plugins.localNotification', [])
+
+ .factory('$cordovaLocalNotification', ['$q', '$window', '$rootScope', '$timeout', function ($q, $window, $rootScope, $timeout) {
+ document.addEventListener("deviceready", function () {
+ if ($window.plugin && $window.plugin.notification) {
+ $window.plugin.notification.local.on("cancel", function (id, state, json) {
+ var notification = {
+ id: id,
+ state: state,
+ json: json
+ };
+ $timeout(function () {
+ $rootScope.$broadcast("$cordovaLocalNotification:canceled", notification);
+ });
+ });
+
+ $window.plugin.notification.local.on("click", function (id, state, json) {
+ var notification = {
+ id: id,
+ state: state,
+ json: json
+ };
+ $timeout(function () {
+ $rootScope.$broadcast("$cordovaLocalNotification:clicked", notification);
+ });
+ });
+
+ $window.plugin.notification.local.on("trigger", function (id, state, json) {
+ var notification = {
+ id: id,
+ state: state,
+ json: json
+ };
+ $timeout(function () {
+ $rootScope.$broadcast("$cordovaLocalNotification:triggered", notification);
+ });
+ });
+
+ $window.plugin.notification.local.on("add", function (id, state, json) {
+ var notification = {
+ id: id,
+ state: state,
+ json: json
+ };
+ $timeout(function () {
+ $rootScope.$broadcast("$cordovaLocalNotification:added", notification);
+ });
+ });
+ }
+ }, false);
+ return {
+ add: function (options, scope) {
+ var q = $q.defer();
+ scope = scope || null;
+ $window.plugin.notification.local.add(options, function (result) {
+ q.resolve(result);
+ }, scope);
+ return q.promise;
+ },
+
+ cancel: function (id, scope) {
+ var q = $q.defer();
+ scope = scope || null;
+ $window.plugin.notification.local.cancel(id, function (result) {
+ q.resolve(result);
+ }, scope);
+ return q.promise;
+ },
+
+ cancelAll: function (scope) {
+ var q = $q.defer();
+ scope = scope || null;
+ $window.plugin.notification.local.cancelAll(function (result) {
+ q.resolve(result);
+ }, scope);
+ return q.promise;
+ },
+
+ isScheduled: function (id, scope) {
+ var q = $q.defer();
+ scope = scope || null;
+ $window.plugin.notification.local.isScheduled(id, function (result) {
+ q.resolve(result);
+ }, scope);
+
+ return q.promise;
+ },
+
+ hasPermission: function (scope) {
+ var q = $q.defer();
+ $window.plugin.notification.local.hasPermission(function (result) {
+ result ? q.resolve(result) : q.reject(result);
+ }, scope);
+ return q.promise;
+ },
+
+ promptForPermission: function () {
+ var q = $q.defer();
+ $window.plugin.notification.local.promptForPermission(function (result) {
+ result ? q.resolve(result) : q.reject(result);
+ });
+ return q.promise;
+ },
+
+ registerPermission: function () {
+ var q = $q.defer();
+ $window.plugin.notification.local.registerPermission(function (result) {
+ result ? q.resolve(result) : q.reject(result);
+ });
+ return q.promise;
+ },
+
+ getScheduledIds: function (scope) {
+ var q = $q.defer();
+ $window.plugin.notification.local.getScheduledIds(function (result) {
+ q.resolve(result);
+ }, scope);
+ return q.promise;
+ },
+
+ isTriggered: function (id, scope) {
+ var q = $q.defer();
+ $window.plugin.notification.local.isTriggered(id, function (result) {
+ q.resolve(result);
+ }, scope);
+ return q.promise;
+ },
+
+ getTriggeredIds: function (scope) {
+ var q = $q.defer();
+ $window.plugin.notification.local.getTriggeredIds(function (result) {
+ q.resolve(result);
+ }, scope);
+ return q.promise;
+ },
+
+ getDefaults: function () {
+ return $window.plugin.notification.local.getDefaults();
+ },
+
+ setDefaults: function (Object) {
+ $window.plugin.notification.local.setDefaults(Object);
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-plugin-mmedia.git
+// link : https://github.com/floatinghotpot/cordova-plugin-mmedia
+
+angular.module('ngCordova.plugins.mMediaAds', [])
+ .factory('$cordovaMMediaAds', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.mMedia.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.mMedia.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.mMedia.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.mMedia.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.mMedia.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.mMedia.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.mMedia.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.mMedia.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.media
+// link : https://github.com/apache/cordova-plugin-media
+
+angular.module('ngCordova.plugins.media', [])
+
+ .factory('$cordovaMedia', ['$q', function ($q) {
+
+ return {
+ newMedia: function (src) {
+ var q = $q.defer();
+ var mediaStatus = null;
+ var media;
+
+ media = new Media(src,
+ function (success) {
+ q.resolve(success);
+ }, function (error) {
+ q.reject(error);
+ }, function (status) {
+ mediaStatus = status;
+ });
+
+ // getCurrentPosition NOT WORKING!
+ q.promise.getCurrentPosition = function () {
+ media.getCurrentPosition(function (success) {
+ }, function (error) {
+ });
+ };
+
+ q.promise.getDuration = function () {
+ media.getDuration();
+ };
+
+ // iOS quirks :
+ // - myMedia.play({ numberOfLoops: 2 }) -> looping
+ // - myMedia.play({ playAudioWhenScreenIsLocked : false })
+ q.promise.play = function (options) {
+ if (typeof options !== "object") {
+ options = {};
+ }
+ media.play(options);
+ };
+
+ q.promise.pause = function () {
+ media.pause();
+ };
+
+ q.promise.stop = function () {
+ media.stop();
+ };
+
+ q.promise.release = function () {
+ media.release();
+ };
+
+ q.promise.seekTo = function (timing) {
+ media.seekTo(timing);
+ };
+
+ q.promise.setVolume = function (volume) {
+ media.setVolume(volume);
+ };
+
+ q.promise.startRecord = function () {
+ media.startRecord();
+ };
+
+ q.promise.stopRecord = function () {
+ media.stopRecord();
+ };
+
+ q.promise.media = media;
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-mobfox-pro.git
+// link : https://github.com/floatinghotpot/cordova-mobfox-pro
+
+angular.module('ngCordova.plugins.mobfoxAds', [])
+ .factory('$cordovaMobFoxAds', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.MobFox.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.MobFox.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.MobFox.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.MobFox.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.MobFox.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.MobFox.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.MobFox.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.MobFox.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+angular.module('ngCordova.plugins', [
+ 'ngCordova.plugins.actionSheet',
+ 'ngCordova.plugins.adMob',
+ 'ngCordova.plugins.appAvailability',
+ 'ngCordova.plugins.appRate',
+ 'ngCordova.plugins.appVersion',
+ 'ngCordova.plugins.backgroundGeolocation',
+ 'ngCordova.plugins.badge',
+ 'ngCordova.plugins.barcodeScanner',
+ 'ngCordova.plugins.batteryStatus',
+ 'ngCordova.plugins.ble',
+ 'ngCordova.plugins.bluetoothSerial',
+ 'ngCordova.plugins.brightness',
+ 'ngCordova.plugins.calendar',
+ 'ngCordova.plugins.camera',
+ 'ngCordova.plugins.capture',
+ 'ngCordova.plugins.clipboard',
+ 'ngCordova.plugins.contacts',
+ 'ngCordova.plugins.datePicker',
+ 'ngCordova.plugins.device',
+ 'ngCordova.plugins.deviceMotion',
+ 'ngCordova.plugins.deviceOrientation',
+ 'ngCordova.plugins.dialogs',
+ 'ngCordova.plugins.emailComposer',
+ 'ngCordova.plugins.facebook',
+ 'ngCordova.plugins.facebookAds',
+ 'ngCordova.plugins.file',
+ 'ngCordova.plugins.fileTransfer',
+ 'ngCordova.plugins.fileOpener2',
+ 'ngCordova.plugins.flashlight',
+ 'ngCordova.plugins.flurryAds',
+ 'ngCordova.plugins.ga',
+ 'ngCordova.plugins.geolocation',
+ 'ngCordova.plugins.globalization',
+ 'ngCordova.plugins.googleAds',
+ 'ngCordova.plugins.googleAnalytics',
+ 'ngCordova.plugins.googleMap',
+ 'ngCordova.plugins.googlePlayGame',
+ 'ngCordova.plugins.healthKit',
+ 'ngCordova.plugins.httpd',
+ 'ngCordova.plugins.iAd',
+ 'ngCordova.plugins.imagePicker',
+ 'ngCordova.plugins.inAppBrowser',
+ 'ngCordova.plugins.keyboard',
+ 'ngCordova.plugins.keychain',
+ 'ngCordova.plugins.localNotification',
+ 'ngCordova.plugins.media',
+ 'ngCordova.plugins.mMediaAds',
+ 'ngCordova.plugins.mobfoxAds',
+ 'ngCordova.plugins.mopubAds',
+ 'ngCordova.plugins.nativeAudio',
+ 'ngCordova.plugins.network',
+ 'ngCordova.plugins.oauth',
+ 'ngCordova.plugins.oauthUtility',
+ 'ngCordova.plugins.pinDialog',
+ 'ngCordova.plugins.prefs',
+ 'ngCordova.plugins.printer',
+ 'ngCordova.plugins.progressIndicator',
+ 'ngCordova.plugins.push',
+ 'ngCordova.plugins.sms',
+ 'ngCordova.plugins.socialSharing',
+ 'ngCordova.plugins.spinnerDialog',
+ 'ngCordova.plugins.splashscreen',
+ 'ngCordova.plugins.sqlite',
+ 'ngCordova.plugins.statusbar',
+ 'ngCordova.plugins.toast',
+ 'ngCordova.plugins.touchid',
+ 'ngCordova.plugins.vibration',
+ 'ngCordova.plugins.videoCapturePlus',
+ 'ngCordova.plugins.zip',
+ 'ngCordova.plugins.insomnia'
+]);
+
+// install : cordova plugin add https://github.com/floatinghotpot/cordova-plugin-mopub.git
+// link : https://github.com/floatinghotpot/cordova-plugin-mopub
+
+angular.module('ngCordova.plugins.mopubAds', [])
+ .factory('$cordovaMoPubAds', ['$q', '$window', function ($q, $window) {
+
+ return {
+ setOptions: function (options) {
+ var d = $q.defer();
+
+ $window.MoPub.setOptions(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ createBanner: function (options) {
+ var d = $q.defer();
+
+ $window.MoPub.createBanner(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ removeBanner: function () {
+ var d = $q.defer();
+
+ $window.MoPub.removeBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBanner: function (position) {
+ var d = $q.defer();
+
+ $window.MoPub.showBanner(position, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showBannerAtXY: function (x, y) {
+ var d = $q.defer();
+
+ $window.MoPub.showBannerAtXY(x, y, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ hideBanner: function () {
+ var d = $q.defer();
+
+ $window.MoPub.hideBanner(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ prepareInterstitial: function (options) {
+ var d = $q.defer();
+
+ $window.MoPub.prepareInterstitial(options, function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ },
+
+ showInterstitial: function () {
+ var d = $q.defer();
+
+ $window.MoPub.showInterstitial(function () {
+ d.resolve();
+ }, function () {
+ d.reject();
+ });
+
+ return d.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/sidneys/cordova-plugin-nativeaudio.git
+// link : https://github.com/sidneys/cordova-plugin-nativeaudio
+
+angular.module('ngCordova.plugins.nativeAudio', [])
+
+ .factory('$cordovaNativeAudio', ['$q', '$window', function ($q, $window) {
+
+ return {
+ preloadSimple: function (id, assetPath) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.preloadSimple(id, assetPath, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ preloadComplex: function (id, assetPath, volume, voices) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.preloadComplex(id, assetPath, volume, voices, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ play: function (id, completeCallback) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.play(id, completeCallback, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ stop: function (id) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.stop(id, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ },
+
+ loop: function (id) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.loop(id, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ unload: function (id) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.unload(id, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ setVolumeForComplexAsset: function (id, volume) {
+ var q = $q.defer();
+ $window.plugins.NativeAudio.setVolumeForComplexAsset(id, volume, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.network-information
+// link : https://github.com/apache/cordova-plugin-network-information/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.network', [])
+
+ .factory('$cordovaNetwork', ['$rootScope', '$timeout', function ($rootScope, $timeout) {
+
+ var offlineEvent = function () {
+ var networkState = navigator.connection.type;
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaNetwork:offline', networkState);
+ });
+ };
+
+ var onlineEvent = function () {
+ var networkState = navigator.connection.type;
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaNetwork:online', networkState);
+ });
+ };
+
+ document.addEventListener("deviceready", function () {
+ if (navigator.connection) {
+ document.addEventListener("offline", offlineEvent, false);
+ document.addEventListener("online", onlineEvent, false);
+ }
+ });
+
+ return {
+ getNetwork: function () {
+ return navigator.connection.type;
+ },
+
+ isOnline: function () {
+ var networkState = navigator.connection.type;
+ return networkState !== Connection.UNKNOWN && networkState !== Connection.NONE;
+ },
+
+ isOffline: function () {
+ var networkState = navigator.connection.type;
+ return networkState === Connection.UNKNOWN || networkState === Connection.NONE;
+ },
+
+ clearOfflineWatch: function () {
+ document.removeEventListener("offline", offlineEvent);
+ $rootScope.$$listeners["$cordovaNetwork:offline"] = [];
+ },
+
+ clearOnlineWatch: function () {
+ document.removeEventListener("online", offlineEvent);
+ $rootScope.$$listeners["$cordovaNetwork:online"] = [];
+ }
+ };
+ }])
+ .run(['$cordovaNetwork', function ($cordovaNetwork) {
+ }]);
+
+/* Created by Nic Raboy
+ * http://www.nraboy.com
+ *
+ * DESCRIPTION: Use Oauth sign in for various web services.
+ *
+ * REQUIRES: Apache Cordova 3.5+, Apache InAppBrowser Plugin, jsSHA (Twitter, Magento only)
+ *
+ * SUPPORTS:
+ * Dropbox
+ * Digital Ocean
+ * Google
+ * GitHub
+ * Facebook
+ * LinkedIn
+ * Instagram
+ * Box
+ * Reddit
+ * Twitter
+ * Meetup
+ * Foursquare
+ * Salesforce
+ * Strava
+ * Magento
+ * vkontakte
+ * ADFS
+ * Imgur
+ */
+
+angular.module("ngCordova.plugins.oauth", ["ngCordova.plugins.oauthUtility"])
+
+ .factory('$cordovaOauth', ['$q', '$http', '$cordovaOauthUtility', function ($q, $http, $cordovaOauthUtility) {
+
+ return {
+
+ /*
+ * Sign into the ADFS service (ADFS 3.0 onwards)
+ *
+ * @param string clientId (client registered in ADFS, with redirect_uri configured to: http://localhost/callback)
+ * @param string adfsServer (url of the ADFS Server)
+ * @param string relyingPartyId (url of the Relying Party (resource relying on ADFS for authentication) configured in ADFS)
+ * @return promise
+ */
+ adfs: function(clientId, adfsServer, relyingPartyId) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open(adfsServer + '/adfs/oauth2/authorize?response_type=code&client_id=' + clientId +'&redirect_uri=http://localhost/callback&resource=' + relyingPartyId, '_blank', 'location=no');
+
+ browserRef.addEventListener("loadstart", function(event) {
+ if((event.url).indexOf('http://localhost/callback') === 0) {
+ var requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: adfsServer + "/adfs/oauth2/token", data: "client_id=" + clientId + "&code=" + requestToken + "&redirect_uri=http://localhost/callback&grant_type=authorization_code" })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Dropbox service
+ *
+ * @param string appKey
+ * @return promise
+ */
+ dropbox: function(appKey) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open("https://www.dropbox.com/1/oauth2/authorize?client_id=" + appKey + "&redirect_uri=http://localhost/callback" + "&response_type=token", "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
+ browserRef.addEventListener("loadstart", function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve({ access_token: parameterMap.access_token, token_type: parameterMap.token_type, uid: parameterMap.uid });
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Digital Ocean service
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @return promise
+ */
+ digitalOcean: function(clientId, clientSecret) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open("https://cloud.digitalocean.com/v1/oauth/authorize?client_id=" + clientId + "&redirect_uri=http://localhost/callback&response_type=code&scope=read%20write", "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
+ browserRef.addEventListener("loadstart", function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: "https://cloud.digitalocean.com/v1/oauth/token", data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Google service
+ *
+ * @param string clientId
+ * @param array appScope
+ * @return promise
+ */
+ google: function(clientId, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://accounts.google.com/o/oauth2/auth?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(" ") + '&approval_prompt=force&response_type=token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener("loadstart", function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve({ access_token: parameterMap.access_token, token_type: parameterMap.token_type, expires_in: parameterMap.expires_in });
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the GitHub service
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @param array appScope
+ * @return promise
+ */
+ github: function(clientId, clientSecret, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://github.com/login/oauth/authorize?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(","), '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http.defaults.headers.post.accept = 'application/json';
+ $http({method: "post", url: "https://github.com/login/oauth/access_token", data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=http://localhost/callback" + "&code=" + requestToken })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Facebook service
+ *
+ * @param string clientId
+ * @param array appScope
+ * @return promise
+ */
+ facebook: function(clientId, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://www.facebook.com/dialog/oauth?client_id=' + clientId + '&redirect_uri=http://localhost/callback&response_type=token&scope=' + appScope.join(","), '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve({ access_token: parameterMap.access_token, expires_in: parameterMap.expires_in });
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the LinkedIn service
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @param array appScope
+ * @param string state
+ * @return promise
+ */
+ linkedin: function(clientId, clientSecret, appScope, state) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://www.linkedin.com/uas/oauth2/authorization?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(" ") + '&response_type=code&state=' + state, '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: "https://www.linkedin.com/uas/oauth2/accessToken", data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Instagram service
+ *
+ * @param string clientId
+ * @param array appScope
+ * @return promise
+ */
+ instagram: function(clientId, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://api.instagram.com/oauth/authorize/?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(" ") + '&response_type=token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve({ access_token: parameterMap.access_token });
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Box service
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @param string appState
+ * @return promise
+ */
+ box: function(clientId, clientSecret, appState) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://app.box.com/api/oauth2/authorize/?client_id=' + clientId + '&redirect_uri=http://localhost/callback&state=' + appState + '&response_type=code', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: "https://app.box.com/api/oauth2/token", data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Reddit service
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @param array appScope
+ * @return promise
+ */
+ reddit: function(clientId, clientSecret, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://ssl.reddit.com/api/v1/authorize?client_id=' + clientId + '&redirect_uri=http://localhost/callback&duration=permanent&state=ngcordovaoauth&scope=' + appScope.join(",") + '&response_type=code', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http.defaults.headers.post.Authorization = 'Basic ' + btoa(clientId + ":" + clientSecret);
+ $http({method: "post", url: "https://ssl.reddit.com/api/v1/access_token", data: "redirect_uri=http://localhost/callback" + "&grant_type=authorization_code" + "&code=" + requestToken })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Twitter service
+ * Note that this service requires jsSHA for generating HMAC-SHA1 Oauth 1.0 signatures
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @return promise
+ */
+ twitter: function(clientId, clientSecret) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ if(typeof jsSHA !== "undefined") {
+ var oauthObject = {
+ oauth_consumer_key: clientId,
+ oauth_nonce: $cordovaOauthUtility.createNonce(10),
+ oauth_signature_method: "HMAC-SHA1",
+ oauth_timestamp: Math.round((new Date()).getTime() / 1000.0),
+ oauth_version: "1.0"
+ };
+ var signatureObj = $cordovaOauthUtility.createSignature("POST", "https://api.twitter.com/oauth/request_token", oauthObject, { oauth_callback: "http://localhost/callback" }, clientSecret);
+ $http({
+ method: "post",
+ url: "https://api.twitter.com/oauth/request_token",
+ headers: {
+ "Authorization": signatureObj.authorization_header,
+ "Content-Type": "application/x-www-form-urlencoded"
+ },
+ data: "oauth_callback=" + encodeURIComponent("http://localhost/callback")
+ })
+ .success(function(requestTokenResult) {
+ var requestTokenParameters = (requestTokenResult).split("&");
+ var parameterMap = {};
+ for(var i = 0; i < requestTokenParameters.length; i++) {
+ parameterMap[requestTokenParameters[i].split("=")[0]] = requestTokenParameters[i].split("=")[1];
+ }
+ if(parameterMap.hasOwnProperty("oauth_token") === false) {
+ deferred.reject("Oauth request token was not received");
+ }
+ var browserRef = window.open('https://api.twitter.com/oauth/authenticate?oauth_token=' + parameterMap.oauth_token, '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("?")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = {};
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.hasOwnProperty("oauth_verifier") === false) {
+ deferred.reject("Browser authentication failed to complete. No oauth_verifier was returned");
+ }
+ delete oauthObject.oauth_signature;
+ oauthObject.oauth_token = parameterMap.oauth_token;
+ var signatureObj = $cordovaOauthUtility.createSignature("POST", "https://api.twitter.com/oauth/access_token", oauthObject, { oauth_verifier: parameterMap.oauth_verifier }, clientSecret);
+ $http({
+ method: "post",
+ url: "https://api.twitter.com/oauth/access_token",
+ headers: {
+ "Authorization": signatureObj.authorization_header
+ },
+ params: {
+ "oauth_verifier": parameterMap.oauth_verifier
+ }
+ })
+ .success(function(result) {
+ var accessTokenParameters = result.split("&");
+ var parameterMap = {};
+ for(var i = 0; i < accessTokenParameters.length; i++) {
+ parameterMap[accessTokenParameters[i].split("=")[0]] = accessTokenParameters[i].split("=")[1];
+ }
+ if(parameterMap.hasOwnProperty("oauth_token_secret") === false) {
+ deferred.reject("Oauth access token was not received");
+ }
+ deferred.resolve(parameterMap);
+ })
+ .error(function(error) {
+ deferred.reject(error);
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ })
+ .error(function(error) {
+ deferred.reject(error);
+ });
+ } else {
+ deferred.reject("Missing jsSHA JavaScript library");
+ }
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Meetup service
+ *
+ * @param string clientId
+ * @return promise
+ */
+ meetup: function(clientId) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://secure.meetup.com/oauth2/authorize/?client_id=' + clientId + '&redirect_uri=http://localhost/callback&response_type=token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = {};
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve(parameterMap);
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Salesforce service
+ *
+ * Suggestion: use salesforce oauth with forcetk.js(as SDK)
+ *
+ * @param string loginUrl (such as: https://login.salesforce.com ; please notice community login)
+ * @param string clientId (copy from connection app info)
+ * @param string redirectUri (callback url in connection app info)
+ * @return promise
+ */
+ salesforce: function (loginUrl, clientId) {
+ var redirectUri = 'http://localhost/callback';
+ var getAuthorizeUrl = function (loginUrl, clientId, redirectUri) {
+ return loginUrl+'services/oauth2/authorize?display=touch'+
+ '&response_type=token&client_id='+escape(clientId)+
+ '&redirect_uri='+escape(redirectUri);
+ };
+ var startWith = function(string, str) {
+ return (string.substr(0, str.length) === str);
+ };
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open(getAuthorizeUrl(loginUrl, clientId, redirectUri), "_blank", "location=no,clearsessioncache=yes,clearcache=yes");
+ browserRef.addEventListener("loadstart", function(event) {
+ if(startWith(event.url, redirectUri)) {
+ var oauthResponse = {};
+
+ var fragment = (event.url).split('#')[1];
+
+ if (fragment) {
+ var nvps = fragment.split('&');
+ for (var nvp in nvps) {
+ var parts = nvps[nvp].split('=');
+ oauthResponse[parts[0]] = unescape(parts[1]);
+ }
+ }
+
+ if (typeof oauthResponse === 'undefined' ||
+ typeof oauthResponse.access_token === 'undefined') {
+ deferred.reject("Problem authenticating");
+ } else {
+ deferred.resolve(oauthResponse);
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Strava service
+ *
+ * @param string clientId
+ * @param string clientSecret
+ * @param array appScope
+ * @return promise
+ */
+ strava: function(clientId, clientSecret, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://www.strava.com/oauth/authorize?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(",") + '&response_type=code&approval_prompt=force', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ requestToken = (event.url).split("code=")[1];
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: "https://www.strava.com/oauth/token", data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&code=" + requestToken })
+ .success(function(data) {
+ deferred.resolve(data);
+ })
+ .error(function(data, status) {
+ deferred.reject("Problem authenticating");
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Foursquare service
+ *
+ * @param string clientId
+ * @return promise
+ */
+ foursquare: function(clientId) {
+ var deferred = $q.defer();
+ if (window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if (cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://foursquare.com/oauth2/authenticate?client_id=' + clientId + '&redirect_uri=http://localhost/callback&response_type=token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function (event) {
+ if ((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for (var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if (parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ var promiseResponse = {
+ access_token: parameterMap.access_token,
+ expires_in: parameterMap.expires_in
+ };
+ deferred.resolve(promiseResponse);
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Magento service
+ * Note that this service requires jsSHA for generating HMAC-SHA1 Oauth 1.0 signatures
+ *
+ * @param string baseUrl
+ * @param string clientId
+ * @param string clientSecret
+ * @return promise
+ */
+ magento: function(baseUrl, clientId, clientSecret) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ if(typeof jsSHA !== "undefined") {
+ var oauthObject = {
+ oauth_callback: "http://localhost/callback",
+ oauth_consumer_key: clientId,
+ oauth_nonce: $cordovaOauthUtility.createNonce(5),
+ oauth_signature_method: "HMAC-SHA1",
+ oauth_timestamp: Math.round((new Date()).getTime() / 1000.0),
+ oauth_version: "1.0"
+ };
+ var signatureObj = $cordovaOauthUtility.createSignature("POST", baseUrl + "/oauth/initiate", oauthObject, { oauth_callback: "http://localhost/callback" }, clientSecret);
+ $http.defaults.headers.post.Authorization = signatureObj.authorization_header;
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: baseUrl + "/oauth/initiate", data: "oauth_callback=http://localhost/callback" })
+ .success(function(requestTokenResult) {
+ var requestTokenParameters = (requestTokenResult).split("&");
+ var parameterMap = {};
+ for(var i = 0; i < requestTokenParameters.length; i++) {
+ parameterMap[requestTokenParameters[i].split("=")[0]] = requestTokenParameters[i].split("=")[1];
+ }
+ if(parameterMap.hasOwnProperty("oauth_token") === false) {
+ deferred.reject("Oauth request token was not received");
+ }
+ var tokenSecret = parameterMap.oauth_token_secret;
+ var browserRef = window.open(baseUrl + '/oauth/authorize?oauth_token=' + parameterMap.oauth_token, '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ var callbackResponse = (event.url).split("?")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = {};
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.hasOwnProperty("oauth_verifier") === false) {
+ deferred.reject("Browser authentication failed to complete. No oauth_verifier was returned");
+ }
+ delete oauthObject.oauth_signature;
+ delete oauthObject.oauth_callback;
+ oauthObject.oauth_token = parameterMap.oauth_token;
+ oauthObject.oauth_nonce = $cordovaOauthUtility.createNonce(5);
+ oauthObject.oauth_verifier = parameterMap.oauth_verifier;
+ var signatureObj = $cordovaOauthUtility.createSignature("POST", baseUrl + "/oauth/token", oauthObject, {}, clientSecret, tokenSecret);
+ $http.defaults.headers.post.Authorization = signatureObj.authorization_header;
+ $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+ $http({method: "post", url: baseUrl + "/oauth/token" })
+ .success(function(result) {
+ var accessTokenParameters = result.split("&");
+ var parameterMap = {};
+ for(var i = 0; i < accessTokenParameters.length; i++) {
+ parameterMap[accessTokenParameters[i].split("=")[0]] = accessTokenParameters[i].split("=")[1];
+ }
+ if(parameterMap.hasOwnProperty("oauth_token_secret") === false) {
+ deferred.reject("Oauth access token was not received");
+ }
+ deferred.resolve(parameterMap);
+ })
+ .error(function(error) {
+ deferred.reject(error);
+ })
+ .finally(function() {
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ });
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ })
+ .error(function(error) {
+ deferred.reject(error);
+ });
+ } else {
+ deferred.reject("Missing jsSHA JavaScript library");
+ }
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Vkontakte service
+ *
+ * @param string clientId
+ * @param array appScope (for example: "friends,wall,photos,messages")
+ * @return promise
+ */
+ vkontakte: function(clientId, appScope) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://oauth.vk.com/authorize?client_id=' + clientId + '&redirect_uri=http://oauth.vk.com/blank.html&response_type=token&scope=' + appScope.join(",") + '&display=touch&response_type=token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ var tmp = (event.url).split("#");
+ if (tmp[0] == 'https://oauth.vk.com/blank.html' || tmp[0] == 'http://oauth.vk.com/blank.html') {
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve({ access_token: parameterMap.access_token, expires_in: parameterMap.expires_in, user_id: parameterMap.user_id });
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ setTimeout(function() {
+ browserRef.close();
+ }, 10);
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ },
+
+ /*
+ * Sign into the Imgur service
+ *
+ * @param string clientId
+ * @return promise
+ */
+ imgur: function(clientId) {
+ var deferred = $q.defer();
+ if(window.cordova) {
+ var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
+ if(cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
+ var browserRef = window.open('https://api.imgur.com/oauth2/authorize?client_id=' + clientId + '&response_type=token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes');
+ browserRef.addEventListener('loadstart', function(event) {
+ if((event.url).indexOf("http://localhost/callback") === 0) {
+ browserRef.removeEventListener("exit",function(event){});
+ browserRef.close();
+ var callbackResponse = (event.url).split("#")[1];
+ var responseParameters = (callbackResponse).split("&");
+ var parameterMap = [];
+ for(var i = 0; i < responseParameters.length; i++) {
+ parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
+ }
+ if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
+ deferred.resolve({ access_token: parameterMap.access_token, expires_in: parameterMap.expires_in, account_username: parameterMap.account_username });
+ } else {
+ deferred.reject("Problem authenticating");
+ }
+ }
+ });
+ browserRef.addEventListener('exit', function(event) {
+ deferred.reject("The sign in flow was canceled");
+ });
+ } else {
+ deferred.reject("Could not find InAppBrowser plugin");
+ }
+ } else {
+ deferred.reject("Cannot authenticate via a web browser");
+ }
+ return deferred.promise;
+ }
+
+ };
+ }]);
+
+angular.module("ngCordova.plugins.oauthUtility", [])
+
+ .factory('$cordovaOauthUtility', ['$q', function ($q) {
+
+ return {
+
+ /*
+ * Sign an Oauth 1.0 request
+ *
+ * @param string method
+ * @param string endPoint
+ * @param object headerParameters
+ * @param object bodyParameters
+ * @param string secretKey
+ * @return object
+ */
+ createSignature: function(method, endPoint, headerParameters, bodyParameters, secretKey, tokenSecret) {
+ if(typeof jsSHA !== "undefined") {
+ var headerAndBodyParameters = angular.copy(headerParameters);
+ var bodyParameterKeys = Object.keys(bodyParameters);
+ for(var i = 0; i < bodyParameterKeys.length; i++) {
+ headerAndBodyParameters[bodyParameterKeys[i]] = encodeURIComponent(bodyParameters[bodyParameterKeys[i]]);
+ }
+ var signatureBaseString = method + "&" + encodeURIComponent(endPoint) + "&";
+ var headerAndBodyParameterKeys = (Object.keys(headerAndBodyParameters)).sort();
+ for(i = 0; i < headerAndBodyParameterKeys.length; i++) {
+ if(i == headerAndBodyParameterKeys.length - 1) {
+ signatureBaseString += encodeURIComponent(headerAndBodyParameterKeys[i] + "=" + headerAndBodyParameters[headerAndBodyParameterKeys[i]]);
+ } else {
+ signatureBaseString += encodeURIComponent(headerAndBodyParameterKeys[i] + "=" + headerAndBodyParameters[headerAndBodyParameterKeys[i]] + "&");
+ }
+ }
+ var oauthSignatureObject = new jsSHA(signatureBaseString, "TEXT");
+
+ var encodedTokenSecret = '';
+ if (tokenSecret) {
+ encodedTokenSecret = encodeURIComponent(tokenSecret);
+ }
+
+ headerParameters.oauth_signature = encodeURIComponent(oauthSignatureObject.getHMAC(encodeURIComponent(secretKey) + "&" + encodedTokenSecret, "TEXT", "SHA-1", "B64"));
+ var headerParameterKeys = Object.keys(headerParameters);
+ var authorizationHeader = 'OAuth ';
+ for(i = 0; i < headerParameterKeys.length; i++) {
+ if(i == headerParameterKeys.length - 1) {
+ authorizationHeader += headerParameterKeys[i] + '="' + headerParameters[headerParameterKeys[i]] + '"';
+ } else {
+ authorizationHeader += headerParameterKeys[i] + '="' + headerParameters[headerParameterKeys[i]] + '",';
+ }
+ }
+ return { signature_base_string: signatureBaseString, authorization_header: authorizationHeader, signature: headerParameters.oauth_signature };
+ } else {
+ return "Missing jsSHA JavaScript library";
+ }
+ },
+
+ /*
+ * Create Random String Nonce
+ *
+ * @param integer length
+ * @return string
+ */
+ createNonce: function(length) {
+ var text = "";
+ var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ for(var i = 0; i < length; i++) {
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+ }
+
+ };
+
+ }]);
+
+// install : cordova plugin add https://github.com/Paldom/PinDialog.git
+// link : https://github.com/Paldom/PinDialog
+
+angular.module('ngCordova.plugins.pinDialog', [])
+
+ .factory('$cordovaPinDialog', ['$q', '$window', function ($q, $window) {
+
+ return {
+ prompt: function (message, title, buttons) {
+ var q = $q.defer();
+
+ $window.plugins.pinDialog.prompt(message, function (res) {
+ q.resolve(res);
+ }, title, buttons);
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install :
+// link :
+
+angular.module('ngCordova.plugins.prefs', [])
+
+ .factory('$cordovaPreferences', ['$window', '$q', function ($window, $q) {
+
+ return {
+
+ set: function (key, value) {
+ var q = $q.defer();
+
+ $window.appgiraffe.plugins.applicationPreferences.set(key, value, function (result) {
+ q.resolve(result);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ },
+
+ get: function (key) {
+ var q = $q.defer();
+
+ $window.appgiraffe.plugins.applicationPreferences.get(key, function (value) {
+ q.resolve(value);
+ }, function (err) {
+ q.reject(err);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add de.appplant.cordova.plugin.printer
+// link : https://github.com/katzer/cordova-plugin-printer
+
+angular.module('ngCordova.plugins.printer', [])
+
+ .factory('$cordovaPrinter', ['$q', '$window', function ($q, $window) {
+
+ return {
+ isAvailable: function () {
+ var q = $q.defer();
+
+ $window.plugin.printer.isAvailable(function (isAvailable) {
+ q.resolve(isAvailable);
+ });
+
+ return q.promise;
+ },
+
+ print: function (doc, options) {
+ var q = $q.defer();
+ $window.plugin.printer.print(doc, options, function () {
+ q.resolve();
+ });
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.pbernasconi.progressindicator
+// link : http://pbernasconi.github.io/cordova-progressIndicator/
+
+angular.module('ngCordova.plugins.progressIndicator', [])
+
+ .factory('$cordovaProgress', ['$q', function ($q) {
+
+ return {
+ show: function(_message) {
+ var message = _message || "Please wait...";
+ return ProgressIndicator.show(message);
+ },
+
+ showSimple: function (_dim) {
+ var dim = _dim || false;
+ return ProgressIndicator.showSimple(dim);
+ },
+
+ showSimpleWithLabel: function (_dim, _label) {
+ var dim = _dim || false;
+ var label = _label || "Loading...";
+ return ProgressIndicator.showSimpleWithLabel(dim, label);
+ },
+
+ showSimpleWithLabelDetail: function (_dim, _label, _detail) {
+ var dim = _dim || false;
+ var label = _label || "Loading...";
+ var detail = _detail || "Please wait";
+ return ProgressIndicator.showSimpleWithLabelDetail(dim, label, detail);
+ },
+
+ showDeterminate: function (_dim, _timeout) {
+ var dim = _dim || false;
+ var timeout = _timeout || 50000;
+ return ProgressIndicator.showDeterminate(dim, timeout);
+ },
+
+ showDeterminateWithLabel: function (_dim, _timeout, _label) {
+ var dim = _dim || false;
+ var timeout = _timeout || 50000;
+ var label = _label || "Loading...";
+
+ return ProgressIndicator.showDeterminateWithLabel(dim, timeout, label);
+ },
+
+ showAnnular: function (_dim, _timeout) {
+ var dim = _dim || false;
+ var timeout = _timeout || 50000;
+ return ProgressIndicator.showAnnular(dim, timeout);
+ },
+
+ showAnnularWithLabel: function (_dim, _timeout, _label) {
+ var dim = _dim || false;
+ var timeout = _timeout || 50000;
+ var label = _label || "Loading...";
+ return ProgressIndicator.showAnnularWithLabel(dim, timeout, label);
+ },
+
+ showBar: function (_dim, _timeout) {
+ var dim = _dim || false;
+ var timeout = _timeout || 50000;
+ return ProgressIndicator.showBar(dim, timeout);
+ },
+
+ showBarWithLabel: function (_dim, _timeout, _label) {
+ var dim = _dim || false;
+ var timeout = _timeout || 50000;
+ var label = _label || "Loading...";
+ return ProgressIndicator.showBarWithLabel(dim, timeout, label);
+ },
+
+ showSuccess: function (_dim, _label) {
+ var dim = _dim || false;
+ var label = _label || "Success";
+ return ProgressIndicator.showSuccess(dim, label);
+ },
+
+ showText: function (_dim, _text, _position) {
+ var dim = _dim || false;
+ var text = _text || "Warning";
+ var position = _position || "center";
+ return ProgressIndicator.showText(dim, text, position);
+ },
+
+ hide: function () {
+ return ProgressIndicator.hide();
+ }
+ };
+
+ }]);
+
+// install : cordova plugin add https://github.com/phonegap-build/PushPlugin.git
+// link : https://github.com/phonegap-build/PushPlugin
+
+angular.module('ngCordova.plugins.push', [])
+
+ .factory('$cordovaPush', ['$q', '$window', '$rootScope', '$timeout', function ($q, $window, $rootScope, $timeout) {
+ return {
+ onNotification: function (notification) {
+ $timeout(function () {
+ $rootScope.$broadcast('$cordovaPush:notificationReceived', notification);
+ });
+ },
+
+ register: function (config) {
+ var q = $q.defer();
+ var injector;
+ if (config !== undefined && config.ecb === undefined) {
+ if (document.querySelector('[ng-app]') == null) {
+ injector = "document.body";
+ }
+ else {
+ injector = "document.querySelector('[ng-app]')";
+ }
+ config.ecb = "angular.element(" + injector + ").injector().get('$cordovaPush').onNotification";
+ }
+
+ $window.plugins.pushNotification.register(function (token) {
+ q.resolve(token);
+ }, function (error) {
+ q.reject(error);
+ }, config);
+
+ return q.promise;
+ },
+
+ unregister: function (options) {
+ var q = $q.defer();
+ $window.plugins.pushNotification.unregister(function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ }, options);
+
+ return q.promise;
+ },
+
+ // iOS only
+ setBadgeNumber: function (number) {
+ var q = $q.defer();
+ $window.plugins.pushNotification.setApplicationIconBadgeNumber(function (result) {
+ q.resolve(result);
+ }, function (error) {
+ q.reject(error);
+ }, number);
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/cordova-sms/cordova-sms-plugin.git
+// link : https://github.com/cordova-sms/cordova-sms-plugin
+
+angular.module('ngCordova.plugins.sms', [])
+
+ .factory('$cordovaSms', ['$q', function ($q) {
+
+ return {
+ send: function (number, message, options) {
+ var q = $q.defer();
+ sms.send(number, message, options, function (res) {
+ q.resolve(res);
+ }, function (err) {
+ q.reject(err);
+ });
+ return q.promise;
+ }
+ };
+
+ }]);
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git
+// link : https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin
+
+// NOTE: shareViaEmail -> if user cancels sharing email, success is still called
+// TODO: add support for iPad
+
+angular.module('ngCordova.plugins.socialSharing', [])
+
+ .factory('$cordovaSocialSharing', ['$q', '$window', function ($q, $window) {
+
+ return {
+ share: function (message, subject, file, link) {
+ var q = $q.defer();
+ subject = subject || null;
+ file = file || null;
+ link = link || null;
+ $window.plugins.socialsharing.share(message, subject, file, link, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareViaTwitter: function (message, file, link) {
+ var q = $q.defer();
+ file = file || null;
+ link = link || null;
+ $window.plugins.socialsharing.shareViaTwitter(message, file, link, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareViaWhatsApp: function (message, file, link) {
+ var q = $q.defer();
+ file = file || null;
+ link = link || null;
+ $window.plugins.socialsharing.shareViaWhatsApp(message, file, link, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareViaFacebook: function (message, file, link) {
+ var q = $q.defer();
+ message = message || null;
+ file = file || null;
+ link = link || null;
+ $window.plugins.socialsharing.shareViaFacebook(message, file, link, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareViaFacebookWithPasteMessageHint: function (message, file, link, pasteMessageHint) {
+ var q = $q.defer();
+ file = file || null;
+ link = link || null;
+ $window.plugins.socialsharing.shareViaFacebookWithPasteMessageHint(message, file, link, pasteMessageHint, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareViaSMS: function (message, commaSeparatedPhoneNumbers) {
+ var q = $q.defer();
+ $window.plugins.socialsharing.shareViaSMS(message, commaSeparatedPhoneNumbers, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareViaEmail: function (message, subject, toArr, ccArr, bccArr, fileArr) {
+ var q = $q.defer();
+ toArr = toArr || null;
+ ccArr = ccArr || null;
+ bccArr = bccArr || null;
+ fileArr = fileArr || null;
+ $window.plugins.socialsharing.shareViaEmail(message, subject, toArr, ccArr, bccArr, fileArr, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ shareVia: function (via, message, subject, file, link) {
+ var q = $q.defer();
+ message = message || null;
+ subject = subject || null;
+ file = file || null;
+ link = link || null;
+ $window.plugins.socialsharing.shareVia(via, message, subject, file, link, function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ canShareViaEmail: function () {
+ var q = $q.defer();
+ $window.plugins.socialsharing.canShareViaEmail(function () {
+ q.resolve(true);
+ }, function () {
+ q.reject(false);
+ });
+ return q.promise;
+ },
+
+ canShareVia: function (via, message, subject, file, link) {
+ var q = $q.defer();
+ $window.plugins.socialsharing.canShareVia(via, message, subject, file, link, function (success) {
+ q.resolve(success);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ available: function () {
+ var q = $q.defer();
+ window.plugins.socialsharing.available(function (isAvailable) {
+ if (isAvailable) {
+ q.resolve();
+ }
+ else {
+ q.reject();
+ }
+ });
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/Paldom/SpinnerDialog.git
+// link : https://github.com/Paldom/SpinnerDialog
+
+angular.module('ngCordova.plugins.spinnerDialog', [])
+
+ .factory('$cordovaSpinnerDialog', ['$window', function ($window) {
+
+ return {
+ show: function (title, message, fixed) {
+ fixed = fixed || false;
+ return $window.plugins.spinnerDialog.show(title, message, fixed);
+ },
+ hide: function () {
+ return $window.plugins.spinnerDialog.hide();
+ }
+ };
+
+ }]);
+
+// install : cordova plugin add org.apache.cordova.splashscreen
+// link : https://github.com/apache/cordova-plugin-splashscreen/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.splashscreen', [])
+
+ .factory('$cordovaSplashscreen', [function () {
+
+ return {
+ hide: function () {
+ return navigator.splashscreen.hide();
+ },
+
+ show: function () {
+ return navigator.splashscreen.show();
+ }
+ };
+
+ }]);
+
+// install : cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin.git
+// link : https://github.com/brodysoft/Cordova-SQLitePlugin/blob/master/README.md
+
+angular.module('ngCordova.plugins.sqlite', [])
+
+ .factory('$cordovaSQLite', ['$q', '$window', function ($q, $window) {
+
+ return {
+ openDB: function (dbName, background) {
+
+ if (typeof background === 'undefined') {
+ background = 0;
+ }
+
+ return $window.sqlitePlugin.openDatabase({
+ name: dbName,
+ bgType: background
+ });
+ },
+
+ execute: function (db, query, binding) {
+ var q = $q.defer();
+ db.transaction(function (tx) {
+ tx.executeSql(query, binding, function (tx, result) {
+ q.resolve(result);
+ },
+ function (transaction, error) {
+ q.reject(error);
+ });
+ });
+ return q.promise;
+ },
+
+ insertCollection: function (db, query, bindings) {
+ var q = $q.defer();
+ var coll = bindings.slice(0); // clone collection
+
+ db.transaction(function (tx) {
+ (function insertOne() {
+ var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one
+ try {
+ tx.executeSql(query, record, function (tx, result) {
+ if (coll.length === 0) {
+ q.resolve(result);
+ } else {
+ insertOne();
+ }
+ }, function (transaction, error) {
+ q.reject(error);
+ return;
+ });
+ } catch (exception) {
+ q.reject(exception);
+ }
+ })();
+ });
+ return q.promise;
+ },
+
+ nestedExecute: function (db, query1, query2, binding1, binding2) {
+ var q = $q.defer();
+
+ db.transaction(function (tx) {
+ tx.executeSql(query1, binding1, function (tx, result) {
+ q.resolve(result);
+ tx.executeSql(query2, binding2, function (tx, res) {
+ q.resolve(res);
+ });
+ });
+ },
+ function (transaction, error) {
+ q.reject(error);
+ });
+
+ return q.promise;
+ },
+
+ deleteDB: function (dbName) {
+ var q = $q.defer();
+
+ $window.sqlitePlugin.deleteDatabase(dbName, function (success) {
+ q.resolve(success);
+ }, function (error) {
+ q.reject(error);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.statusbar
+// link : https://github.com/apache/cordova-plugin-statusbar/
+
+angular.module('ngCordova.plugins.statusbar', [])
+
+ .factory('$cordovaStatusbar', [function () {
+
+ return {
+ overlaysWebView: function (bool) {
+ return StatusBar.overlaysWebView(!!bool);
+ },
+
+ style: function (style) {
+ switch (style) {
+ // Default
+ case 0:
+ return StatusBar.styleDefault();
+
+ // LightContent
+ case 1:
+ return StatusBar.styleLightContent();
+
+ // BlackTranslucent
+ case 2:
+ return StatusBar.styleBlackTranslucent();
+
+ // BlackOpaque
+ case 3:
+ return StatusBar.styleBlackOpaque();
+
+ default:
+ return StatusBar.styleDefault();
+ }
+ },
+
+ // supported names:
+ // black, darkGray, lightGray, white, gray, red, green,
+ // blue, cyan, yellow, magenta, orange, purple, brown
+ styleColor: function (color) {
+ return StatusBar.backgroundColorByName(color);
+ },
+
+ styleHex: function (colorHex) {
+ return StatusBar.backgroundColorByHexString(colorHex);
+ },
+
+ hide: function () {
+ return StatusBar.hide();
+ },
+
+ show: function () {
+ return StatusBar.show();
+ },
+
+ isVisible: function () {
+ return StatusBar.isVisible;
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin.git
+// link : https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin
+
+angular.module('ngCordova.plugins.toast', [])
+
+ .factory('$cordovaToast', ['$q', '$window', function ($q, $window) {
+
+ return {
+ showShortTop: function (message) {
+ var q = $q.defer();
+ $window.plugins.toast.showShortTop(message, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ showShortCenter: function (message) {
+ var q = $q.defer();
+ $window.plugins.toast.showShortCenter(message, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ showShortBottom: function (message) {
+ var q = $q.defer();
+ $window.plugins.toast.showShortBottom(message, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ showLongTop: function (message) {
+ var q = $q.defer();
+ $window.plugins.toast.showLongTop(message, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ showLongCenter: function (message) {
+ var q = $q.defer();
+ $window.plugins.toast.showLongCenter(message, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+ showLongBottom: function (message) {
+ var q = $q.defer();
+ $window.plugins.toast.showLongBottom(message, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ },
+
+
+ show: function (message, duration, position) {
+ var q = $q.defer();
+ $window.plugins.toast.show(message, duration, position, function (response) {
+ q.resolve(response);
+ }, function (error) {
+ q.reject(error);
+ });
+ return q.promise;
+ }
+ };
+
+ }]);
+
+// install : cordova plugin add https://github.com/leecrossley/cordova-plugin-touchid.git
+// link : https://github.com/leecrossley/cordova-plugin-touchid
+
+angular.module('ngCordova.plugins.touchid', [])
+
+ .factory('$cordovaTouchID', ['$q', function ($q) {
+
+ return {
+ checkSupport: function () {
+ var defer = $q.defer();
+ if (!window.cordova) {
+ defer.reject("Not supported without cordova.js");
+ } else {
+ touchid.checkSupport(function (value) {
+ defer.resolve(value);
+ }, function (err) {
+ defer.reject(err);
+ });
+ }
+
+ return defer.promise;
+ },
+
+ authenticate: function (auth_reason_text) {
+ var defer = $q.defer();
+ if (!window.cordova) {
+ defer.reject("Not supported without cordova.js");
+ } else {
+ touchid.authenticate(function (value) {
+ defer.resolve(value);
+ }, function (err) {
+ defer.reject(err);
+ }, auth_reason_text);
+ }
+
+ return defer.promise;
+ }
+ };
+ }]);
+
+// install : cordova plugin add org.apache.cordova.vibration
+// link : https://github.com/apache/cordova-plugin-vibration/blob/master/doc/index.md
+
+angular.module('ngCordova.plugins.vibration', [])
+
+ .factory('$cordovaVibration', [function () {
+
+ return {
+ vibrate: function (times) {
+ return navigator.notification.vibrate(times);
+ },
+ vibrateWithPattern: function (pattern, repeat) {
+ return navigator.notification.vibrateWithPattern(pattern, repeat);
+ },
+ cancelVibration: function () {
+ return navigator.notification.cancelVibration();
+ }
+ };
+ }]);
+
+// install : cordova plugin add https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin.git
+// link : https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin
+
+angular.module('ngCordova.plugins.videoCapturePlus', [])
+
+ .provider('$cordovaVideoCapturePlus', [function () {
+
+ var defaultOptions = {};
+
+
+ /**
+ * the nr of videos to record, default 1 (on iOS always 1)
+ *
+ * @param limit
+ */
+ this.setLimit = function setLimit(limit) {
+ defaultOptions.limit = limit;
+ };
+
+
+ /**
+ * max duration in seconds, default 0, which is 'forever'
+ *
+ * @param seconds
+ */
+ this.setMaxDuration = function setMaxDuration(seconds) {
+ defaultOptions.duration = seconds;
+ };
+
+
+ /**
+ * set to true to override the default low quality setting
+ *
+ * @param {Boolean} highquality
+ */
+ this.setHighQuality = function setHighQuality(highquality) {
+ defaultOptions.highquality = highquality;
+ };
+
+ /**
+ * you'll want to sniff the user-Agent/device and pass the best overlay based on that..
+ * set to true to override the default backfacing camera setting. iOS: works fine, Android: YMMV (#18)
+ *
+ * @param {Boolean} frontcamera
+ */
+ this.useFrontCamera = function useFrontCamera(frontcamera) {
+ defaultOptions.frontcamera = frontcamera;
+ };
+
+
+ /**
+ * put the png in your www folder
+ *
+ * @param {String} imageUrl
+ */
+ this.setPortraitOverlay = function setPortraitOverlay(imageUrl) {
+ defaultOptions.portraitOverlay = imageUrl;
+ };
+
+
+ /**
+ *
+ * @param {String} imageUrl
+ */
+ this.setLandscapeOverlay = function setLandscapeOverlay(imageUrl) {
+ defaultOptions.landscapeOverlay = imageUrl;
+ };
+
+
+ /**
+ * iOS only
+ *
+ * @param text
+ */
+ this.setOverlayText = function setOverlayText(text) {
+ defaultOptions.overlayText = text;
+ };
+
+
+ this.$get = ['$q', '$window', function ($q, $window) {
+ return {
+ captureVideo: function (options) {
+ var q = $q.defer();
+
+ if (!$window.plugins.videocaptureplus) {
+ q.resolve(null);
+ return q.promise;
+ }
+
+ $window.plugins.videocaptureplus.captureVideo(q.resolve, q.reject,
+ angular.extend({}, defaultOptions, options));
+
+ return q.promise;
+ }
+ };
+ }];
+ }]);
+
+// install : cordova plugin add https://github.com/MobileChromeApps/zip.git
+// link : https://github.com/MobileChromeApps/zip
+
+angular.module('ngCordova.plugins.zip', [])
+
+ .factory('$cordovaZip', ['$q', '$window', function ($q, $window) {
+
+ return {
+ unzip: function (source, destination) {
+ var q = $q.defer();
+
+ $window.zip.unzip(source, destination, function (isError) {
+ if (isError === 0) {
+ q.resolve();
+ } else {
+ q.reject();
+ }
+ }, function (progressEvent) {
+ q.notify(progressEvent);
+ });
+
+ return q.promise;
+ }
+ };
+ }]);
+
+})();
diff --git a/www/lib/ngCordova/dist/ng-cordova.min.js b/www/lib/ngCordova/dist/ng-cordova.min.js
new file mode 100644
index 00000000..9c372655
--- /dev/null
+++ b/www/lib/ngCordova/dist/ng-cordova.min.js
@@ -0,0 +1,9 @@
+/*!
+ * ngCordova
+ * v0.1.15-alpha
+ * Copyright 2014 Drifty Co. http://drifty.com/
+ * See LICENSE in this repository for license information
+ */
+!function(){angular.module("ngCordova",["ngCordova.plugins"]),angular.module("ngCordova.plugins.actionSheet",[]).factory("$cordovaActionSheet",["$q","$window",function(e,n){return{show:function(t){var r=e.defer();return n.plugins.actionsheet.show(t,function(e){r.resolve(e)}),r.promise},hide:function(){return n.plugins.actionsheet.hide()}}}]),angular.module("ngCordova.plugins.adMob",[]).factory("$cordovaAdMob",["$q","$window",function(e,n){return{createBannerView:function(t){var r=e.defer();return n.plugins.AdMob.createBannerView(t,function(){r.resolve()},function(){r.reject()}),r.promise},createInterstitialView:function(t){var r=e.defer();return n.plugins.AdMob.createInterstitialView(t,function(){r.resolve()},function(){r.reject()}),r.promise},requestAd:function(t){var r=e.defer();return n.plugins.AdMob.requestAd(t,function(){r.resolve()},function(){r.reject()}),r.promise},showAd:function(t){var r=e.defer();return n.plugins.AdMob.showAd(t,function(){r.resolve()},function(){r.reject()}),r.promise},requestInterstitialAd:function(t){var r=e.defer();return n.plugins.AdMob.requestInterstitialAd(t,function(){r.resolve()},function(){r.reject()}),r.promise}}}]),angular.module("ngCordova.plugins.appAvailability",[]).factory("$cordovaAppAvailability",["$q",function(e){return{check:function(n){var t=e.defer();return appAvailability.check(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise}}}]),angular.module("ngCordova.plugins.appRate",[]).provider("$cordovaAppRate",[function(){this.setPreferences=function(e){e&&angular.isObject(e)&&(AppRate.preferences.useLanguage=e.language||null,AppRate.preferences.displayAppName=e.appName||"",AppRate.preferences.promptAgainForEachNewVersion=e.promptForNewVersion||!0,AppRate.preferences.openStoreInApp=e.openStoreInApp||!1,AppRate.preferences.usesUntilPrompt=e.usesUntilPrompt||3,AppRate.preferences.useCustomRateDialog=e.useCustomRateDialog||!1,AppRate.preferences.storeAppURL.ios=e.iosURL||null,AppRate.preferences.storeAppURL.android=e.androidURL||null,AppRate.preferences.storeAppURL.blackberry=e.blackberryURL||null,AppRate.preferences.storeAppURL.windows8=e.windowsURL||null)},this.setCustomLocale=function(e){var n={title:"Rate %@",message:"If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!",cancelButtonLabel:"No, Thanks",laterButtonLabel:"Remind Me Later",rateButtonLabel:"Rate It Now"};n=angular.extend(n,e),AppRate.preferences.customLocale=n},this.$get=["$q",function(e){return{promptForRating:function(n){var t=e.defer(),r=AppRate.promptForRating(n);return t.resolve(r),t.promise},navigateToAppStore:function(){var n=e.defer(),t=AppRate.navigateToAppStore();return n.resolve(t),n.promise},onButtonClicked:function(e){AppRate.onButtonClicked=function(n){e.call(this,n)}},onRateDialogShow:function(e){AppRate.onRateDialogShow=e()}}}]}]),angular.module("ngCordova.plugins.appVersion",[]).factory("$cordovaAppVersion",["$q",function(e){return{getAppVersion:function(){var n=e.defer();return cordova.getAppVersion(function(e){n.resolve(e)}),n.promise}}}]),angular.module("ngCordova.plugins.backgroundGeolocation",[]).factory("$cordovaBackgroundGeolocation",["$q","$window",function(e,n){return{init:function(){n.navigator.geolocation.getCurrentPosition(function(e){return e})},configure:function(t){this.init();var r=e.defer();return n.plugins.backgroundGeoLocation.configure(function(e){r.notify(e),n.plugins.backgroundGeoLocation.finish()},function(e){r.reject(e)},t),this.start(),r.promise},start:function(){var t=e.defer();return n.plugins.backgroundGeoLocation.start(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},stop:function(){var t=e.defer();return n.plugins.backgroundGeoLocation.stop(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise}}}]),angular.module("ngCordova.plugins.badge",[]).factory("$cordovaBadge",["$q",function(e){return{hasPermission:function(){var n=e.defer();return cordova.plugins.notification.badge.hasPermission(function(e){e?n.resolve(!0):n.reject("You do not have permission")}),n.promise},promptForPermission:function(){return cordova.plugins.notification.badge.promptForPermission()},set:function(n){var t=e.defer();return cordova.plugins.notification.badge.hasPermission(function(e){e?t.resolve(cordova.plugins.notification.badge.set(n)):t.reject("You do not have permission to set Badge")}),t.promise},get:function(){var n=e.defer();return cordova.plugins.notification.badge.hasPermission(function(e){e?cordova.plugins.notification.badge.get(function(e){n.resolve(e)}):n.reject("You do not have permission to get Badge")}),n.promise},clear:function(){var n=e.defer();return cordova.plugins.notification.badge.hasPermission(function(e){e?n.resolve(cordova.plugins.notification.badge.clear()):n.reject("You do not have permission to clear Badge")}),n.promise},configure:function(e){return cordova.plugins.notification.badge.configure(e)}}}]),angular.module("ngCordova.plugins.barcodeScanner",[]).factory("$cordovaBarcodeScanner",["$q",function(e){return{scan:function(n){var t=e.defer();return cordova.plugins.barcodeScanner.scan(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise},encode:function(n,t){var r=e.defer();return n=n||"TEXT_TYPE",cordova.plugins.barcodeScanner.encode(n,t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise}}}]),angular.module("ngCordova.plugins.batteryStatus",[]).factory("$cordovaBatteryStatus",["$rootScope","$window","$timeout",function(e,n,t){var r=function(n){t(function(){e.$broadcast("$cordovaBatteryStatus:status",n)})},o=function(n){t(function(){e.$broadcast("$cordovaBatteryStatus:critical",n)})},i=function(n){t(function(){e.$broadcast("$cordovaBatteryStatus:low",n)})};return document.addEventListener("deviceready",function(){navigator.battery&&(n.addEventListener("batterystatus",r,!1),n.addEventListener("batterycritical",o,!1),n.addEventListener("batterylow",i,!1))},!1),!0}]).run(["$cordovaBatteryStatus",function(){}]),angular.module("ngCordova.plugins.ble",[]).factory("$cordovaBLE",["$q",function(e){return{scan:function(n,t){var r=e.defer();return ble.scan(n,t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},connect:function(n){var t=e.defer();return ble.connect(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},disconnect:function(n){var t=e.defer();return ble.disconnect(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},read:function(n,t,r){var o=e.defer();return ble.read(n,t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},write:function(n,t,r,o){var i=e.defer();return ble.write(n,t,r,o,function(e){i.resolve(e)},function(e){i.reject(e)}),i.promise},writeCommand:function(n,t,r,o){var i=e.defer();return ble.writeCommand(n,t,r,o,function(e){i.resolve(e)},function(e){i.reject(e)}),i.promise},notify:function(n,t,r){var o=e.defer();return ble.notify(n,t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},indicate:function(n,t,r){var o=e.defer();return ble.indicate(n,t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},isConnected:function(n){var t=e.defer();return ble.isConnected(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},isEnabled:function(){var n=e.defer();return ble.isEnabled(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise}}}]),angular.module("ngCordova.plugins.bluetoothSerial",[]).factory("$cordovaBluetoothSerial",["$q","$window",function(e,n){return{connect:function(t){var r=e.defer();return n.bluetoothSerial.connect(t,function(){r.resolve()},function(e){r.reject(e)}),r.promise},connectInsecure:function(t){var r=e.defer();return n.bluetoothSerial.connectInsecure(t,function(){r.resolve()},function(e){r.reject(e)}),r.promise},disconnect:function(){var t=e.defer();return n.bluetoothSerial.disconnect(function(){t.resolve()},function(e){t.reject(e)}),t.promise},list:function(){var t=e.defer();return n.bluetoothSerial.list(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},discoverUnpaired:function(){var t=e.defer();return n.bluetoothSerial.discoverUnpaired(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},setDeviceDiscoveredListener:function(){var t=e.defer();return n.bluetoothSerial.setDeviceDiscoveredListener(function(e){t.notify(e)}),t.promise},clearDeviceDiscoveredListener:function(){n.bluetoothSerial.clearDeviceDiscoveredListener()},showBluetoothSettings:function(){var t=e.defer();return n.bluetoothSerial.showBluetoothSettings(function(){t.resolve()},function(e){t.reject(e)}),t.promise},isEnabled:function(){var t=e.defer();return n.bluetoothSerial.isEnabled(function(){t.resolve()},function(){t.reject()}),t.promise},enable:function(){var t=e.defer();return n.bluetoothSerial.enable(function(){t.resolve()},function(){t.reject()}),t.promise},isConnected:function(){var t=e.defer();return n.bluetoothSerial.isConnected(function(){t.resolve()},function(){t.reject()}),t.promise},available:function(){var t=e.defer();return n.bluetoothSerial.available(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},read:function(){var t=e.defer();return n.bluetoothSerial.read(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},readUntil:function(t){var r=e.defer();return n.bluetoothSerial.readUntil(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},write:function(t){var r=e.defer();return n.bluetoothSerial.write(t,function(){r.resolve()},function(e){r.reject(e)}),r.promise},subscribe:function(t){var r=e.defer();return n.bluetoothSerial.subscribe(t,function(e){r.notify(e)},function(e){r.reject(e)}),r.promise},subscribeRawData:function(){var t=e.defer();return n.bluetoothSerial.subscribeRawData(function(e){t.notify(e)},function(e){t.reject(e)}),t.promise},unsubscribe:function(){var t=e.defer();return n.bluetoothSerial.unsubscribe(function(){t.resolve()},function(e){t.reject(e)}),t.promise},unsubscribeRawData:function(){var t=e.defer();return n.bluetoothSerial.unsubscribeRawData(function(){t.resolve()},function(e){t.reject(e)}),t.promise},clear:function(){var t=e.defer();return n.bluetoothSerial.clear(function(){t.resolve()},function(e){t.reject(e)}),t.promise},readRSSI:function(){var t=e.defer();return n.bluetoothSerial.readRSSI(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise}}}]),angular.module("ngCordova.plugins.brightness",[]).factory("$cordovaBrightness",["$q","$window",function(e,n){return{get:function(){var t=e.defer();return n.cordova.plugins.brightness.getBrightness(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},set:function(t){var r=e.defer();return n.cordova.plugins.brightness.setBrightness(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},setKeepScreenOn:function(t){var r=e.defer();return n.cordova.plugins.brightness.setKeepScreenOn(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise}}}]),angular.module("ngCordova.plugins.calendar",[]).factory("$cordovaCalendar",["$q","$window",function(e,n){return{createCalendar:function(t){var r=e.defer(),o=n.plugins.calendar.getCreateCalendarOptions();return"string"==typeof t?o.calendarName=t:o=angular.extend(o,t),n.plugins.calendar.createCalendar(o,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},deleteCalendar:function(t){var r=e.defer();return n.plugins.calendar.deleteCalendar(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},createEvent:function(t){var r=e.defer(),o={title:null,location:null,notes:null,startDate:null,endDate:null};return o=angular.extend(o,t),n.plugins.calendar.createEvent(o.title,o.location,o.notes,new Date(o.startDate),new Date(o.endDate),function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},createEventWithOptions:function(t){var r=e.defer(),o=[],i=window.plugins.calendar.getCalendarOptions(),a={title:null,location:null,notes:null,startDate:null,endDate:null};o=Object.keys(a);for(var c in t)-1===o.indexOf(c)?i[c]=t[c]:a[c]=t[c];return n.plugins.calendar.createEventWithOptions(a.title,a.location,a.notes,new Date(a.startDate),new Date(a.endDate),i,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},createEventInteractively:function(t){var r=e.defer(),o={title:null,location:null,notes:null,startDate:null,endDate:null};return o=angular.extend(o,t),n.plugins.calendar.createEventInteractively(o.title,o.location,o.notes,new Date(o.startDate),new Date(o.endDate),function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},createEventInNamedCalendar:function(t){var r=e.defer(),o={title:null,location:null,notes:null,startDate:null,endDate:null,calendarName:null};return o=angular.extend(o,t),n.plugins.calendar.createEventInNamedCalendar(o.title,o.location,o.notes,new Date(o.startDate),new Date(o.endDate),o.calendarName,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},findEvent:function(t){var r=e.defer(),o={title:null,location:null,notes:null,startDate:null,endDate:null};return o=angular.extend(o,t),n.plugins.calendar.findEvent(o.title,o.location,o.notes,new Date(o.startDate),new Date(o.endDate),function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},listEventsInRange:function(t,r){var o=e.defer();return n.plugins.calendar.listEventsInRange(t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},listCalendars:function(){var t=e.defer();return n.plugins.calendar.listCalendars(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},findAllEventsInNamedCalendar:function(t){var r=e.defer();return n.plugins.calendar.findAllEventsInNamedCalendar(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},modifyEvent:function(t){var r=e.defer(),o={title:null,location:null,notes:null,startDate:null,endDate:null,newTitle:null,newLocation:null,newNotes:null,newStartDate:null,newEndDate:null};return o=angular.extend(o,t),n.plugins.calendar.modifyEvent(o.title,o.location,o.notes,new Date(o.startDate),new Date(o.endDate),o.newTitle,o.newLocation,o.newNotes,new Date(o.newStartDate),new Date(o.newEndDate),function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},deleteEvent:function(t){var r=e.defer(),o={newTitle:null,location:null,notes:null,startDate:null,endDate:null};return o=angular.extend(o,t),n.plugins.calendar.deleteEvent(o.newTitle,o.location,o.notes,new Date(o.startDate),new Date(o.endDate),function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise}}}]),angular.module("ngCordova.plugins.camera",[]).factory("$cordovaCamera",["$q",function(e){return{getPicture:function(n){var t=e.defer();return navigator.camera?(navigator.camera.getPicture(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise):(t.resolve(null),t.promise)},cleanup:function(){var n=e.defer();return navigator.camera.cleanup(function(){n.resolve()},function(e){n.reject(e)}),n.promise}}}]),angular.module("ngCordova.plugins.capture",[]).factory("$cordovaCapture",["$q",function(e){return{captureAudio:function(n){var t=e.defer();return navigator.device.capture?(navigator.device.capture.captureAudio(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise):(t.resolve(null),t.promise)},captureImage:function(n){var t=e.defer();return navigator.device.capture?(navigator.device.capture.captureImage(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise):(t.resolve(null),t.promise)},captureVideo:function(n){var t=e.defer();return navigator.device.capture?(navigator.device.capture.captureVideo(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise):(t.resolve(null),t.promise)}}}]),angular.module("ngCordova.plugins.clipboard",[]).factory("$cordovaClipboard",["$q","$window",function(e,n){return{copy:function(t){var r=e.defer();return n.cordova.plugins.clipboard.copy(t,function(){r.resolve()},function(){r.reject()}),r.promise},paste:function(){var t=e.defer();return n.cordova.plugins.clipboard.paste(function(e){t.resolve(e)},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.contacts",[]).factory("$cordovaContacts",["$q",function(e){return{save:function(n){var t=e.defer(),r=navigator.contacts.create(n);return r.save(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},remove:function(n){var t=e.defer(),r=navigator.contacts.create(n);return r.remove(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},clone:function(e){var n=navigator.contacts.create(e);return n.clone(e)},find:function(n){var t=e.defer(),r=n.fields||["id","displayName"];return delete n.fields,navigator.contacts.find(r,function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise},pickContact:function(){var n=e.defer();return navigator.contacts.pickContact(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise}}}]),angular.module("ngCordova.plugins.datePicker",[]).factory("$cordovaDatePicker",["$window","$q",function(e,n){return{show:function(t){var r=n.defer();return t=t||{date:new Date,mode:"date"},e.datePicker.show(t,function(e){r.resolve(e)}),r.promise}}}]),angular.module("ngCordova.plugins.device",[]).factory("$cordovaDevice",[function(){return{getDevice:function(){return device},getCordova:function(){return device.cordova},getModel:function(){return device.model},getName:function(){return device.name},getPlatform:function(){return device.platform},getUUID:function(){return device.uuid},getVersion:function(){return device.version}}}]),angular.module("ngCordova.plugins.deviceMotion",[]).factory("$cordovaDeviceMotion",["$q",function(e){return{getCurrentAcceleration:function(){var n=e.defer();return navigator.accelerometer.getCurrentAcceleration(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},watchAcceleration:function(n){var t=e.defer(),r=navigator.accelerometer.watchAcceleration(function(e){t.notify(e)},function(e){t.reject(e)},n);return t.promise.cancel=function(){navigator.accelerometer.clearWatch(r)},t.promise.clearWatch=function(e){navigator.accelerometer.clearWatch(e||r)},t.promise.watchID=r,t.promise},clearWatch:function(e){return navigator.accelerometer.clearWatch(e)}}}]),angular.module("ngCordova.plugins.deviceOrientation",[]).factory("$cordovaDeviceOrientation",["$q",function(e){return{getCurrentHeading:function(){var n=e.defer();return navigator.compass.getCurrentHeading(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},watchHeading:function(n){var t=e.defer(),r=navigator.compass.watchHeading(function(e){t.notify(e)},function(e){t.reject(e)},n);return t.promise.cancel=function(){navigator.compass.clearWatch(r)},t.promise.clearWatch=function(e){navigator.compass.clearWatch(e||r)},t.promise.watchID=r,t.promise},clearWatch:function(e){return navigator.compass.clearWatch(e)}}}]),angular.module("ngCordova.plugins.dialogs",[]).factory("$cordovaDialogs",["$q","$window",function(e,n){return{alert:function(t,r,o){var i=e.defer();return n.navigator.notification?navigator.notification.alert(t,function(){i.resolve()},r,o):(n.alert(t),i.resolve()),i.promise},confirm:function(t,r,o){var i=e.defer();return n.navigator.notification?navigator.notification.confirm(t,function(e){i.resolve(e)},r,o):i.resolve(n.confirm(t)?1:2),i.promise},prompt:function(t,r,o,i){var a=e.defer();if(n.navigator.notification)navigator.notification.prompt(t,function(e){a.resolve(e)},r,o,i);else{var c=n.prompt(t,i);a.resolve(null!==c?{input1:c,buttonIndex:1}:{input1:c,buttonIndex:2})}return a.promise},beep:function(e){return navigator.notification.beep(e)}}}]),angular.module("ngCordova.plugins.emailComposer",[]).factory("$cordovaEmailComposer",["$q",function(e){return{isAvailable:function(){var n=e.defer();return cordova.plugins.email.isAvailable(function(e){e?n.resolve():n.reject()}),n.promise},open:function(n){var t=e.defer();return cordova.plugins.email.open(n,function(){t.reject()}),t.promise},addAlias:function(e,n){cordova.plugins.email.addAlias(e,n)}}}]),angular.module("ngCordova.plugins.facebook",[]).provider("$cordovaFacebook",[function(){this.browserInit=function(e,n){this.appID=e,this.appVersion=n||"v2.0",facebookConnectPlugin.browserInit(this.appID,this.appVersion)},this.$get=["$q",function(e){return{login:function(n){var t=e.defer();return facebookConnectPlugin.login(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},showDialog:function(n){var t=e.defer();return facebookConnectPlugin.showDialog(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},api:function(n,t){var r=e.defer();return facebookConnectPlugin.api(n,t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},getAccessToken:function(){var n=e.defer();return facebookConnectPlugin.getAccessToken(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},getLoginStatus:function(){var n=e.defer();return facebookConnectPlugin.getLoginStatus(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},logout:function(){var n=e.defer();return facebookConnectPlugin.logout(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise}}}]}]),angular.module("ngCordova.plugins.facebookAds",[]).factory("$cordovaFacebookAds",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.FacebookAds.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.FacebookAds.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.FacebookAds.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.FacebookAds.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.FacebookAds.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.FacebookAds.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.FacebookAds.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.FacebookAds.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.file",[]).constant("$cordovaFileError",{1:"NOT_FOUND_ERR",2:"SECURITY_ERR",3:"ABORT_ERR",4:"NOT_READABLE_ERR",5:"ENCODING_ERR",6:"NO_MODIFICATION_ALLOWED_ERR",7:"INVALID_STATE_ERR",8:"SYNTAX_ERR",9:"INVALID_MODIFICATION_ERR",10:"QUOTA_EXCEEDED_ERR",11:"TYPE_MISMATCH_ERR",12:"PATH_EXISTS_ERR"}).provider("$cordovaFile",[function(){this.$get=["$q","$window","$cordovaFileError",function(e,n,t){return{getFreeDiskSpace:function(){var n=e.defer();return cordova.exec(function(e){n.resolve(e)},function(e){n.reject(e)},"File","getFreeDiskSpace",[]),n.promise},checkDir:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("directory cannot start with /");try{var a=r+o;n.resolveLocalFileSystemURL(a,function(e){e.isDirectory===!0?i.resolve(e):i.reject({code:13,message:"input is not a directory"})},function(e){e.message=t[e.code],i.reject(e)})}catch(c){c.message=t[c.code],i.reject(c)}return i.promise},checkFile:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("directory cannot start with /");try{var a=r+o;n.resolveLocalFileSystemURL(a,function(e){e.isFile===!0?i.resolve(e):i.reject({code:13,message:"input is not a file"})},function(e){e.message=t[e.code],i.reject(e)})}catch(c){c.message=t[c.code],i.reject(c)}return i.promise},createDir:function(r,o,i){var a=e.defer();/^\//.test(o)&&a.reject("directory cannot start with /"),i=i?!1:!0;var c={create:!0,exclusive:i};try{n.resolveLocalFileSystemURL(r,function(e){e.getDirectory(o,c,function(e){a.resolve(e)},function(e){e.message=t[e.code],a.reject(e)})},function(e){e.message=t[e.code],a.reject(e)})}catch(u){u.message=t[u.code],a.reject(u)}return a.promise},createFile:function(r,o,i){var a=e.defer();/^\//.test(o)&&a.reject("file-name cannot start with /"),i=i?!1:!0;var c={create:!0,exclusive:i};try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,c,function(e){a.resolve(e)},function(e){e.message=t[e.code],a.reject(e)})},function(e){e.message=t[e.code],a.reject(e)})}catch(u){u.message=t[u.code],a.reject(u)}return a.promise},removeDir:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getDirectory(o,{create:!1},function(e){e.remove(function(){i.resolve({success:!0,fileRemoved:e})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},removeFile:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1},function(e){e.remove(function(){i.resolve({success:!0,fileRemoved:e})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},removeRecursively:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getDirectory(o,{create:!1},function(e){e.removeRecursively(function(){i.resolve({success:!0,fileRemoved:e})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},writeFile:function(r,o,i,a){var c=e.defer();/^\//.test(o)&&c.reject("file-name cannot start with /"),a=a?!1:!0;var u={create:!0,exclusive:a};try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,u,function(e){e.createWriter(function(e){u.append===!0&&e.seek(e.length),u.truncate&&e.truncate(u.truncate),e.onwriteend=function(e){this.error?c.reject(this.error):c.resolve(e)},e.write(i),c.promise.abort=function(){e.abort()}})},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})}catch(s){s.message=t[s.code],c.reject(s)}return c.promise},writeExistingFile:function(r,o,i){var a=e.defer();/^\//.test(o)&&a.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1},function(e){e.createWriter(function(e){e.seek(e.length),e.onwriteend=function(e){this.error?a.reject(this.error):a.resolve(e)},e.write(i),a.promise.abort=function(){e.abort()}})},function(e){e.message=t[e.code],a.reject(e)})},function(e){e.message=t[e.code],a.reject(e)})}catch(c){c.message=t[c.code],a.reject(c)}return a.promise},readAsText:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1},function(e){e.file(function(e){var n=new FileReader;n.onloadend=function(e){void 0!==e.target._result||null!==e.target._result?i.resolve(e.target._result):i.reject(void 0!==e.target._error||null!==e.target._error?e.target._error:{code:null,message:"READER_ONLOADEND_ERR"})},n.readAsText(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},readAsDataURL:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1},function(e){e.file(function(e){var n=new FileReader;n.onloadend=function(e){void 0!==e.target._result||null!==e.target._result?i.resolve(e.target._result):i.reject(void 0!==e.target._error||null!==e.target._error?e.target._error:{code:null,message:"READER_ONLOADEND_ERR"})},n.readAsDataURL(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},readAsBinaryString:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1},function(e){e.file(function(e){var n=new FileReader;n.onloadend=function(e){void 0!==e.target._result||null!==e.target._result?i.resolve(e.target._result):i.reject(void 0!==e.target._error||null!==e.target._error?e.target._error:{code:null,message:"READER_ONLOADEND_ERR"})},n.readAsBinaryString(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},readAsArrayBuffer:function(r,o){var i=e.defer();/^\//.test(o)&&i.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1},function(e){e.file(function(e){var n=new FileReader;n.onloadend=function(e){void 0!==e.target._result||null!==e.target._result?i.resolve(e.target._result):i.reject(void 0!==e.target._error||null!==e.target._error?e.target._error:{code:null,message:"READER_ONLOADEND_ERR"})},n.readAsArrayBuffer(e)})},function(e){e.message=t[e.code],i.reject(e)})},function(e){e.message=t[e.code],i.reject(e)})}catch(a){a.message=t[a.code],i.reject(a)}return i.promise},moveFile:function(t,r,o,i){var a=e.defer();i=i||r,(/^\//.test(r)||/^\//.test(i))&&a.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(t,function(e){e.getFile(r,{create:!1},function(e){n.resolveLocalFileSystemURL(o,function(n){e.moveTo(n,i,function(e){a.resolve(e)},function(e){a.reject(e)})},function(e){a.reject(e)})},function(e){a.reject(e)})},function(e){a.reject(e)})}catch(c){a.reject(c)}return a.promise},moveDir:function(t,r,o,i){var a=e.defer();i=i||r,(/^\//.test(r)||/^\//.test(i))&&a.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(t,function(e){e.getDirectory(r,{create:!1},function(e){n.resolveLocalFileSystemURL(o,function(n){e.moveTo(n,i,function(e){a.resolve(e)},function(e){a.reject(e)})},function(e){a.reject(e)})},function(e){a.reject(e)})},function(e){a.reject(e)})}catch(c){a.reject(c)}return a.promise},copyDir:function(r,o,i,a){var c=e.defer();a=a||o,(/^\//.test(o)||/^\//.test(a))&&c.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getDirectory(o,{create:!1,exclusive:!1},function(e){n.resolveLocalFileSystemURL(i,function(n){e.copyTo(n,a,function(e){c.resolve(e)},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})}catch(u){u.message=t[u.code],c.reject(u)}return c.promise},copyFile:function(r,o,i,a){var c=e.defer();a=a||o,/^\//.test(o)&&c.reject("file-name cannot start with /");try{n.resolveLocalFileSystemURL(r,function(e){e.getFile(o,{create:!1,exclusive:!1},function(e){n.resolveLocalFileSystemURL(i,function(n){e.copyTo(n,a,function(e){c.resolve(e)},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})},function(e){e.message=t[e.code],c.reject(e)})}catch(u){u.message=t[u.code],c.reject(u)}return c.promise}}}]}]),angular.module("ngCordova.plugins.fileOpener2",[]).factory("$cordovaFileOpener2",["$q",function(e){return{open:function(n,t){var r=e.defer();return cordova.plugins.fileOpener2.open(n,t,{error:function(e){r.reject(e)},success:function(){r.resolve()}}),r.promise},uninstall:function(n){var t=e.defer();return cordova.plugins.fileOpener2.uninstall(n,{error:function(e){t.reject(e)},success:function(){t.resolve()}}),t.promise},appIsInstalled:function(n){var t=e.defer();return cordova.plugins.fileOpener2.appIsInstalled(n,{success:function(e){t.resolve(e)}}),t.promise}}}]),angular.module("ngCordova.plugins.fileTransfer",[]).factory("$cordovaFileTransfer",["$q","$timeout",function(e,n){return{download:function(t,r,o,i){var a=e.defer(),c=new FileTransfer,u=o&&o.encodeURI===!1?t:encodeURI(t);return o&&void 0!==o.timeout&&null!==o.timeout&&(n(function(){c.abort()},o.timeout),o.timeout=null),c.onprogress=function(e){a.notify(e)},a.promise.abort=function(){c.abort()},c.download(u,r,a.resolve,a.reject,i,o),a.promise
+},upload:function(t,r,o,i){var a=e.defer(),c=new FileTransfer,u=o&&o.encodeURI===!1?t:encodeURI(t);return o&&void 0!==o.timeout&&null!==o.timeout&&(n(function(){c.abort()},o.timeout),o.timeout=null),c.onprogress=function(e){a.notify(e)},a.promise.abort=function(){c.abort()},c.upload(r,u,a.resolve,a.reject,o,i),a.promise}}}]),angular.module("ngCordova.plugins.flashlight",[]).factory("$cordovaFlashlight",["$q","$window",function(e,n){return{available:function(){var t=e.defer();return n.plugins.flashlight.available(function(e){t.resolve(e)}),t.promise},switchOn:function(){var t=e.defer();return n.plugins.flashlight.switchOn(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},switchOff:function(){var t=e.defer();return n.plugins.flashlight.switchOff(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},toggle:function(){var t=e.defer();return n.plugins.flashlight.toggle(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise}}}]),angular.module("ngCordova.plugins.flurryAds",[]).factory("$cordovaFlurryAds",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.FlurryAds.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.FlurryAds.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.FlurryAds.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.FlurryAds.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.FlurryAds.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.FlurryAds.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.FlurryAds.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.FlurryAds.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.ga",[]).factory("$cordovaGA",["$q","$window",function(e,n){return{init:function(t,r){var o=e.defer();return r=r>=0?r:10,n.plugins.gaPlugin.init(function(e){o.resolve(e)},function(e){o.reject(e)},t,r),o.promise},trackEvent:function(t,r,o,i,a,c){var u=e.defer();return n.plugins.gaPlugin.trackEvent(function(e){u.resolve(e)},function(e){u.reject(e)},o,i,a,c),u.promise},trackPage:function(t,r,o){var i=e.defer();return n.plugins.gaPlugin.trackPage(function(e){i.resolve(e)},function(e){i.reject(e)},o),i.promise},setVariable:function(t,r,o,i){var a=e.defer();return n.plugins.gaPlugin.setVariable(function(e){a.resolve(e)},function(e){a.reject(e)},o,i),a.promise},exit:function(){var t=e.defer();return n.plugins.gaPlugin.exit(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise}}}]),angular.module("ngCordova.plugins.geolocation",[]).factory("$cordovaGeolocation",["$q",function(e){return{getCurrentPosition:function(n){var t=e.defer();return navigator.geolocation.getCurrentPosition(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise},watchPosition:function(n){var t=e.defer(),r=navigator.geolocation.watchPosition(function(e){t.notify(e)},function(e){t.reject(e)},n);return t.promise.cancel=function(){navigator.geolocation.clearWatch(r)},t.promise.clearWatch=function(e){navigator.geolocation.clearWatch(e||r)},t.promise.watchID=r,t.promise},clearWatch:function(e){return navigator.geolocation.clearWatch(e)}}}]),angular.module("ngCordova.plugins.globalization",[]).factory("$cordovaGlobalization",["$q",function(e){return{getPreferredLanguage:function(){var n=e.defer();return navigator.globalization.getPreferredLanguage(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},getLocaleName:function(){var n=e.defer();return navigator.globalization.getLocaleName(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},getFirstDayOfWeek:function(){var n=e.defer();return navigator.globalization.getFirstDayOfWeek(function(e){n.resolve(e)},function(e){n.reject(e)}),n.promise},dateToString:function(n,t){var r=e.defer();return navigator.globalization.dateToString(n,function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise},stringToDate:function(n,t){var r=e.defer();return navigator.globalization.stringToDate(n,function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise},getDatePattern:function(n){var t=e.defer();return navigator.globalization.getDatePattern(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise},getDateNames:function(n){var t=e.defer();return navigator.globalization.getDateNames(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise},isDayLightSavingsTime:function(n){var t=e.defer();return navigator.globalization.isDayLightSavingsTime(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},numberToString:function(n,t){var r=e.defer();return navigator.globalization.numberToString(n,function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise},stringToNumber:function(n,t){var r=e.defer();return navigator.globalization.stringToNumber(n,function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise},getNumberPattern:function(n){var t=e.defer();return navigator.globalization.getNumberPattern(function(e){t.resolve(e)},function(e){t.reject(e)},n),t.promise},getCurrencyPattern:function(n){var t=e.defer();return navigator.globalization.getCurrencyPattern(n,function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise}}}]),angular.module("ngCordova.plugins.googleAds",[]).factory("$cordovaGoogleAds",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.AdMob.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.AdMob.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.AdMob.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.AdMob.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.AdMob.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.AdMob.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.AdMob.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.AdMob.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.googleAnalytics",[]).factory("$cordovaGoogleAnalytics",["$q","$window",function(e,n){return{startTrackerWithId:function(t){var r=e.defer();return n.analytics.startTrackerWithId(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},setUserId:function(t){var r=e.defer();return n.analytics.setUserId(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},debugMode:function(){var t=e.defer();return n.analytics.debugMode(function(e){t.resolve(e)},function(){t.reject()}),t.promise},trackView:function(t){var r=e.defer();return n.analytics.trackView(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},addCustomDimension:function(t,r){var o=e.defer();return n.analytics.addCustomDimension(t,r,function(){o.resolve()},function(e){o.reject(e)}),o.promise},trackEvent:function(t,r,o,i){var a=e.defer();return n.analytics.trackEvent(t,r,o,i,function(e){a.resolve(e)},function(e){a.reject(e)}),a.promise},addTransaction:function(t,r,o,i,a,c){var u=e.defer();return n.analytics.addTransaction(t,r,o,i,a,c,function(e){u.resolve(e)},function(e){u.reject(e)}),u.promise},addTransactionItem:function(t,r,o,i,a,c,u){var s=e.defer();return n.analytics.addTransactionItem(t,r,o,i,a,c,u,function(e){s.resolve(e)},function(e){s.reject(e)}),s.promise}}}]),angular.module("ngCordova.plugins.googleMap",[]).factory("$cordovaGoogleMap",["$q","$window",function(e,n){var t=null;return{getMap:function(r){var o=e.defer();if(n.plugin.google.maps){var i=document.getElementById("map_canvas");t=n.plugin.google.maps.Map.getMap(r),t.setDiv(i),o.resolve(t)}else o.reject(null);return o.promise},isMapLoaded:function(){return!!t},addMarker:function(n){var r=e.defer();return t.addMarker(n,function(e){r.resolve(e)}),r.promise},getMapTypeIds:function(){return n.plugin.google.maps.mapTypeId},setVisible:function(n){var r=e.defer();return t.setVisible(n),r.promise},cleanup:function(){t=null}}}]),angular.module("ngCordova.plugins.googlePlayGame",[]).factory("$cordovaGooglePlayGame",["$q",function(e){return{auth:function(){var n=e.defer();return googleplaygame.auth(function(e){return n.resolve(e)},function(e){return n.reject(e)}),n.promise},signout:function(){var n=e.defer();return googleplaygame.signout(function(e){return n.resolve(e)},function(e){return n.reject(e)}),n.promise},isSignedIn:function(){var n=e.defer();return googleplaygame.isSignedIn(function(e){return n.resolve(e)},function(e){return n.reject(e)}),n.promise},showPlayer:function(){var n=e.defer();return googleplaygame.showPlayer(function(e){return n.resolve(e)},function(e){return n.reject(e)}),n.promise},submitScore:function(n){var t=e.defer();return googleplaygame.submitScore(n,function(e){return t.resolve(e)},function(e){return t.reject(e)}),t.promise},showAllLeaderboards:function(){var n=e.defer();return googleplaygame.showAllLeaderboards(function(e){return n.resolve(e)},function(e){return n.reject(e)}),n.promise},showLeaderboard:function(n){var t=e.defer();return googleplaygame.showLeaderboard(n,function(e){return t.resolve(e)},function(e){return t.reject(e)}),t.promise},unlockAchievement:function(n){var t=e.defer();return googleplaygame.unlockAchievement(n,function(e){return t.resolve(e)},function(e){return t.reject(e)}),t.promise},incrementAchievement:function(n){var t=e.defer();return googleplaygame.incrementAchievement(n,function(e){return t.resolve(e)},function(e){return t.reject(e)}),t.promise},showAchievements:function(){var n=e.defer();return googleplaygame.showAchievements(function(e){return n.resolve(e)},function(e){return n.reject(e)}),n.promise}}}]),angular.module("ngCordova.plugins.googleplus",[]).factory("$cordovaGooglePlus",["$q","$window",function(e,n){return{login:function(t){void 0===t&&(t={});var r=e.defer();return n.plugins.googleplus.login({iOSApiKey:t},function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},silentLogin:function(t){void 0===t&&(t={});var r=e.defer();return n.plugins.googleplus.trySilentLogin({iOSApiKey:t},function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},logout:function(){var t=e.defer();n.plugins.googleplus.logout(function(e){t.resolve(e)})},disconnect:function(){var t=e.defer();n.plugins.googleplus.disconnect(function(e){t.resolve(e)})}}}]),angular.module("ngCordova.plugins.healthKit",[]).factory("$cordovaHealthKit",["$q","$window",function(e,n){return{isAvailable:function(){var t=e.defer();return n.plugins.healthkit.available(function(e){t.resolve(e)},function(e){t.reject(e)}),t.promise},checkAuthStatus:function(t){var r=e.defer();return t=t||"HKQuantityTypeIdentifierHeight",n.plugins.healthkit.checkAuthStatus({type:t},function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},requestAuthorization:function(t,r){var o=e.defer();return t=t||["HKCharacteristicTypeIdentifierDateOfBirth","HKQuantityTypeIdentifierActiveEnergyBurned","HKQuantityTypeIdentifierHeight"],r=r||["HKQuantityTypeIdentifierActiveEnergyBurned","HKQuantityTypeIdentifierHeight","HKQuantityTypeIdentifierDistanceCycling"],n.plugins.healthkit.requestAuthorization({readTypes:t,writeTypes:r},function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},readDateOfBirth:function(){var t=e.defer();return n.plugins.healthkit.readDateOfBirth(function(e){t.resolve(e)},function(e){t.resolve(e)}),t.promise},readGender:function(){var t=e.defer();return n.plugins.healthkit.readGender(function(e){t.resolve(e)},function(e){t.resolve(e)}),t.promise},saveWeight:function(t,r,o){var i=e.defer();return n.plugins.healthkit.saveWeight({unit:r||"lb",amount:t,date:o||new Date},function(e){i.resolve(e)},function(e){i.resolve(e)}),i.promise},readWeight:function(t){var r=e.defer();return n.plugins.healthkit.readWeight({unit:t||"lb"},function(e){r.resolve(e)},function(e){r.resolve(e)}),r.promise},saveHeight:function(t,r,o){var i=e.defer();return n.plugins.healthkit.saveHeight({unit:r||"in",amount:t,date:o||new Date},function(e){i.resolve(e)},function(e){i.resolve(e)}),i.promise},readHeight:function(t){var r=e.defer();return n.plugins.healthkit.readHeight({unit:t||"in"},function(e){r.resolve(e)},function(e){r.resolve(e)}),r.promise},findWorkouts:function(){var t=e.defer();return n.plugins.healthkit.findWorkouts({},function(e){t.resolve(e)},function(e){t.resolve(e)}),t.promise},saveWorkout:function(t){var r=e.defer();return n.plugins.healthkit.saveWorkout(t,function(e){r.resolve(e)},function(e){r.resolve(e)}),r.promise},querySampleType:function(t){var r=e.defer();return n.plugins.healthkit.querySampleType(t,function(e){r.resolve(e)},function(e){r.resolve(e)}),r.promise}}}]),angular.module("ngCordova.plugins.httpd",[]).factory("$cordovaHttpd",["$q",function(e){return{startServer:function(n){var t=e.defer();return cordova.plugins.CorHttpd.startServer(n,function(){t.resolve()},function(){t.reject()}),t.promise},stopServer:function(){var n=e.defer();return cordova.plugins.CorHttpd.stopServer(function(){n.resolve()},function(){n.reject()}),n.promise},getURL:function(){var n=e.defer();return cordova.plugins.CorHttpd.getURL(function(e){n.resolve(e)},function(){n.reject()}),n.promise},getLocalPath:function(){var n=e.defer();return cordova.plugins.CorHttpd.getLocalPath(function(e){n.resolve(e)},function(){n.reject()}),n.promise}}}]),angular.module("ngCordova.plugins.iAd",[]).factory("$cordovaiAd",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.iAd.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.iAd.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.iAd.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.iAd.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.iAd.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.iAd.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.iAd.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.iAd.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.imagePicker",[]).factory("$cordovaImagePicker",["$q","$window",function(e,n){return{getPictures:function(t){var r=e.defer();return n.imagePicker.getPictures(function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise}}}]),angular.module("ngCordova.plugins.inAppBrowser",[]).provider("$cordovaInAppBrowser",[function(){var e,n=this.defaultOptions={};this.setDefaultOptions=function(e){n=angular.extend(n,e)},this.$get=["$rootScope","$q","$window","$timeout",function(t,r,o,i){return{open:function(a,c,u){var s=r.defer();if(u&&!angular.isObject(u))return s.reject("options must be an object"),s.promise;var l=angular.extend({},n,u),f=[];angular.forEach(l,function(e,n){f.push(n+"="+e)});var d=f.join();return e=o.open(a,c,d),e.addEventListener("loadstart",function(e){i(function(){t.$broadcast("$cordovaInAppBrowser:loadstart",e)})},!1),e.addEventListener("loadstop",function(e){s.resolve(e),i(function(){t.$broadcast("$cordovaInAppBrowser:loadstop",e)})},!1),e.addEventListener("loaderror",function(e){s.reject(e),i(function(){t.$broadcast("$cordovaInAppBrowser:loaderror",e)})},!1),e.addEventListener("exit",function(e){i(function(){t.$broadcast("$cordovaInAppBrowser:exit",e)})},!1),s.promise},close:function(){e.close(),e=null},show:function(){e.show()},executeScript:function(n){var t=r.defer();return e.executeScript(n,function(e){t.resolve(e)}),t.promise},insertCSS:function(n){var t=r.defer();return e.insertCSS(n,function(e){t.resolve(e)}),t.promise}}}]}]),angular.module("ngCordova.plugins.insomnia",[]).factory("$cordovaInsomnia",["$window",function(e){return{keepAwake:function(){return e.plugins.insomnia.keepAwake()},allowSleepAgain:function(){return e.plugins.insomnia.allowSleepAgain()}}}]),angular.module("ngCordova.plugins.instagram",[]).factory("$cordovaInstagram",["$q",function(e){return{share:function(n){var t=e.defer();return window.Instagram?(Instagram.share(n.image,n.caption,function(e){e?t.reject(e):t.resolve(!0)}),t.promise):(console.error("Tried to call Instagram.share but the Instagram plugin isn't installed!"),t.resolve(null),t.promise)},isInstalled:function(){var n=e.defer();return window.Instagram?(Instagram.isInstalled(function(e,t){e?n.reject(e):n.resolve(t||!0)}),n.promise):(console.error("Tried to call Instagram.isInstalled but the Instagram plugin isn't installed!"),n.resolve(null),n.promise)}}}]),angular.module("ngCordova.plugins.keyboard",[]).factory("$cordovaKeyboard",[function(){var e=function(){$timeout(function(){$rootScope.$broadcast("$cordovaKeyboard:show")})},n=function(){$timeout(function(){$rootScope.$broadcast("$cordovaKeyboard:hide")})};return document.addEventListener("deviceready",function(){cordova.plugins.Keyboard&&(window.addEventListener("native.keyboardshow",e,!1),window.addEventListener("native.keyboardhide",n,!1))}),{hideAccessoryBar:function(e){return cordova.plugins.Keyboard.hideKeyboardAccessoryBar(e)},close:function(){return cordova.plugins.Keyboard.close()},disableScroll:function(e){return cordova.plugins.Keyboard.disableScroll(e)},isVisible:function(){return cordova.plugins.Keyboard.isVisible},clearShowWatch:function(){document.removeEventListener("native.keyboardshow",e),$rootScope.$$listeners["$cordovaKeyboard:show"]=[]},clearHideWatch:function(){document.removeEventListener("native.keyboardhide",n),$rootScope.$$listeners["$cordovaKeyboard:hide"]=[]}}}]),angular.module("ngCordova.plugins.keychain",[]).factory("$cordovaKeychain",["$q","$window",function(e,n){if("Keychain"in n)var t=new Keychain;return{getForKey:function(n,r){var o=e.defer();return t.getForKey(o.resolve,o.reject,n,r),o.promise},setForKey:function(n,r,o){var i=e.defer();return t.setForKey(i.resolve,i.reject,n,r,o),i.promise},removeForKey:function(n,r){var o=e.defer();return t.removeForKey(o.resolve,o.reject,n,r),o.promise}}}]),angular.module("ngCordova.plugins.localNotification",[]).factory("$cordovaLocalNotification",["$q","$window","$rootScope","$timeout",function(e,n,t,r){return document.addEventListener("deviceready",function(){n.plugin&&n.plugin.notification&&(n.plugin.notification.local.on("cancel",function(e,n,o){var i={id:e,state:n,json:o};r(function(){t.$broadcast("$cordovaLocalNotification:canceled",i)})}),n.plugin.notification.local.on("click",function(e,n,o){var i={id:e,state:n,json:o};r(function(){t.$broadcast("$cordovaLocalNotification:clicked",i)})}),n.plugin.notification.local.on("trigger",function(e,n,o){var i={id:e,state:n,json:o};r(function(){t.$broadcast("$cordovaLocalNotification:triggered",i)})}),n.plugin.notification.local.on("add",function(e,n,o){var i={id:e,state:n,json:o};r(function(){t.$broadcast("$cordovaLocalNotification:added",i)})}))},!1),{add:function(t,r){var o=e.defer();return r=r||null,n.plugin.notification.local.add(t,function(e){o.resolve(e)},r),o.promise},cancel:function(t,r){var o=e.defer();return r=r||null,n.plugin.notification.local.cancel(t,function(e){o.resolve(e)},r),o.promise},cancelAll:function(t){var r=e.defer();return t=t||null,n.plugin.notification.local.cancelAll(function(e){r.resolve(e)},t),r.promise},isScheduled:function(t,r){var o=e.defer();return r=r||null,n.plugin.notification.local.isScheduled(t,function(e){o.resolve(e)},r),o.promise},hasPermission:function(t){var r=e.defer();return n.plugin.notification.local.hasPermission(function(e){e?r.resolve(e):r.reject(e)},t),r.promise},promptForPermission:function(){var t=e.defer();return n.plugin.notification.local.promptForPermission(function(e){e?t.resolve(e):t.reject(e)}),t.promise},registerPermission:function(){var t=e.defer();return n.plugin.notification.local.registerPermission(function(e){e?t.resolve(e):t.reject(e)}),t.promise},getScheduledIds:function(t){var r=e.defer();return n.plugin.notification.local.getScheduledIds(function(e){r.resolve(e)},t),r.promise},isTriggered:function(t,r){var o=e.defer();return n.plugin.notification.local.isTriggered(t,function(e){o.resolve(e)},r),o.promise},getTriggeredIds:function(t){var r=e.defer();return n.plugin.notification.local.getTriggeredIds(function(e){r.resolve(e)},t),r.promise},getDefaults:function(){return n.plugin.notification.local.getDefaults()},setDefaults:function(e){n.plugin.notification.local.setDefaults(e)}}}]),angular.module("ngCordova.plugins.mMediaAds",[]).factory("$cordovaMMediaAds",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.mMedia.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.mMedia.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.mMedia.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.mMedia.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.mMedia.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.mMedia.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.mMedia.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.mMedia.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.media",[]).factory("$cordovaMedia",["$q",function(e){return{newMedia:function(n){var t,r=e.defer(),o=null;return t=new Media(n,function(e){r.resolve(e)},function(e){r.reject(e)},function(e){o=e}),r.promise.getCurrentPosition=function(){t.getCurrentPosition(function(){},function(){})},r.promise.getDuration=function(){t.getDuration()},r.promise.play=function(e){"object"!=typeof e&&(e={}),t.play(e)},r.promise.pause=function(){t.pause()},r.promise.stop=function(){t.stop()},r.promise.release=function(){t.release()},r.promise.seekTo=function(e){t.seekTo(e)},r.promise.setVolume=function(e){t.setVolume(e)},r.promise.startRecord=function(){t.startRecord()},r.promise.stopRecord=function(){t.stopRecord()},r.promise.media=t,r.promise}}}]),angular.module("ngCordova.plugins.mobfoxAds",[]).factory("$cordovaMobFoxAds",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.MobFox.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.MobFox.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.MobFox.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.MobFox.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.MobFox.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.MobFox.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.MobFox.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.MobFox.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins",["ngCordova.plugins.actionSheet","ngCordova.plugins.adMob","ngCordova.plugins.appAvailability","ngCordova.plugins.appRate","ngCordova.plugins.appVersion","ngCordova.plugins.backgroundGeolocation","ngCordova.plugins.badge","ngCordova.plugins.barcodeScanner","ngCordova.plugins.batteryStatus","ngCordova.plugins.ble","ngCordova.plugins.bluetoothSerial","ngCordova.plugins.brightness","ngCordova.plugins.calendar","ngCordova.plugins.camera","ngCordova.plugins.capture","ngCordova.plugins.clipboard","ngCordova.plugins.contacts","ngCordova.plugins.datePicker","ngCordova.plugins.device","ngCordova.plugins.deviceMotion","ngCordova.plugins.deviceOrientation","ngCordova.plugins.dialogs","ngCordova.plugins.emailComposer","ngCordova.plugins.facebook","ngCordova.plugins.facebookAds","ngCordova.plugins.file","ngCordova.plugins.fileTransfer","ngCordova.plugins.fileOpener2","ngCordova.plugins.flashlight","ngCordova.plugins.flurryAds","ngCordova.plugins.ga","ngCordova.plugins.geolocation","ngCordova.plugins.globalization","ngCordova.plugins.googleAds","ngCordova.plugins.googleAnalytics","ngCordova.plugins.googleMap","ngCordova.plugins.googlePlayGame","ngCordova.plugins.healthKit","ngCordova.plugins.httpd","ngCordova.plugins.iAd","ngCordova.plugins.imagePicker","ngCordova.plugins.inAppBrowser","ngCordova.plugins.keyboard","ngCordova.plugins.keychain","ngCordova.plugins.localNotification","ngCordova.plugins.media","ngCordova.plugins.mMediaAds","ngCordova.plugins.mobfoxAds","ngCordova.plugins.mopubAds","ngCordova.plugins.nativeAudio","ngCordova.plugins.network","ngCordova.plugins.oauth","ngCordova.plugins.oauthUtility","ngCordova.plugins.pinDialog","ngCordova.plugins.prefs","ngCordova.plugins.printer","ngCordova.plugins.progressIndicator","ngCordova.plugins.push","ngCordova.plugins.sms","ngCordova.plugins.socialSharing","ngCordova.plugins.spinnerDialog","ngCordova.plugins.splashscreen","ngCordova.plugins.sqlite","ngCordova.plugins.statusbar","ngCordova.plugins.toast","ngCordova.plugins.touchid","ngCordova.plugins.vibration","ngCordova.plugins.videoCapturePlus","ngCordova.plugins.zip","ngCordova.plugins.insomnia"]),angular.module("ngCordova.plugins.mopubAds",[]).factory("$cordovaMoPubAds",["$q","$window",function(e,n){return{setOptions:function(t){var r=e.defer();return n.MoPub.setOptions(t,function(){r.resolve()},function(){r.reject()}),r.promise},createBanner:function(t){var r=e.defer();return n.MoPub.createBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},removeBanner:function(){var t=e.defer();return n.MoPub.removeBanner(function(){t.resolve()},function(){t.reject()}),t.promise},showBanner:function(t){var r=e.defer();return n.MoPub.showBanner(t,function(){r.resolve()},function(){r.reject()}),r.promise},showBannerAtXY:function(t,r){var o=e.defer();return n.MoPub.showBannerAtXY(t,r,function(){o.resolve()},function(){o.reject()}),o.promise},hideBanner:function(){var t=e.defer();return n.MoPub.hideBanner(function(){t.resolve()},function(){t.reject()}),t.promise},prepareInterstitial:function(t){var r=e.defer();return n.MoPub.prepareInterstitial(t,function(){r.resolve()},function(){r.reject()}),r.promise},showInterstitial:function(){var t=e.defer();return n.MoPub.showInterstitial(function(){t.resolve()},function(){t.reject()}),t.promise}}}]),angular.module("ngCordova.plugins.nativeAudio",[]).factory("$cordovaNativeAudio",["$q","$window",function(e,n){return{preloadSimple:function(t,r){var o=e.defer();return n.plugins.NativeAudio.preloadSimple(t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},preloadComplex:function(t,r,o,i){var a=e.defer();return n.plugins.NativeAudio.preloadComplex(t,r,o,i,function(e){a.resolve(e)},function(e){a.reject(e)}),a.promise},play:function(t,r){var o=e.defer();return n.plugins.NativeAudio.play(t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},stop:function(t){var r=e.defer();return n.plugins.NativeAudio.stop(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},loop:function(t){var r=e.defer();return n.plugins.NativeAudio.loop(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},unload:function(t){var r=e.defer();return n.plugins.NativeAudio.unload(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},setVolumeForComplexAsset:function(t,r){var o=e.defer();return n.plugins.NativeAudio.setVolumeForComplexAsset(t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise}}}]),angular.module("ngCordova.plugins.network",[]).factory("$cordovaNetwork",["$rootScope","$timeout",function(e,n){var t=function(){var t=navigator.connection.type;n(function(){e.$broadcast("$cordovaNetwork:offline",t)})},r=function(){var t=navigator.connection.type;n(function(){e.$broadcast("$cordovaNetwork:online",t)})};return document.addEventListener("deviceready",function(){navigator.connection&&(document.addEventListener("offline",t,!1),document.addEventListener("online",r,!1))}),{getNetwork:function(){return navigator.connection.type},isOnline:function(){var e=navigator.connection.type;return e!==Connection.UNKNOWN&&e!==Connection.NONE},isOffline:function(){var e=navigator.connection.type;return e===Connection.UNKNOWN||e===Connection.NONE},clearOfflineWatch:function(){document.removeEventListener("offline",t),e.$$listeners["$cordovaNetwork:offline"]=[]},clearOnlineWatch:function(){document.removeEventListener("online",t),e.$$listeners["$cordovaNetwork:online"]=[]}}}]).run(["$cordovaNetwork",function(){}]),angular.module("ngCordova.plugins.oauth",["ngCordova.plugins.oauthUtility"]).factory("$cordovaOauth",["$q","$http","$cordovaOauthUtility",function(e,n,t){return{adfs:function(t,r,o){var i=e.defer();if(window.cordova){var a=cordova.require("cordova/plugin_list").metadata;if(a.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var c=window.open(r+"/adfs/oauth2/authorize?response_type=code&client_id="+t+"&redirect_uri=http://localhost/callback&resource="+o,"_blank","location=no");c.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){var o=e.url.split("code=")[1];n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:r+"/adfs/oauth2/token",data:"client_id="+t+"&code="+o+"&redirect_uri=http://localhost/callback&grant_type=authorization_code"}).success(function(e){i.resolve(e)}).error(function(){i.reject("Problem authenticating")}).finally(function(){setTimeout(function(){c.close()},10)})}}),c.addEventListener("exit",function(){i.reject("The sign in flow was canceled")})}else i.reject("Could not find InAppBrowser plugin")}else i.reject("Cannot authenticate via a web browser");return i.promise},dropbox:function(n){var t=e.defer();if(window.cordova){var r=cordova.require("cordova/plugin_list").metadata;if(r.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var o=window.open("https://www.dropbox.com/1/oauth2/authorize?client_id="+n+"&redirect_uri=http://localhost/callback&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");o.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var n=e.url.split("#")[1],r=n.split("&"),i=[],a=0;a<r.length;a++)i[r[a].split("=")[0]]=r[a].split("=")[1];void 0!==i.access_token&&null!==i.access_token?t.resolve({access_token:i.access_token,token_type:i.token_type,uid:i.uid}):t.reject("Problem authenticating"),setTimeout(function(){o.close()},10)}}),o.addEventListener("exit",function(){t.reject("The sign in flow was canceled")
+})}else t.reject("Could not find InAppBrowser plugin")}else t.reject("Cannot authenticate via a web browser");return t.promise},digitalOcean:function(t,r){var o=e.defer();if(window.cordova){var i=cordova.require("cordova/plugin_list").metadata;if(i.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var a=window.open("https://cloud.digitalocean.com/v1/oauth/authorize?client_id="+t+"&redirect_uri=http://localhost/callback&response_type=code&scope=read%20write","_blank","location=no,clearsessioncache=yes,clearcache=yes");a.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){var i=e.url.split("code=")[1];n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:"https://cloud.digitalocean.com/v1/oauth/token",data:"client_id="+t+"&client_secret="+r+"&redirect_uri=http://localhost/callback&grant_type=authorization_code&code="+i}).success(function(e){o.resolve(e)}).error(function(){o.reject("Problem authenticating")}).finally(function(){setTimeout(function(){a.close()},10)})}}),a.addEventListener("exit",function(){o.reject("The sign in flow was canceled")})}else o.reject("Could not find InAppBrowser plugin")}else o.reject("Cannot authenticate via a web browser");return o.promise},google:function(n,t){var r=e.defer();if(window.cordova){var o=cordova.require("cordova/plugin_list").metadata;if(o.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var i=window.open("https://accounts.google.com/o/oauth2/auth?client_id="+n+"&redirect_uri=http://localhost/callback&scope="+t.join(" ")+"&approval_prompt=force&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");i.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var n=e.url.split("#")[1],t=n.split("&"),o=[],a=0;a<t.length;a++)o[t[a].split("=")[0]]=t[a].split("=")[1];void 0!==o.access_token&&null!==o.access_token?r.resolve({access_token:o.access_token,token_type:o.token_type,expires_in:o.expires_in}):r.reject("Problem authenticating"),setTimeout(function(){i.close()},10)}}),i.addEventListener("exit",function(){r.reject("The sign in flow was canceled")})}else r.reject("Could not find InAppBrowser plugin")}else r.reject("Cannot authenticate via a web browser");return r.promise},github:function(t,r,o){var i=e.defer();if(window.cordova){var a=cordova.require("cordova/plugin_list").metadata;if(a.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var c=window.open("https://github.com/login/oauth/authorize?client_id="+t+"&redirect_uri=http://localhost/callback&scope="+o.join(","),"_blank","location=no,clearsessioncache=yes,clearcache=yes");c.addEventListener("loadstart",function(e){0===e.url.indexOf("http://localhost/callback")&&(requestToken=e.url.split("code=")[1],n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n.defaults.headers.post.accept="application/json",n({method:"post",url:"https://github.com/login/oauth/access_token",data:"client_id="+t+"&client_secret="+r+"&redirect_uri=http://localhost/callback&code="+requestToken}).success(function(e){i.resolve(e)}).error(function(){i.reject("Problem authenticating")}).finally(function(){setTimeout(function(){c.close()},10)}))}),c.addEventListener("exit",function(){i.reject("The sign in flow was canceled")})}else i.reject("Could not find InAppBrowser plugin")}else i.reject("Cannot authenticate via a web browser");return i.promise},facebook:function(n,t){var r=e.defer();if(window.cordova){var o=cordova.require("cordova/plugin_list").metadata;if(o.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var i=window.open("https://www.facebook.com/dialog/oauth?client_id="+n+"&redirect_uri=http://localhost/callback&response_type=token&scope="+t.join(","),"_blank","location=no,clearsessioncache=yes,clearcache=yes");i.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var n=e.url.split("#")[1],t=n.split("&"),o=[],a=0;a<t.length;a++)o[t[a].split("=")[0]]=t[a].split("=")[1];void 0!==o.access_token&&null!==o.access_token?r.resolve({access_token:o.access_token,expires_in:o.expires_in}):r.reject("Problem authenticating"),setTimeout(function(){i.close()},10)}}),i.addEventListener("exit",function(){r.reject("The sign in flow was canceled")})}else r.reject("Could not find InAppBrowser plugin")}else r.reject("Cannot authenticate via a web browser");return r.promise},linkedin:function(t,r,o,i){var a=e.defer();if(window.cordova){var c=cordova.require("cordova/plugin_list").metadata;if(c.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var u=window.open("https://www.linkedin.com/uas/oauth2/authorization?client_id="+t+"&redirect_uri=http://localhost/callback&scope="+o.join(" ")+"&response_type=code&state="+i,"_blank","location=no,clearsessioncache=yes,clearcache=yes");u.addEventListener("loadstart",function(e){0===e.url.indexOf("http://localhost/callback")&&(requestToken=e.url.split("code=")[1],n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:"https://www.linkedin.com/uas/oauth2/accessToken",data:"client_id="+t+"&client_secret="+r+"&redirect_uri=http://localhost/callback&grant_type=authorization_code&code="+requestToken}).success(function(e){a.resolve(e)}).error(function(){a.reject("Problem authenticating")}).finally(function(){setTimeout(function(){u.close()},10)}))}),u.addEventListener("exit",function(){a.reject("The sign in flow was canceled")})}else a.reject("Could not find InAppBrowser plugin")}else a.reject("Cannot authenticate via a web browser");return a.promise},instagram:function(n,t){var r=e.defer();if(window.cordova){var o=cordova.require("cordova/plugin_list").metadata;if(o.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var i=window.open("https://api.instagram.com/oauth/authorize/?client_id="+n+"&redirect_uri=http://localhost/callback&scope="+t.join(" ")+"&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");i.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var n=e.url.split("#")[1],t=n.split("&"),o=[],a=0;a<t.length;a++)o[t[a].split("=")[0]]=t[a].split("=")[1];void 0!==o.access_token&&null!==o.access_token?r.resolve({access_token:o.access_token}):r.reject("Problem authenticating"),setTimeout(function(){i.close()},10)}}),i.addEventListener("exit",function(){r.reject("The sign in flow was canceled")})}else r.reject("Could not find InAppBrowser plugin")}else r.reject("Cannot authenticate via a web browser");return r.promise},box:function(t,r,o){var i=e.defer();if(window.cordova){var a=cordova.require("cordova/plugin_list").metadata;if(a.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var c=window.open("https://app.box.com/api/oauth2/authorize/?client_id="+t+"&redirect_uri=http://localhost/callback&state="+o+"&response_type=code","_blank","location=no,clearsessioncache=yes,clearcache=yes");c.addEventListener("loadstart",function(e){0===e.url.indexOf("http://localhost/callback")&&(requestToken=e.url.split("code=")[1],n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:"https://app.box.com/api/oauth2/token",data:"client_id="+t+"&client_secret="+r+"&redirect_uri=http://localhost/callback&grant_type=authorization_code&code="+requestToken}).success(function(e){i.resolve(e)}).error(function(){i.reject("Problem authenticating")}).finally(function(){setTimeout(function(){c.close()},10)}))}),c.addEventListener("exit",function(){i.reject("The sign in flow was canceled")})}else i.reject("Could not find InAppBrowser plugin")}else i.reject("Cannot authenticate via a web browser");return i.promise},reddit:function(t,r,o){var i=e.defer();if(window.cordova){var a=cordova.require("cordova/plugin_list").metadata;if(a.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var c=window.open("https://ssl.reddit.com/api/v1/authorize?client_id="+t+"&redirect_uri=http://localhost/callback&duration=permanent&state=ngcordovaoauth&scope="+o.join(",")+"&response_type=code","_blank","location=no,clearsessioncache=yes,clearcache=yes");c.addEventListener("loadstart",function(e){0===e.url.indexOf("http://localhost/callback")&&(requestToken=e.url.split("code=")[1],n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n.defaults.headers.post.Authorization="Basic "+btoa(t+":"+r),n({method:"post",url:"https://ssl.reddit.com/api/v1/access_token",data:"redirect_uri=http://localhost/callback&grant_type=authorization_code&code="+requestToken}).success(function(e){i.resolve(e)}).error(function(){i.reject("Problem authenticating")}).finally(function(){setTimeout(function(){c.close()},10)}))}),c.addEventListener("exit",function(){i.reject("The sign in flow was canceled")})}else i.reject("Could not find InAppBrowser plugin")}else i.reject("Cannot authenticate via a web browser");return i.promise},twitter:function(r,o){var i=e.defer();if(window.cordova){var a=cordova.require("cordova/plugin_list").metadata;if(a.hasOwnProperty("org.apache.cordova.inappbrowser")===!0)if("undefined"!=typeof jsSHA){var c={oauth_consumer_key:r,oauth_nonce:t.createNonce(10),oauth_signature_method:"HMAC-SHA1",oauth_timestamp:Math.round((new Date).getTime()/1e3),oauth_version:"1.0"},u=t.createSignature("POST","https://api.twitter.com/oauth/request_token",c,{oauth_callback:"http://localhost/callback"},o);n({method:"post",url:"https://api.twitter.com/oauth/request_token",headers:{Authorization:u.authorization_header,"Content-Type":"application/x-www-form-urlencoded"},data:"oauth_callback="+encodeURIComponent("http://localhost/callback")}).success(function(e){for(var r=e.split("&"),a={},u=0;u<r.length;u++)a[r[u].split("=")[0]]=r[u].split("=")[1];a.hasOwnProperty("oauth_token")===!1&&i.reject("Oauth request token was not received");var s=window.open("https://api.twitter.com/oauth/authenticate?oauth_token="+a.oauth_token,"_blank","location=no,clearsessioncache=yes,clearcache=yes");s.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var r=e.url.split("?")[1],a=r.split("&"),u={},l=0;l<a.length;l++)u[a[l].split("=")[0]]=a[l].split("=")[1];u.hasOwnProperty("oauth_verifier")===!1&&i.reject("Browser authentication failed to complete. No oauth_verifier was returned"),delete c.oauth_signature,c.oauth_token=u.oauth_token;var f=t.createSignature("POST","https://api.twitter.com/oauth/access_token",c,{oauth_verifier:u.oauth_verifier},o);n({method:"post",url:"https://api.twitter.com/oauth/access_token",headers:{Authorization:f.authorization_header},params:{oauth_verifier:u.oauth_verifier}}).success(function(e){for(var n=e.split("&"),t={},r=0;r<n.length;r++)t[n[r].split("=")[0]]=n[r].split("=")[1];t.hasOwnProperty("oauth_token_secret")===!1&&i.reject("Oauth access token was not received"),i.resolve(t)}).error(function(e){i.reject(e)}).finally(function(){setTimeout(function(){s.close()},10)})}}),s.addEventListener("exit",function(){i.reject("The sign in flow was canceled")})}).error(function(e){i.reject(e)})}else i.reject("Missing jsSHA JavaScript library");else i.reject("Could not find InAppBrowser plugin")}else i.reject("Cannot authenticate via a web browser");return i.promise},meetup:function(n){var t=e.defer();if(window.cordova){var r=cordova.require("cordova/plugin_list").metadata;if(r.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var o=window.open("https://secure.meetup.com/oauth2/authorize/?client_id="+n+"&redirect_uri=http://localhost/callback&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");o.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var n=e.url.split("#")[1],r=n.split("&"),i={},a=0;a<r.length;a++)i[r[a].split("=")[0]]=r[a].split("=")[1];void 0!==i.access_token&&null!==i.access_token?t.resolve(i):t.reject("Problem authenticating"),setTimeout(function(){o.close()},10)}}),o.addEventListener("exit",function(){t.reject("The sign in flow was canceled")})}else t.reject("Could not find InAppBrowser plugin")}else t.reject("Cannot authenticate via a web browser");return t.promise},salesforce:function(n,t){var r="http://localhost/callback",o=function(e,n,t){return e+"services/oauth2/authorize?display=touch&response_type=token&client_id="+escape(n)+"&redirect_uri="+escape(t)},i=function(e,n){return e.substr(0,n.length)===n},a=e.defer();if(window.cordova){var c=cordova.require("cordova/plugin_list").metadata;if(c.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var u=window.open(o(n,t,r),"_blank","location=no,clearsessioncache=yes,clearcache=yes");u.addEventListener("loadstart",function(e){if(i(e.url,r)){var n={},t=e.url.split("#")[1];if(t){var o=t.split("&");for(var c in o){var s=o[c].split("=");n[s[0]]=unescape(s[1])}}"undefined"==typeof n||"undefined"==typeof n.access_token?a.reject("Problem authenticating"):a.resolve(n),setTimeout(function(){u.close()},10)}}),u.addEventListener("exit",function(){a.reject("The sign in flow was canceled")})}else a.reject("Could not find InAppBrowser plugin")}else a.reject("Cannot authenticate via a web browser");return a.promise},strava:function(t,r,o){var i=e.defer();if(window.cordova){var a=cordova.require("cordova/plugin_list").metadata;if(a.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var c=window.open("https://www.strava.com/oauth/authorize?client_id="+t+"&redirect_uri=http://localhost/callback&scope="+o.join(",")+"&response_type=code&approval_prompt=force","_blank","location=no,clearsessioncache=yes,clearcache=yes");c.addEventListener("loadstart",function(e){0===e.url.indexOf("http://localhost/callback")&&(requestToken=e.url.split("code=")[1],n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:"https://www.strava.com/oauth/token",data:"client_id="+t+"&client_secret="+r+"&code="+requestToken}).success(function(e){i.resolve(e)}).error(function(){i.reject("Problem authenticating")}).finally(function(){setTimeout(function(){c.close()},10)}))}),c.addEventListener("exit",function(){i.reject("The sign in flow was canceled")})}else i.reject("Could not find InAppBrowser plugin")}else i.reject("Cannot authenticate via a web browser");return i.promise},foursquare:function(n){var t=e.defer();if(window.cordova){var r=cordova.require("cordova/plugin_list").metadata;if(r.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var o=window.open("https://foursquare.com/oauth2/authenticate?client_id="+n+"&redirect_uri=http://localhost/callback&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");o.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var n=e.url.split("#")[1],r=n.split("&"),i=[],a=0;a<r.length;a++)i[r[a].split("=")[0]]=r[a].split("=")[1];if(void 0!==i.access_token&&null!==i.access_token){var c={access_token:i.access_token,expires_in:i.expires_in};t.resolve(c)}else t.reject("Problem authenticating");setTimeout(function(){o.close()},10)}}),o.addEventListener("exit",function(){t.reject("The sign in flow was canceled")})}else t.reject("Could not find InAppBrowser plugin")}else t.reject("Cannot authenticate via a web browser");return t.promise},magento:function(r,o,i){var a=e.defer();if(window.cordova){var c=cordova.require("cordova/plugin_list").metadata;if(c.hasOwnProperty("org.apache.cordova.inappbrowser")===!0)if("undefined"!=typeof jsSHA){var u={oauth_callback:"http://localhost/callback",oauth_consumer_key:o,oauth_nonce:t.createNonce(5),oauth_signature_method:"HMAC-SHA1",oauth_timestamp:Math.round((new Date).getTime()/1e3),oauth_version:"1.0"},s=t.createSignature("POST",r+"/oauth/initiate",u,{oauth_callback:"http://localhost/callback"},i);n.defaults.headers.post.Authorization=s.authorization_header,n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:r+"/oauth/initiate",data:"oauth_callback=http://localhost/callback"}).success(function(e){for(var o=e.split("&"),c={},s=0;s<o.length;s++)c[o[s].split("=")[0]]=o[s].split("=")[1];c.hasOwnProperty("oauth_token")===!1&&a.reject("Oauth request token was not received");var l=c.oauth_token_secret,f=window.open(r+"/oauth/authorize?oauth_token="+c.oauth_token,"_blank","location=no,clearsessioncache=yes,clearcache=yes");f.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){for(var o=e.url.split("?")[1],c=o.split("&"),s={},d=0;d<c.length;d++)s[c[d].split("=")[0]]=c[d].split("=")[1];s.hasOwnProperty("oauth_verifier")===!1&&a.reject("Browser authentication failed to complete. No oauth_verifier was returned"),delete u.oauth_signature,delete u.oauth_callback,u.oauth_token=s.oauth_token,u.oauth_nonce=t.createNonce(5),u.oauth_verifier=s.oauth_verifier;var p=t.createSignature("POST",r+"/oauth/token",u,{},i,l);n.defaults.headers.post.Authorization=p.authorization_header,n.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded",n({method:"post",url:r+"/oauth/token"}).success(function(e){for(var n=e.split("&"),t={},r=0;r<n.length;r++)t[n[r].split("=")[0]]=n[r].split("=")[1];t.hasOwnProperty("oauth_token_secret")===!1&&a.reject("Oauth access token was not received"),a.resolve(t)}).error(function(e){a.reject(e)}).finally(function(){setTimeout(function(){f.close()},10)})}}),f.addEventListener("exit",function(){a.reject("The sign in flow was canceled")})}).error(function(e){a.reject(e)})}else a.reject("Missing jsSHA JavaScript library");else a.reject("Could not find InAppBrowser plugin")}else a.reject("Cannot authenticate via a web browser");return a.promise},vkontakte:function(n,t){var r=e.defer();if(window.cordova){var o=cordova.require("cordova/plugin_list").metadata;if(o.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var i=window.open("https://oauth.vk.com/authorize?client_id="+n+"&redirect_uri=http://oauth.vk.com/blank.html&response_type=token&scope="+t.join(",")+"&display=touch&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");i.addEventListener("loadstart",function(e){var n=e.url.split("#");if("https://oauth.vk.com/blank.html"==n[0]||"http://oauth.vk.com/blank.html"==n[0]){for(var t=e.url.split("#")[1],o=t.split("&"),a=[],c=0;c<o.length;c++)a[o[c].split("=")[0]]=o[c].split("=")[1];void 0!==a.access_token&&null!==a.access_token?r.resolve({access_token:a.access_token,expires_in:a.expires_in,user_id:a.user_id}):r.reject("Problem authenticating"),setTimeout(function(){i.close()},10)}}),i.addEventListener("exit",function(){r.reject("The sign in flow was canceled")})}else r.reject("Could not find InAppBrowser plugin")}else r.reject("Cannot authenticate via a web browser");return r.promise},imgur:function(n){var t=e.defer();if(window.cordova){var r=cordova.require("cordova/plugin_list").metadata;if(r.hasOwnProperty("org.apache.cordova.inappbrowser")===!0){var o=window.open("https://api.imgur.com/oauth2/authorize?client_id="+n+"&response_type=token","_blank","location=no,clearsessioncache=yes,clearcache=yes");o.addEventListener("loadstart",function(e){if(0===e.url.indexOf("http://localhost/callback")){o.removeEventListener("exit",function(){}),o.close();for(var n=e.url.split("#")[1],r=n.split("&"),i=[],a=0;a<r.length;a++)i[r[a].split("=")[0]]=r[a].split("=")[1];void 0!==i.access_token&&null!==i.access_token?t.resolve({access_token:i.access_token,expires_in:i.expires_in,account_username:i.account_username}):t.reject("Problem authenticating")}}),o.addEventListener("exit",function(){t.reject("The sign in flow was canceled")})}else t.reject("Could not find InAppBrowser plugin")}else t.reject("Cannot authenticate via a web browser");return t.promise}}}]),angular.module("ngCordova.plugins.oauthUtility",[]).factory("$cordovaOauthUtility",["$q",function(){return{createSignature:function(e,n,t,r,o,i){if("undefined"!=typeof jsSHA){for(var a=angular.copy(t),c=Object.keys(r),u=0;u<c.length;u++)a[c[u]]=encodeURIComponent(r[c[u]]);var s=e+"&"+encodeURIComponent(n)+"&",l=Object.keys(a).sort();for(u=0;u<l.length;u++)s+=encodeURIComponent(u==l.length-1?l[u]+"="+a[l[u]]:l[u]+"="+a[l[u]]+"&");var f=new jsSHA(s,"TEXT"),d="";i&&(d=encodeURIComponent(i)),t.oauth_signature=encodeURIComponent(f.getHMAC(encodeURIComponent(o)+"&"+d,"TEXT","SHA-1","B64"));var p=Object.keys(t),v="OAuth ";for(u=0;u<p.length;u++)v+=u==p.length-1?p[u]+'="'+t[p[u]]+'"':p[u]+'="'+t[p[u]]+'",';return{signature_base_string:s,authorization_header:v,signature:t.oauth_signature}}return"Missing jsSHA JavaScript library"},createNonce:function(e){for(var n="",t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=0;e>r;r++)n+=t.charAt(Math.floor(Math.random()*t.length));return n}}}]),angular.module("ngCordova.plugins.pinDialog",[]).factory("$cordovaPinDialog",["$q","$window",function(e,n){return{prompt:function(t,r,o){var i=e.defer();return n.plugins.pinDialog.prompt(t,function(e){i.resolve(e)},r,o),i.promise}}}]),angular.module("ngCordova.plugins.prefs",[]).factory("$cordovaPreferences",["$window","$q",function(e,n){return{set:function(t,r){var o=n.defer();return e.appgiraffe.plugins.applicationPreferences.set(t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise},get:function(t){var r=n.defer();return e.appgiraffe.plugins.applicationPreferences.get(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise}}}]),angular.module("ngCordova.plugins.printer",[]).factory("$cordovaPrinter",["$q","$window",function(e,n){return{isAvailable:function(){var t=e.defer();return n.plugin.printer.isAvailable(function(e){t.resolve(e)}),t.promise},print:function(t,r){var o=e.defer();return n.plugin.printer.print(t,r,function(){o.resolve()}),o.promise}}}]),angular.module("ngCordova.plugins.progressIndicator",[]).factory("$cordovaProgress",["$q",function(){return{show:function(e){var n=e||"Please wait...";return ProgressIndicator.show(n)},showSimple:function(e){var n=e||!1;return ProgressIndicator.showSimple(n)},showSimpleWithLabel:function(e,n){var t=e||!1,r=n||"Loading...";return ProgressIndicator.showSimpleWithLabel(t,r)},showSimpleWithLabelDetail:function(e,n,t){var r=e||!1,o=n||"Loading...",i=t||"Please wait";return ProgressIndicator.showSimpleWithLabelDetail(r,o,i)},showDeterminate:function(e,n){var t=e||!1,r=n||5e4;return ProgressIndicator.showDeterminate(t,r)},showDeterminateWithLabel:function(e,n,t){var r=e||!1,o=n||5e4,i=t||"Loading...";return ProgressIndicator.showDeterminateWithLabel(r,o,i)},showAnnular:function(e,n){var t=e||!1,r=n||5e4;return ProgressIndicator.showAnnular(t,r)},showAnnularWithLabel:function(e,n,t){var r=e||!1,o=n||5e4,i=t||"Loading...";return ProgressIndicator.showAnnularWithLabel(r,o,i)},showBar:function(e,n){var t=e||!1,r=n||5e4;return ProgressIndicator.showBar(t,r)},showBarWithLabel:function(e,n,t){var r=e||!1,o=n||5e4,i=t||"Loading...";return ProgressIndicator.showBarWithLabel(r,o,i)},showSuccess:function(e,n){var t=e||!1,r=n||"Success";return ProgressIndicator.showSuccess(t,r)},showText:function(e,n,t){var r=e||!1,o=n||"Warning",i=t||"center";return ProgressIndicator.showText(r,o,i)},hide:function(){return ProgressIndicator.hide()}}}]),angular.module("ngCordova.plugins.push",[]).factory("$cordovaPush",["$q","$window","$rootScope","$timeout",function(e,n,t,r){return{onNotification:function(e){r(function(){t.$broadcast("$cordovaPush:notificationReceived",e)})},register:function(t){var r,o=e.defer();return void 0!==t&&void 0===t.ecb&&(r=null==document.querySelector("[ng-app]")?"document.body":"document.querySelector('[ng-app]')",t.ecb="angular.element("+r+").injector().get('$cordovaPush').onNotification"),n.plugins.pushNotification.register(function(e){o.resolve(e)},function(e){o.reject(e)},t),o.promise},unregister:function(t){var r=e.defer();return n.plugins.pushNotification.unregister(function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise},setBadgeNumber:function(t){var r=e.defer();return n.plugins.pushNotification.setApplicationIconBadgeNumber(function(e){r.resolve(e)},function(e){r.reject(e)},t),r.promise}}}]),angular.module("ngCordova.plugins.sms",[]).factory("$cordovaSms",["$q",function(e){return{send:function(n,t,r){var o=e.defer();return sms.send(n,t,r,function(e){o.resolve(e)},function(e){o.reject(e)}),o.promise}}}]),angular.module("ngCordova.plugins.socialSharing",[]).factory("$cordovaSocialSharing",["$q","$window",function(e,n){return{share:function(t,r,o,i){var a=e.defer();return r=r||null,o=o||null,i=i||null,n.plugins.socialsharing.share(t,r,o,i,function(){a.resolve(!0)},function(){a.reject(!1)}),a.promise},shareViaTwitter:function(t,r,o){var i=e.defer();return r=r||null,o=o||null,n.plugins.socialsharing.shareViaTwitter(t,r,o,function(){i.resolve(!0)},function(){i.reject(!1)}),i.promise},shareViaWhatsApp:function(t,r,o){var i=e.defer();return r=r||null,o=o||null,n.plugins.socialsharing.shareViaWhatsApp(t,r,o,function(){i.resolve(!0)},function(){i.reject(!1)}),i.promise},shareViaFacebook:function(t,r,o){var i=e.defer();return t=t||null,r=r||null,o=o||null,n.plugins.socialsharing.shareViaFacebook(t,r,o,function(){i.resolve(!0)},function(){i.reject(!1)}),i.promise},shareViaFacebookWithPasteMessageHint:function(t,r,o,i){var a=e.defer();return r=r||null,o=o||null,n.plugins.socialsharing.shareViaFacebookWithPasteMessageHint(t,r,o,i,function(){a.resolve(!0)},function(){a.reject(!1)}),a.promise},shareViaSMS:function(t,r){var o=e.defer();return n.plugins.socialsharing.shareViaSMS(t,r,function(){o.resolve(!0)},function(){o.reject(!1)}),o.promise},shareViaEmail:function(t,r,o,i,a,c){var u=e.defer();return o=o||null,i=i||null,a=a||null,c=c||null,n.plugins.socialsharing.shareViaEmail(t,r,o,i,a,c,function(){u.resolve(!0)},function(){u.reject(!1)}),u.promise},shareVia:function(t,r,o,i,a){var c=e.defer();return r=r||null,o=o||null,i=i||null,a=a||null,n.plugins.socialsharing.shareVia(t,r,o,i,a,function(){c.resolve(!0)},function(){c.reject(!1)}),c.promise},canShareViaEmail:function(){var t=e.defer();return n.plugins.socialsharing.canShareViaEmail(function(){t.resolve(!0)},function(){t.reject(!1)}),t.promise},canShareVia:function(t,r,o,i,a){var c=e.defer();return n.plugins.socialsharing.canShareVia(t,r,o,i,a,function(e){c.resolve(e)},function(e){c.reject(e)}),c.promise},available:function(){var n=e.defer();window.plugins.socialsharing.available(function(e){e?n.resolve():n.reject()})}}}]),angular.module("ngCordova.plugins.spinnerDialog",[]).factory("$cordovaSpinnerDialog",["$window",function(e){return{show:function(n,t,r){return r=r||!1,e.plugins.spinnerDialog.show(n,t,r)},hide:function(){return e.plugins.spinnerDialog.hide()}}}]),angular.module("ngCordova.plugins.splashscreen",[]).factory("$cordovaSplashscreen",[function(){return{hide:function(){return navigator.splashscreen.hide()},show:function(){return navigator.splashscreen.show()}}}]),angular.module("ngCordova.plugins.sqlite",[]).factory("$cordovaSQLite",["$q","$window",function(e,n){return{openDB:function(e,t){return"undefined"==typeof t&&(t=0),n.sqlitePlugin.openDatabase({name:e,bgType:t})},execute:function(n,t,r){var o=e.defer();return n.transaction(function(e){e.executeSql(t,r,function(e,n){o.resolve(n)},function(e,n){o.reject(n)})}),o.promise},insertCollection:function(n,t,r){var o=e.defer(),i=r.slice(0);return n.transaction(function(e){!function n(){var r=i.splice(0,1)[0];try{e.executeSql(t,r,function(e,t){0===i.length?o.resolve(t):n()},function(e,n){o.reject(n)})}catch(a){o.reject(a)}}()}),o.promise},nestedExecute:function(n,t,r,o,i){var a=e.defer();return n.transaction(function(e){e.executeSql(t,o,function(e,n){a.resolve(n),e.executeSql(r,i,function(e,n){a.resolve(n)})})},function(e,n){a.reject(n)}),a.promise},deleteDB:function(t){var r=e.defer();return n.sqlitePlugin.deleteDatabase(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise}}}]),angular.module("ngCordova.plugins.statusbar",[]).factory("$cordovaStatusbar",[function(){return{overlaysWebView:function(e){return StatusBar.overlaysWebView(!!e)},style:function(e){switch(e){case 0:return StatusBar.styleDefault();case 1:return StatusBar.styleLightContent();case 2:return StatusBar.styleBlackTranslucent();case 3:return StatusBar.styleBlackOpaque();default:return StatusBar.styleDefault()}},styleColor:function(e){return StatusBar.backgroundColorByName(e)},styleHex:function(e){return StatusBar.backgroundColorByHexString(e)},hide:function(){return StatusBar.hide()},show:function(){return StatusBar.show()},isVisible:function(){return StatusBar.isVisible}}}]),angular.module("ngCordova.plugins.toast",[]).factory("$cordovaToast",["$q","$window",function(e,n){return{showShortTop:function(t){var r=e.defer();return n.plugins.toast.showShortTop(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},showShortCenter:function(t){var r=e.defer();return n.plugins.toast.showShortCenter(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},showShortBottom:function(t){var r=e.defer();return n.plugins.toast.showShortBottom(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},showLongTop:function(t){var r=e.defer();return n.plugins.toast.showLongTop(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},showLongCenter:function(t){var r=e.defer();return n.plugins.toast.showLongCenter(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},showLongBottom:function(t){var r=e.defer();return n.plugins.toast.showLongBottom(t,function(e){r.resolve(e)},function(e){r.reject(e)}),r.promise},show:function(t,r,o){var i=e.defer();return n.plugins.toast.show(t,r,o,function(e){i.resolve(e)},function(e){i.reject(e)}),i.promise}}}]),angular.module("ngCordova.plugins.touchid",[]).factory("$cordovaTouchID",["$q",function(e){return{checkSupport:function(){var n=e.defer();return window.cordova?touchid.checkSupport(function(e){n.resolve(e)},function(e){n.reject(e)}):n.reject("Not supported without cordova.js"),n.promise},authenticate:function(n){var t=e.defer();return window.cordova?touchid.authenticate(function(e){t.resolve(e)},function(e){t.reject(e)},n):t.reject("Not supported without cordova.js"),t.promise}}}]),angular.module("ngCordova.plugins.vibration",[]).factory("$cordovaVibration",[function(){return{vibrate:function(e){return navigator.notification.vibrate(e)},vibrateWithPattern:function(e,n){return navigator.notification.vibrateWithPattern(e,n)},cancelVibration:function(){return navigator.notification.cancelVibration()}}}]),angular.module("ngCordova.plugins.videoCapturePlus",[]).provider("$cordovaVideoCapturePlus",[function(){var e={};this.setLimit=function(n){e.limit=n},this.setMaxDuration=function(n){e.duration=n},this.setHighQuality=function(n){e.highquality=n},this.useFrontCamera=function(n){e.frontcamera=n},this.setPortraitOverlay=function(n){e.portraitOverlay=n},this.setLandscapeOverlay=function(n){e.landscapeOverlay=n},this.setOverlayText=function(n){e.overlayText=n},this.$get=["$q","$window",function(n,t){return{captureVideo:function(r){var o=n.defer();return t.plugins.videocaptureplus?(t.plugins.videocaptureplus.captureVideo(o.resolve,o.reject,angular.extend({},e,r)),o.promise):(o.resolve(null),o.promise)}}}]}]),angular.module("ngCordova.plugins.zip",[]).factory("$cordovaZip",["$q","$window",function(e,n){return{unzip:function(t,r){var o=e.defer();return n.zip.unzip(t,r,function(e){0===e?o.resolve():o.reject()},function(e){o.notify(e)}),o.promise}}}])}();
diff --git a/www/lib/ngCordova/package.json b/www/lib/ngCordova/package.json
new file mode 100644
index 00000000..1670270c
--- /dev/null
+++ b/www/lib/ngCordova/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "ng-cordova",
+ "private": false,
+ "main": "dist/ng-cordova",
+ "version": "0.1.15-alpha",
+ "repository": {
+ "url": "git://github.com/driftyco/ng-cordova.git"
+ },
+ "devDependencies": {
+ "gulp": "^3.7.0",
+ "gulp-concat": "^2.2.0",
+ "gulp-footer": "^1.0.4",
+ "gulp-header": "^1.0.2",
+ "gulp-jshint": "^1.6.1",
+ "gulp-prettify": "^0.3.0",
+ "gulp-rename": "^1.2.0",
+ "gulp-shell": "^0.2.10",
+ "gulp-uglify": "^0.2.1",
+ "jshint-stylish": "^0.4.0",
+ "karma": "^0.12.16",
+ "karma-chrome-launcher": "~0.1.2",
+ "karma-coverage": "~0.2.6",
+ "karma-jasmine": "~0.1.5",
+ "karma-phantomjs-launcher": "~0.1.2",
+ "minimist": "^0.1.0"
+ },
+ "licenses": [
+ {
+ "type": "MIT"
+ }
+ ],
+ "scripts": {
+ "test": "gulp karma --browsers=PhantomJS --reporters=progress"
+ },
+ "dependencies": {
+ "conventional-changelog": "0.0.11",
+ "fs": "0.0.2",
+ "q": "^1.1.2"
+ }
+}