arnaucube
arnaucube/commonroutesAppPublic Self-hosted repository
commonroutesApp/www/lib/ngCordova/dist/ng-cordova.js
www/lib/ngCordova/dist/ng-cordova.jsRaw
   1/*!
   2 * ngCordova
   3 * v0.1.27-alpha
   4 * Copyright 2015 Drifty Co. http://drifty.com/
   5 * See LICENSE in this repository for license information
   6 */
   7(function(){
   8
   9angular.module('ngCordova', [
  10  'ngCordova.plugins'
  11]);
  12
  13// install   :      cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-3dtouch.git
  14// link      :      https://github.com/EddyVerbruggen/cordova-plugin-3dtouch
  15
  16angular.module('ngCordova.plugins.3dtouch', [])
  17
  18    .factory('$cordova3DTouch', ['$q', function($q) {
  19        var quickActions = [];
  20        var quickActionHandler = {};
  21
  22        var createQuickActionHandler = function(quickActionHandler) {
  23            return function (payload) {
  24                for (var key in quickActionHandler) {
  25                    if (payload.type === key) {
  26                        quickActionHandler[key]();
  27                    }
  28                }
  29            };
  30        };
  31
  32        return {
  33            /*
  34             * Checks if Cordova 3D touch is present and loaded
  35             *
  36             * @return   promise
  37             */
  38            isAvailable: function () {
  39                var deferred = $q.defer();
  40                if (!window.cordova) {
  41                    deferred.reject('Not supported in browser');
  42                } else {
  43                    if (!window.ThreeDeeTouch) {
  44                        deferred.reject('Could not find 3D touch plugin');
  45                    } else {
  46                        window.ThreeDeeTouch.isAvailable(function (value) {
  47                            deferred.resolve(value);
  48                        }, function (err) {
  49                            deferred.reject(err);
  50                        });
  51                    }
  52                }
  53
  54                return deferred.promise;
  55            },
  56
  57            /*
  58             * Add a quick action to menu
  59             *
  60             * @param    string type
  61             * @param    string title
  62             * @param    string iconType (optional)
  63             * @param    string subtitle (optional)
  64             * @param    function callback (optional)
  65             * @return   promise
  66             */
  67            addQuickAction: function(type, title, iconType, iconTemplate, subtitle, callback) {
  68                var deferred = $q.defer();
  69
  70                var quickAction = {
  71                    type: type,
  72                    title: title,
  73                    subtitle: subtitle
  74                };
  75
  76                if (iconType) {
  77                    quickAction.iconType = iconType;
  78                }
  79
  80                if (iconTemplate) {
  81                    quickAction.iconTemplate = iconTemplate;
  82                }
  83
  84                this.isAvailable().then(function() {
  85                    quickActions.push(quickAction);
  86                    quickActionHandler[type] = callback;
  87                    window.ThreeDeeTouch.configureQuickActions(quickActions);
  88                    window.ThreeDeeTouch.onHomeIconPressed = createQuickActionHandler(quickActionHandler);
  89                    deferred.resolve(quickActions);
  90                },
  91                function(err) {
  92                    deferred.reject(err);
  93                });
  94
  95                return deferred.promise;
  96            },
  97
  98            /*
  99             * Add a quick action handler. Used for static quick actions
 100             *
 101             * @param    string type
 102             * @param    function callback
 103             * @return   promise
 104             */
 105            addQuickActionHandler: function(type, callback) {
 106                var deferred = $q.defer();
 107
 108                this.isAvailable().then(function() {
 109                    quickActionHandler[type] = callback;
 110                    window.ThreeDeeTouch.onHomeIconPressed = createQuickActionHandler(quickActionHandler);
 111                    deferred.resolve(true);
 112                },
 113                function(err) {
 114                    deferred.reject(err);
 115                });
 116
 117                return deferred.promise;
 118            },
 119
 120            /*
 121             * Enable link preview popup when force touch is appled to link elements
 122             *
 123             * @return   bool
 124             */
 125            enableLinkPreview: function() {
 126                var deferred = $q.defer();
 127
 128                this.isAvailable().then(function() {
 129                    window.ThreeDeeTouch.enableLinkPreview();
 130                        deferred.resolve(true);
 131                },
 132                function(err) {
 133                    deferred.reject(err);
 134                });
 135
 136                return deferred.promise;
 137            },
 138
 139            /*
 140             * Add a hanlder function for force touch events,
 141             *
 142             * @param    function callback
 143             * @return   promise
 144             */
 145            addForceTouchHandler: function(callback) {
 146                var deferred = $q.defer();
 147
 148                this.isAvailable().then(function() {
 149                    window.ThreeDeeTouch.watchForceTouches(callback);
 150                    deferred.resolve(true);
 151                },
 152                function(err) {
 153                    deferred.reject(err);
 154                });
 155
 156                return deferred.promise;
 157            }
 158        };
 159    }]);
 160
 161// install  :     cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-actionsheet.git
 162// link     :     https://github.com/EddyVerbruggen/cordova-plugin-actionsheet
 163
 164angular.module('ngCordova.plugins.actionSheet', [])
 165
 166  .factory('$cordovaActionSheet', ['$q', '$window', function ($q, $window) {
 167
 168    return {
 169      show: function (options) {
 170        var q = $q.defer();
 171
 172        $window.plugins.actionsheet.show(options, function (result) {
 173          q.resolve(result);
 174        });
 175
 176        return q.promise;
 177      },
 178
 179      hide: function () {
 180        return $window.plugins.actionsheet.hide();
 181      }
 182    };
 183  }]);
 184
 185// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-plugin-admob.git
 186// link     :     https://github.com/floatinghotpot/cordova-plugin-admob
 187
 188angular.module('ngCordova.plugins.adMob', [])
 189
 190  .factory('$cordovaAdMob', ['$q', '$window', function ($q, $window) {
 191
 192    return {
 193      createBannerView: function (options) {
 194        var d = $q.defer();
 195
 196        $window.plugins.AdMob.createBannerView(options, function () {
 197          d.resolve();
 198        }, function () {
 199          d.reject();
 200        });
 201
 202        return d.promise;
 203      },
 204
 205      createInterstitialView: function (options) {
 206        var d = $q.defer();
 207
 208        $window.plugins.AdMob.createInterstitialView(options, function () {
 209          d.resolve();
 210        }, function () {
 211          d.reject();
 212        });
 213
 214        return d.promise;
 215      },
 216
 217      requestAd: function (options) {
 218        var d = $q.defer();
 219
 220        $window.plugins.AdMob.requestAd(options, function () {
 221          d.resolve();
 222        }, function () {
 223          d.reject();
 224        });
 225
 226        return d.promise;
 227      },
 228
 229      showAd: function (options) {
 230        var d = $q.defer();
 231
 232        $window.plugins.AdMob.showAd(options, function () {
 233          d.resolve();
 234        }, function () {
 235          d.reject();
 236        });
 237
 238        return d.promise;
 239      },
 240
 241      requestInterstitialAd: function (options) {
 242        var d = $q.defer();
 243
 244        $window.plugins.AdMob.requestInterstitialAd(options, function () {
 245          d.resolve();
 246        }, function () {
 247          d.reject();
 248        });
 249
 250        return d.promise;
 251      }
 252    };
 253  }]);
 254
 255// install  :     cordova plugin add https://github.com/ohh2ahh/AppAvailability.git
 256// link     :     https://github.com/ohh2ahh/AppAvailability
 257
 258/* globals appAvailability: true */
 259angular.module('ngCordova.plugins.appAvailability', [])
 260
 261  .factory('$cordovaAppAvailability', ['$q', function ($q) {
 262
 263    return {
 264      check: function (urlScheme) {
 265        var q = $q.defer();
 266
 267        appAvailability.check(urlScheme, function (result) {
 268          q.resolve(result);
 269        }, function (err) {
 270          q.reject(err);
 271        });
 272
 273        return q.promise;
 274      }
 275    };
 276  }]);
 277
 278// install  :     cordova plugin add https://github.com/pushandplay/cordova-plugin-apprate.git
 279// link     :     https://github.com/pushandplay/cordova-plugin-apprate
 280
 281/* globals AppRate: true */
 282angular.module('ngCordova.plugins.appRate', [])
 283
 284  .provider('$cordovaAppRate', [function () {
 285
 286    /**
 287      * Set defaults settings to AppRate
 288      *
 289      * @param {Object} defaults - AppRate default settings
 290      * @param {string} defaults.language
 291      * @param {string} defaults.appName
 292      * @param {boolean} defaults.promptForNewVersion
 293      * @param {boolean} defaults.openStoreInApp
 294      * @param {number} defaults.usesUntilPrompt
 295      * @param {boolean} defaults.useCustomRateDialog
 296      * @param {string} defaults.iosURL
 297      * @param {string} defaults.androidURL
 298      * @param {string} defaults.blackberryURL
 299      * @param {string} defaults.windowsURL
 300      */
 301    this.setPreferences = function (defaults) {
 302      if (!defaults || !angular.isObject(defaults)) {
 303        return;
 304      }
 305
 306      AppRate.preferences.useLanguage = defaults.language || null;
 307      AppRate.preferences.displayAppName = defaults.appName || '';
 308      AppRate.preferences.promptAgainForEachNewVersion = defaults.promptForNewVersion || true;
 309      AppRate.preferences.openStoreInApp = defaults.openStoreInApp || false;
 310      AppRate.preferences.usesUntilPrompt = defaults.usesUntilPrompt || 3;
 311      AppRate.preferences.useCustomRateDialog = defaults.useCustomRateDialog || false;
 312      AppRate.preferences.storeAppURL.ios = defaults.iosURL || null;
 313      AppRate.preferences.storeAppURL.android = defaults.androidURL || null;
 314      AppRate.preferences.storeAppURL.blackberry = defaults.blackberryURL || null;
 315      AppRate.preferences.storeAppURL.windows8 = defaults.windowsURL || null;
 316    };
 317
 318    /**
 319      * Set custom locale
 320      *
 321      * @param {Object} customObj
 322      * @param {string} customObj.title
 323      * @param {string} customObj.message
 324      * @param {string} customObj.cancelButtonLabel
 325      * @param {string} customObj.laterButtonLabel
 326      * @param {string} customObj.rateButtonLabel
 327      */
 328    this.setCustomLocale = function (customObj) {
 329      var strings = {
 330        title: 'Rate %@',
 331        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!',
 332        cancelButtonLabel: 'No, Thanks',
 333        laterButtonLabel: 'Remind Me Later',
 334        rateButtonLabel: 'Rate It Now'
 335      };
 336
 337      strings = angular.extend(strings, customObj);
 338
 339      AppRate.preferences.customLocale = strings;
 340    };
 341
 342    this.$get = ['$q', function ($q) {
 343      return {
 344        promptForRating: function (immediate) {
 345          var q = $q.defer();
 346          var prompt = AppRate.promptForRating(immediate);
 347          q.resolve(prompt);
 348
 349          return q.promise;
 350        },
 351
 352        navigateToAppStore: function () {
 353          var q = $q.defer();
 354          var navigate = AppRate.navigateToAppStore();
 355          q.resolve(navigate);
 356
 357          return q.promise;
 358        },
 359
 360        onButtonClicked: function (cb) {
 361          AppRate.preferences.callbacks.onButtonClicked = cb.bind(this);
 362        },
 363
 364        onRateDialogShow: function (cb) {
 365          AppRate.preferences.callbacks.onRateDialogShow = cb.bind(this);
 366        }
 367      };
 368    }];
 369  }]);
 370
 371// install   :     cordova plugin add https://github.com/whiteoctober/cordova-plugin-app-version.git
 372// link      :     https://github.com/whiteoctober/cordova-plugin-app-version
 373
 374angular.module('ngCordova.plugins.appVersion', [])
 375
 376  .factory('$cordovaAppVersion', ['$q', function ($q) {
 377
 378    return {
 379      getAppName: function () {
 380        var q = $q.defer();
 381        cordova.getAppVersion.getAppName(function (name) {
 382          q.resolve(name);
 383        });
 384
 385        return q.promise;
 386      },
 387
 388      getPackageName: function () {
 389        var q = $q.defer();
 390        cordova.getAppVersion.getPackageName(function (pack) {
 391          q.resolve(pack);
 392        });
 393
 394        return q.promise;
 395      },
 396
 397      getVersionNumber: function () {
 398        var q = $q.defer();
 399        cordova.getAppVersion.getVersionNumber(function (version) {
 400          q.resolve(version);
 401        });
 402
 403        return q.promise;
 404      },
 405
 406      getVersionCode: function () {
 407        var q = $q.defer();
 408        cordova.getAppVersion.getVersionCode(function (code) {
 409          q.resolve(code);
 410        });
 411
 412        return q.promise;
 413      }
 414    };
 415  }]);
 416
 417// install   :     cordova plugin add https://github.com/christocracy/cordova-plugin-background-geolocation.git
 418// link      :     https://github.com/christocracy/cordova-plugin-background-geolocation
 419
 420angular.module('ngCordova.plugins.backgroundGeolocation', [])
 421
 422  .factory('$cordovaBackgroundGeolocation', ['$q', '$window', function ($q, $window) {
 423
 424    return {
 425
 426      init: function () {
 427        $window.navigator.geolocation.getCurrentPosition(function (location) {
 428          return location;
 429        });
 430      },
 431
 432      configure: function (options) {
 433
 434        this.init();
 435        var q = $q.defer();
 436
 437        $window.plugins.backgroundGeoLocation.configure(
 438          function (result) {
 439            q.notify(result);
 440            $window.plugins.backgroundGeoLocation.finish();
 441          },
 442          function (err) {
 443            q.reject(err);
 444          }, options);
 445
 446        this.start();
 447
 448        return q.promise;
 449      },
 450
 451      start: function () {
 452        var q = $q.defer();
 453
 454        $window.plugins.backgroundGeoLocation.start(
 455          function (result) {
 456            q.resolve(result);
 457          },
 458          function (err) {
 459            q.reject(err);
 460          });
 461
 462        return q.promise;
 463      },
 464
 465      stop: function () {
 466        var q = $q.defer();
 467
 468        $window.plugins.backgroundGeoLocation.stop(
 469          function (result) {
 470            q.resolve(result);
 471          },
 472          function (err) {
 473            q.reject(err);
 474          });
 475
 476        return q.promise;
 477      }
 478    };
 479  }
 480
 481  ]);
 482
 483// install  :     cordova plugin add https://github.com/katzer/cordova-plugin-badge.git
 484// link     :     https://github.com/katzer/cordova-plugin-badge
 485
 486angular.module('ngCordova.plugins.badge', [])
 487
 488  .factory('$cordovaBadge', ['$q', function ($q) {
 489
 490    return {
 491      hasPermission: function () {
 492        var q = $q.defer();
 493        cordova.plugins.notification.badge.hasPermission(function (permission) {
 494          if (permission) {
 495            q.resolve(true);
 496          } else {
 497            q.reject('You do not have permission');
 498          }
 499        });
 500
 501        return q.promise;
 502      },
 503
 504      promptForPermission: function () {
 505        return cordova.plugins.notification.badge.promptForPermission();
 506      },
 507
 508      set: function (badge, callback, scope) {
 509        var q = $q.defer();
 510
 511        cordova.plugins.notification.badge.hasPermission(function (permission) {
 512          if (permission) {
 513            q.resolve(
 514              cordova.plugins.notification.badge.set(badge, callback, scope)
 515            );
 516          } else {
 517            q.reject('You do not have permission to set Badge');
 518          }
 519        });
 520        return q.promise;
 521      },
 522
 523      get: function () {
 524        var q = $q.defer();
 525        cordova.plugins.notification.badge.hasPermission(function (permission) {
 526          if (permission) {
 527            cordova.plugins.notification.badge.get(function (badge) {
 528              q.resolve(badge);
 529            });
 530          } else {
 531            q.reject('You do not have permission to get Badge');
 532          }
 533        });
 534
 535        return q.promise;
 536      },
 537
 538      clear: function (callback, scope) {
 539        var q = $q.defer();
 540
 541        cordova.plugins.notification.badge.hasPermission(function (permission) {
 542          if (permission) {
 543            q.resolve(cordova.plugins.notification.badge.clear(callback, scope));
 544          } else {
 545            q.reject('You do not have permission to clear Badge');
 546          }
 547        });
 548        return q.promise;
 549      },
 550
 551      increase: function (count, callback, scope) {
 552        var q = $q.defer();
 553
 554        this.hasPermission().then(function (){
 555          q.resolve(
 556            cordova.plugins.notification.badge.increase(count, callback, scope)
 557          );
 558        }, function (){
 559          q.reject('You do not have permission to increase Badge');
 560        }) ;
 561
 562        return q.promise;
 563      },
 564
 565      decrease: function (count, callback, scope) {
 566        var q = $q.defer();
 567
 568        this.hasPermission().then(function (){
 569          q.resolve(
 570            cordova.plugins.notification.badge.decrease(count, callback, scope)
 571          );
 572        }, function (){
 573          q.reject('You do not have permission to decrease Badge');
 574        }) ;
 575
 576        return q.promise;
 577      },
 578
 579      configure: function (config) {
 580        return cordova.plugins.notification.badge.configure(config);
 581      }
 582    };
 583  }]);
 584
 585// install  :    cordova plugin add https://github.com/phonegap/phonegap-plugin-barcodescanner.git
 586// link     :    https://github.com/phonegap/phonegap-plugin-barcodescanner
 587
 588angular.module('ngCordova.plugins.barcodeScanner', [])
 589
 590  .factory('$cordovaBarcodeScanner', ['$q', function ($q) {
 591
 592    return {
 593      scan: function (config) {
 594        var q = $q.defer();
 595
 596        cordova.plugins.barcodeScanner.scan(function (result) {
 597          q.resolve(result);
 598        }, function (err) {
 599          q.reject(err);
 600        }, config);
 601
 602        return q.promise;
 603      },
 604
 605      encode: function (type, data) {
 606        var q = $q.defer();
 607        type = type || 'TEXT_TYPE';
 608
 609        cordova.plugins.barcodeScanner.encode(type, data, function (result) {
 610          q.resolve(result);
 611        }, function (err) {
 612          q.reject(err);
 613        });
 614
 615        return q.promise;
 616      }
 617    };
 618  }]);
 619
 620//  install   :   cordova plugin add cordova-plugin-battery-status
 621//  link      :   https://github.com/apache/cordova-plugin-battery-status
 622
 623angular.module('ngCordova.plugins.batteryStatus', [])
 624
 625  .factory('$cordovaBatteryStatus', ['$rootScope', '$window', '$timeout', function ($rootScope, $window, $timeout) {
 626
 627    /**
 628      * @param {string} status
 629      */
 630    var batteryStatus = function (status) {
 631      $timeout(function () {
 632        $rootScope.$broadcast('$cordovaBatteryStatus:status', status);
 633      });
 634    };
 635
 636    /**
 637      * @param {string} status
 638      */
 639    var batteryCritical = function (status) {
 640      $timeout(function () {
 641        $rootScope.$broadcast('$cordovaBatteryStatus:critical', status);
 642      });
 643    };
 644
 645    /**
 646      * @param {string} status
 647      */
 648    var batteryLow = function (status) {
 649      $timeout(function () {
 650        $rootScope.$broadcast('$cordovaBatteryStatus:low', status);
 651      });
 652    };
 653
 654    document.addEventListener('deviceready', function () {
 655      if (navigator.battery) {
 656        $window.addEventListener('batterystatus', batteryStatus, false);
 657        $window.addEventListener('batterycritical', batteryCritical, false);
 658        $window.addEventListener('batterylow', batteryLow, false);
 659
 660      }
 661    }, false);
 662    return true;
 663  }])
 664  .run(['$injector', function ($injector) {
 665    $injector.get('$cordovaBatteryStatus'); //ensure the factory and subsequent event listeners get initialised
 666  }]);
 667
 668// install   :  cordova plugin add https://github.com/petermetz/cordova-plugin-ibeacon.git
 669// link      :  https://github.com/petermetz/cordova-plugin-ibeacon
 670
 671angular.module('ngCordova.plugins.beacon', [])
 672
 673  .factory('$cordovaBeacon', ['$window', '$rootScope', '$timeout', '$q', function ($window, $rootScope, $timeout, $q) {
 674    var callbackDidDetermineStateForRegion = null;
 675    var callbackDidStartMonitoringForRegion = null;
 676    var callbackDidExitRegion = null;
 677    var callbackDidEnterRegion = null;
 678    var callbackDidRangeBeaconsInRegion = null;
 679    var callbackPeripheralManagerDidStartAdvertising = null;
 680    var callbackPeripheralManagerDidUpdateState = null;
 681    var callbackDidChangeAuthorizationStatus = null;
 682
 683    document.addEventListener('deviceready', function () {
 684      if ($window.cordova &&
 685          $window.cordova.plugins &&
 686          $window.cordova.plugins.locationManager) {
 687        var delegate = new $window.cordova.plugins.locationManager.Delegate();
 688
 689        delegate.didDetermineStateForRegion = function (pluginResult) {
 690          $timeout(function () {
 691            $rootScope.$broadcast('$cordovaBeacon:didDetermineStateForRegion', pluginResult);
 692          });
 693
 694          if (callbackDidDetermineStateForRegion) {
 695            callbackDidDetermineStateForRegion(pluginResult);
 696          }
 697        };
 698
 699        delegate.didStartMonitoringForRegion = function (pluginResult) {
 700          $timeout(function () {
 701            $rootScope.$broadcast('$cordovaBeacon:didStartMonitoringForRegion', pluginResult);
 702          });
 703
 704          if (callbackDidStartMonitoringForRegion) {
 705            callbackDidStartMonitoringForRegion(pluginResult);
 706          }
 707        };
 708
 709        delegate.didExitRegion = function (pluginResult) {
 710          $timeout(function () {
 711            $rootScope.$broadcast('$cordovaBeacon:didExitRegion', pluginResult);
 712          });
 713
 714          if (callbackDidExitRegion) {
 715            callbackDidExitRegion(pluginResult);
 716          }
 717        };
 718
 719        delegate.didEnterRegion = function (pluginResult) {
 720          $timeout(function () {
 721            $rootScope.$broadcast('$cordovaBeacon:didEnterRegion', pluginResult);
 722          });
 723
 724          if (callbackDidEnterRegion) {
 725            callbackDidEnterRegion(pluginResult);
 726          }
 727        };
 728
 729        delegate.didRangeBeaconsInRegion = function (pluginResult) {
 730          $timeout(function () {
 731            $rootScope.$broadcast('$cordovaBeacon:didRangeBeaconsInRegion', pluginResult);
 732          });
 733
 734          if (callbackDidRangeBeaconsInRegion) {
 735            callbackDidRangeBeaconsInRegion(pluginResult);
 736          }
 737        };
 738
 739        delegate.peripheralManagerDidStartAdvertising = function (pluginResult) {
 740          $timeout(function () {
 741            $rootScope.$broadcast('$cordovaBeacon:peripheralManagerDidStartAdvertising', pluginResult);
 742          });
 743
 744          if (callbackPeripheralManagerDidStartAdvertising) {
 745            callbackPeripheralManagerDidStartAdvertising(pluginResult);
 746          }
 747        };
 748
 749        delegate.peripheralManagerDidUpdateState = function (pluginResult) {
 750          $timeout(function () {
 751            $rootScope.$broadcast('$cordovaBeacon:peripheralManagerDidUpdateState', pluginResult);
 752          });
 753
 754          if (callbackPeripheralManagerDidUpdateState) {
 755            callbackPeripheralManagerDidUpdateState(pluginResult);
 756          }
 757        };
 758
 759        delegate.didChangeAuthorizationStatus = function (status) {
 760          $timeout(function () {
 761            $rootScope.$broadcast('$cordovaBeacon:didChangeAuthorizationStatus', status);
 762          });
 763
 764          if (callbackDidChangeAuthorizationStatus) {
 765            callbackDidChangeAuthorizationStatus(status);
 766          }
 767        };
 768
 769        $window.cordova.plugins.locationManager.setDelegate(delegate);
 770      }
 771    }, false);
 772
 773    return {
 774      setCallbackDidDetermineStateForRegion: function (callback) {
 775        callbackDidDetermineStateForRegion = callback;
 776      },
 777      setCallbackDidStartMonitoringForRegion: function (callback) {
 778        callbackDidStartMonitoringForRegion = callback;
 779      },
 780      setCallbackDidExitRegion: function (callback) {
 781        callbackDidExitRegion = callback;
 782      },
 783      setCallbackDidEnterRegion: function (callback) {
 784        callbackDidEnterRegion = callback;
 785      },
 786      setCallbackDidRangeBeaconsInRegion: function (callback) {
 787        callbackDidRangeBeaconsInRegion = callback;
 788      },
 789      setCallbackPeripheralManagerDidStartAdvertising: function (callback) {
 790        callbackPeripheralManagerDidStartAdvertising = callback;
 791      },
 792      setCallbackPeripheralManagerDidUpdateState: function (callback) {
 793        callbackPeripheralManagerDidUpdateState = callback;
 794      },
 795      setCallbackDidChangeAuthorizationStatus: function (callback) {
 796        callbackDidChangeAuthorizationStatus = callback;
 797      },
 798      createBeaconRegion: function (identifier, uuid, major, minor, notifyEntryStateOnDisplay) {
 799        major = major || undefined;
 800        minor = minor || undefined;
 801
 802        return new $window.cordova.plugins.locationManager.BeaconRegion(
 803          identifier,
 804          uuid,
 805          major,
 806          minor,
 807          notifyEntryStateOnDisplay
 808        );
 809      },
 810      isBluetoothEnabled: function () {
 811        return $q.when($window.cordova.plugins.locationManager.isBluetoothEnabled());
 812      },
 813      enableBluetooth: function () {
 814        return $q.when($window.cordova.plugins.locationManager.enableBluetooth());
 815      },
 816      disableBluetooth: function () {
 817        return $q.when($window.cordova.plugins.locationManager.disableBluetooth());
 818      },
 819      startMonitoringForRegion: function (region) {
 820        return $q.when($window.cordova.plugins.locationManager.startMonitoringForRegion(region));
 821      },
 822      stopMonitoringForRegion: function (region) {
 823        return $q.when($window.cordova.plugins.locationManager.stopMonitoringForRegion(region));
 824      },
 825      requestStateForRegion: function (region) {
 826        return $q.when($window.cordova.plugins.locationManager.requestStateForRegion(region));
 827      },
 828      startRangingBeaconsInRegion: function (region) {
 829        return $q.when($window.cordova.plugins.locationManager.startRangingBeaconsInRegion(region));
 830      },
 831      stopRangingBeaconsInRegion: function (region) {
 832        return $q.when($window.cordova.plugins.locationManager.stopRangingBeaconsInRegion(region));
 833      },
 834      getAuthorizationStatus: function () {
 835        return $q.when($window.cordova.plugins.locationManager.getAuthorizationStatus());
 836      },
 837      requestWhenInUseAuthorization: function () {
 838        return $q.when($window.cordova.plugins.locationManager.requestWhenInUseAuthorization());
 839      },
 840      requestAlwaysAuthorization: function () {
 841        return $q.when($window.cordova.plugins.locationManager.requestAlwaysAuthorization());
 842      },
 843      getMonitoredRegions: function () {
 844        return $q.when($window.cordova.plugins.locationManager.getMonitoredRegions());
 845      },
 846      getRangedRegions: function () {
 847        return $q.when($window.cordova.plugins.locationManager.getRangedRegions());
 848      },
 849      isRangingAvailable: function () {
 850        return $q.when($window.cordova.plugins.locationManager.isRangingAvailable());
 851      },
 852      isMonitoringAvailableForClass: function (region) {
 853        return $q.when($window.cordova.plugins.locationManager.isMonitoringAvailableForClass(region));
 854      },
 855      startAdvertising: function (region, measuredPower) {
 856        return $q.when($window.cordova.plugins.locationManager.startAdvertising(region, measuredPower));
 857      },
 858      stopAdvertising: function () {
 859        return $q.when($window.cordova.plugins.locationManager.stopAdvertising());
 860      },
 861      isAdvertisingAvailable: function () {
 862        return $q.when($window.cordova.plugins.locationManager.isAdvertisingAvailable());
 863      },
 864      isAdvertising: function () {
 865        return $q.when($window.cordova.plugins.locationManager.isAdvertising());
 866      },
 867      disableDebugLogs: function () {
 868        return $q.when($window.cordova.plugins.locationManager.disableDebugLogs());
 869      },
 870      enableDebugNotifications: function () {
 871        return $q.when($window.cordova.plugins.locationManager.enableDebugNotifications());
 872      },
 873      disableDebugNotifications: function () {
 874        return $q.when($window.cordova.plugins.locationManager.disableDebugNotifications());
 875      },
 876      enableDebugLogs: function () {
 877        return $q.when($window.cordova.plugins.locationManager.enableDebugLogs());
 878      },
 879      appendToDeviceLog: function (message) {
 880        return $q.when($window.cordova.plugins.locationManager.appendToDeviceLog(message));
 881      }
 882    };
 883  }]);
 884
 885//  install   :   cordova plugin add https://github.com/don/cordova-plugin-ble-central.git
 886//  link      :   https://github.com/don/cordova-plugin-ble-central
 887
 888/* globals ble: true */
 889angular.module('ngCordova.plugins.ble', [])
 890
 891  .factory('$cordovaBLE', ['$q', '$timeout', '$log', function ($q, $timeout, $log) {
 892
 893    return {
 894      scan: function (services, seconds) {
 895        var q = $q.defer();
 896
 897        ble.startScan(services, function (result) {
 898          q.notify(result);
 899        }, function (error) {
 900          q.reject(error);
 901        });
 902
 903        $timeout(function () {
 904            ble.stopScan(function () {
 905              q.resolve();
 906            }, function (error) {
 907              q.reject(error);
 908            });
 909        }, seconds*1000);
 910
 911        return q.promise;
 912      },
 913
 914      startScan: function (services, callback, errorCallback) {
 915        return ble.startScan(services, callback, errorCallback);
 916      },
 917
 918      stopScan: function () {
 919        var q = $q.defer();
 920        ble.stopScan(function () {
 921          q.resolve();
 922        }, function (error) {
 923          q.reject(error);
 924        });
 925        return q.promise;
 926      },
 927
 928      connect: function (deviceID) {
 929        var q = $q.defer();
 930        ble.connect(deviceID, function (result) {
 931          q.resolve(result);
 932        }, function (error) {
 933          q.reject(error);
 934        });
 935        return q.promise;
 936      },
 937
 938      disconnect: function (deviceID) {
 939        var q = $q.defer();
 940        ble.disconnect(deviceID, function (result) {
 941          q.resolve(result);
 942        }, function (error) {
 943          q.reject(error);
 944        });
 945        return q.promise;
 946      },
 947
 948      read: function (deviceID, serviceUUID, characteristicUUID) {
 949        var q = $q.defer();
 950        ble.read(deviceID, serviceUUID, characteristicUUID, function (result) {
 951          q.resolve(result);
 952        }, function (error) {
 953          q.reject(error);
 954        });
 955        return q.promise;
 956      },
 957
 958      write: function (deviceID, serviceUUID, characteristicUUID, data) {
 959        var q = $q.defer();
 960        ble.write(deviceID, serviceUUID, characteristicUUID, data, function (result) {
 961          q.resolve(result);
 962        }, function (error) {
 963          q.reject(error);
 964        });
 965        return q.promise;
 966      },
 967
 968      writeWithoutResponse: function (deviceID, serviceUUID, characteristicUUID, data) {
 969        var q = $q.defer();
 970        ble.writeWithoutResponse(deviceID, serviceUUID, characteristicUUID, data, function (result) {
 971          q.resolve(result);
 972        }, function (error) {
 973          q.reject(error);
 974        });
 975        return q.promise;
 976      },
 977
 978      writeCommand: function (deviceID, serviceUUID, characteristicUUID, data) {
 979        $log.warning('writeCommand is deprecated, use writeWithoutResponse');
 980        return this.writeWithoutResponse(deviceID, serviceUUID, characteristicUUID, data);
 981      },
 982
 983      startNotification: function (deviceID, serviceUUID, characteristicUUID, callback, errorCallback) {
 984        return ble.startNotification(deviceID, serviceUUID, characteristicUUID, callback, errorCallback);
 985      },
 986
 987      stopNotification: function (deviceID, serviceUUID, characteristicUUID) {
 988        var q = $q.defer();
 989        ble.stopNotification(deviceID, serviceUUID, characteristicUUID, function (result) {
 990          q.resolve(result);
 991        }, function (error) {
 992          q.reject(error);
 993        });
 994        return q.promise;
 995      },
 996
 997      isConnected: function (deviceID) {
 998        var q = $q.defer();
 999        ble.isConnected(deviceID, function (result) {
1000          q.resolve(result);
1001        }, function (error) {
1002          q.reject(error);
1003        });
1004        return q.promise;
1005      },
1006
1007      enable: function () {
1008        var q = $q.defer();
1009        ble.enable(function (result) {
1010          q.resolve(result);
1011        }, function (error) {
1012          q.reject(error);
1013        });
1014        return q.promise;
1015      },
1016
1017      isEnabled: function () {
1018        var q = $q.defer();
1019        ble.isEnabled(function (result) {
1020          q.resolve(result);
1021        }, function (error) {
1022          q.reject(error);
1023        });
1024        return q.promise;
1025      }
1026    };
1027  }]);
1028
1029// install   :     cordova plugin add https://github.com/don/BluetoothSerial.git
1030// link      :     https://github.com/don/BluetoothSerial
1031
1032angular.module('ngCordova.plugins.bluetoothSerial', [])
1033
1034  .factory('$cordovaBluetoothSerial', ['$q', '$window', function ($q, $window) {
1035
1036    return {
1037      connect: function (address) {
1038        var q = $q.defer();
1039        var disconnectionPromise = $q.defer();
1040        var isConnected = false;
1041        $window.bluetoothSerial.connect(address, function () {
1042          isConnected = true;
1043          q.resolve(disconnectionPromise);
1044        }, function (error) {
1045          if(isConnected === false) {
1046            disconnectionPromise.reject(error);
1047          }
1048          q.reject(error);
1049        });
1050        return q.promise;
1051      },
1052
1053      // not supported on iOS
1054      connectInsecure: function (address) {
1055        var q = $q.defer();
1056        $window.bluetoothSerial.connectInsecure(address, function () {
1057          q.resolve();
1058        }, function (error) {
1059          q.reject(error);
1060        });
1061        return q.promise;
1062      },
1063
1064      disconnect: function () {
1065        var q = $q.defer();
1066        $window.bluetoothSerial.disconnect(function () {
1067          q.resolve();
1068        }, function (error) {
1069          q.reject(error);
1070        });
1071        return q.promise;
1072      },
1073
1074      list: function () {
1075        var q = $q.defer();
1076        $window.bluetoothSerial.list(function (data) {
1077          q.resolve(data);
1078        }, function (error) {
1079          q.reject(error);
1080        });
1081        return q.promise;
1082      },
1083
1084      discoverUnpaired: function () {
1085        var q = $q.defer();
1086        $window.bluetoothSerial.discoverUnpaired(function (data) {
1087          q.resolve(data);
1088        }, function (error) {
1089          q.reject(error);
1090        });
1091        return q.promise;
1092      },
1093
1094      setDeviceDiscoveredListener: function () {
1095        var q = $q.defer();
1096        $window.bluetoothSerial.setDeviceDiscoveredListener(function (data) {
1097          q.notify(data);
1098        });
1099        return q.promise;
1100      },
1101
1102      clearDeviceDiscoveredListener: function () {
1103        $window.bluetoothSerial.clearDeviceDiscoveredListener();
1104      },
1105
1106      showBluetoothSettings: function () {
1107        var q = $q.defer();
1108        $window.bluetoothSerial.showBluetoothSettings(function () {
1109          q.resolve();
1110        }, function (error) {
1111          q.reject(error);
1112        });
1113        return q.promise;
1114      },
1115
1116      isEnabled: function () {
1117        var q = $q.defer();
1118        $window.bluetoothSerial.isEnabled(function () {
1119          q.resolve();
1120        }, function () {
1121          q.reject();
1122        });
1123        return q.promise;
1124      },
1125
1126      enable: function () {
1127        var q = $q.defer();
1128        $window.bluetoothSerial.enable(function () {
1129          q.resolve();
1130        }, function () {
1131          q.reject();
1132        });
1133        return q.promise;
1134      },
1135
1136      isConnected: function () {
1137        var q = $q.defer();
1138        $window.bluetoothSerial.isConnected(function () {
1139          q.resolve();
1140        }, function () {
1141          q.reject();
1142        });
1143        return q.promise;
1144      },
1145
1146      available: function () {
1147        var q = $q.defer();
1148        $window.bluetoothSerial.available(function (data) {
1149          q.resolve(data);
1150        }, function (error) {
1151          q.reject(error);
1152        });
1153        return q.promise;
1154      },
1155
1156      read: function () {
1157        var q = $q.defer();
1158        $window.bluetoothSerial.read(function (data) {
1159          q.resolve(data);
1160        }, function (error) {
1161          q.reject(error);
1162        });
1163        return q.promise;
1164      },
1165
1166      readUntil: function (delimiter) {
1167        var q = $q.defer();
1168        $window.bluetoothSerial.readUntil(delimiter, function (data) {
1169          q.resolve(data);
1170        }, function (error) {
1171          q.reject(error);
1172        });
1173        return q.promise;
1174      },
1175
1176      write: function (data) {
1177        var q = $q.defer();
1178        $window.bluetoothSerial.write(data, function () {
1179          q.resolve();
1180        }, function (error) {
1181          q.reject(error);
1182        });
1183        return q.promise;
1184      },
1185
1186      subscribe: function (delimiter) {
1187        var q = $q.defer();
1188        $window.bluetoothSerial.subscribe(delimiter, function (data) {
1189          q.notify(data);
1190        }, function (error) {
1191          q.reject(error);
1192        });
1193        return q.promise;
1194      },
1195
1196      subscribeRawData: function () {
1197        var q = $q.defer();
1198        $window.bluetoothSerial.subscribeRawData(function (data) {
1199          q.notify(data);
1200        }, function (error) {
1201          q.reject(error);
1202        });
1203        return q.promise;
1204      },
1205
1206      unsubscribe: function () {
1207        var q = $q.defer();
1208        $window.bluetoothSerial.unsubscribe(function () {
1209          q.resolve();
1210        }, function (error) {
1211          q.reject(error);
1212        });
1213        return q.promise;
1214      },
1215
1216      unsubscribeRawData: function () {
1217        var q = $q.defer();
1218        $window.bluetoothSerial.unsubscribeRawData(function () {
1219          q.resolve();
1220        }, function (error) {
1221          q.reject(error);
1222        });
1223        return q.promise;
1224      },
1225
1226      clear: function () {
1227        var q = $q.defer();
1228        $window.bluetoothSerial.clear(function () {
1229          q.resolve();
1230        }, function (error) {
1231          q.reject(error);
1232        });
1233        return q.promise;
1234      },
1235
1236      readRSSI: function () {
1237        var q = $q.defer();
1238        $window.bluetoothSerial.readRSSI(function (data) {
1239          q.resolve(data);
1240        }, function (error) {
1241          q.reject(error);
1242        });
1243        return q.promise;
1244      }
1245    };
1246  }]);
1247
1248// install  :    cordova plugin add https://github.com/fiscal-cliff/phonegap-plugin-brightness.git
1249// link     :    https://github.com/fiscal-cliff/phonegap-plugin-brightness
1250
1251angular.module('ngCordova.plugins.brightness', [])
1252
1253  .factory('$cordovaBrightness', ['$q', '$window', function ($q, $window) {
1254
1255    return {
1256      get: function () {
1257        var q = $q.defer();
1258
1259        if (!$window.cordova) {
1260          q.reject('Not supported without cordova.js');
1261        } else {
1262          $window.cordova.plugins.brightness.getBrightness(function (result) {
1263            q.resolve(result);
1264          }, function (err) {
1265            q.reject(err);
1266          });
1267        }
1268
1269        return q.promise;
1270      },
1271
1272      set: function (data) {
1273        var q = $q.defer();
1274
1275        if (!$window.cordova) {
1276          q.reject('Not supported without cordova.js');
1277        } else {
1278          $window.cordova.plugins.brightness.setBrightness(data, function (result) {
1279            q.resolve(result);
1280          }, function (err) {
1281            q.reject(err);
1282          });
1283        }
1284
1285        return q.promise;
1286      },
1287
1288      setKeepScreenOn: function (bool) {
1289        var q = $q.defer();
1290
1291        if (!$window.cordova) {
1292          q.reject('Not supported without cordova.js');
1293        } else {
1294          $window.cordova.plugins.brightness.setKeepScreenOn(bool, function (result) {
1295            q.resolve(result);
1296          }, function (err) {
1297            q.reject(err);
1298          });
1299        }
1300
1301        return q.promise;
1302      }
1303    };
1304  }]);
1305
1306
1307// install  :     cordova plugin add https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin.git
1308// link     :     https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin
1309
1310angular.module('ngCordova.plugins.calendar', [])
1311
1312  .factory('$cordovaCalendar', ['$q', '$window', function ($q, $window) {
1313    
1314    return {
1315      createCalendar: function (options) {
1316        var d = $q.defer(),
1317          createCalOptions = $window.plugins.calendar.getCreateCalendarOptions();
1318
1319        if (typeof options === 'string') {
1320          createCalOptions.calendarName = options;
1321        } else {
1322          createCalOptions = angular.extend(createCalOptions, options);
1323        }
1324
1325        $window.plugins.calendar.createCalendar(createCalOptions, function (message) {
1326          d.resolve(message);
1327        }, function (error) {
1328          d.reject(error);
1329        });
1330
1331        return d.promise;
1332      },
1333
1334      deleteCalendar: function (calendarName) {
1335        var d = $q.defer();
1336
1337        $window.plugins.calendar.deleteCalendar(calendarName, function (message) {
1338          d.resolve(message);
1339        }, function (error) {
1340          d.reject(error);
1341        });
1342
1343        return d.promise;
1344      },
1345
1346      createEvent: function (options) {
1347        var d = $q.defer(),
1348          defaultOptions = {
1349            title: null,
1350            location: null,
1351            notes: null,
1352            startDate: null,
1353            endDate: null
1354          };
1355
1356        defaultOptions = angular.extend(defaultOptions, options);
1357
1358        $window.plugins.calendar.createEvent(
1359          defaultOptions.title,
1360          defaultOptions.location,
1361          defaultOptions.notes,
1362          new Date(defaultOptions.startDate),
1363          new Date(defaultOptions.endDate),
1364          function (message) {
1365            d.resolve(message);
1366          }, function (error) {
1367            d.reject(error);
1368          }
1369        );
1370
1371        return d.promise;
1372      },
1373
1374      createEventWithOptions: function (options) {
1375        var d = $q.defer(),
1376          defaultOptionKeys = [],
1377          calOptions = window.plugins.calendar.getCalendarOptions(),
1378          defaultOptions = {
1379            title: null,
1380            location: null,
1381            notes: null,
1382            startDate: null,
1383            endDate: null
1384          };
1385
1386        defaultOptionKeys = Object.keys(defaultOptions);
1387
1388        for (var key in options) {
1389          if (defaultOptionKeys.indexOf(key) === -1) {
1390            calOptions[key] = options[key];
1391          } else {
1392            defaultOptions[key] = options[key];
1393          }
1394        }
1395
1396        $window.plugins.calendar.createEventWithOptions(
1397          defaultOptions.title,
1398          defaultOptions.location,
1399          defaultOptions.notes,
1400          new Date(defaultOptions.startDate),
1401          new Date(defaultOptions.endDate),
1402          calOptions,
1403          function (message) {
1404            d.resolve(message);
1405          }, function (error) {
1406            d.reject(error);
1407          }
1408        );
1409
1410        return d.promise;
1411      },
1412
1413      createEventInteractively: function (options) {
1414        var d = $q.defer(),
1415          defaultOptions = {
1416            title: null,
1417            location: null,
1418            notes: null,
1419            startDate: null,
1420            endDate: null
1421          };
1422
1423        defaultOptions = angular.extend(defaultOptions, options);
1424
1425        $window.plugins.calendar.createEventInteractively(
1426          defaultOptions.title,
1427          defaultOptions.location,
1428          defaultOptions.notes,
1429          new Date(defaultOptions.startDate),
1430          new Date(defaultOptions.endDate),
1431          function (message) {
1432            d.resolve(message);
1433          }, function (error) {
1434            d.reject(error);
1435          }
1436        );
1437
1438        return d.promise;
1439      },
1440
1441      createEventInNamedCalendar: function (options) {
1442        var d = $q.defer(),
1443          defaultOptions = {
1444            title: null,
1445            location: null,
1446            notes: null,
1447            startDate: null,
1448            endDate: null,
1449            calendarName: null
1450          };
1451
1452        defaultOptions = angular.extend(defaultOptions, options);
1453
1454        $window.plugins.calendar.createEventInNamedCalendar(
1455          defaultOptions.title,
1456          defaultOptions.location,
1457          defaultOptions.notes,
1458          new Date(defaultOptions.startDate),
1459          new Date(defaultOptions.endDate),
1460          defaultOptions.calendarName,
1461          function (message) {
1462            d.resolve(message);
1463          }, function (error) {
1464            d.reject(error);
1465          }
1466        );
1467
1468        return d.promise;
1469      },
1470
1471      findEvent: function (options) {
1472        var d = $q.defer(),
1473          defaultOptions = {
1474            title: null,
1475            location: null,
1476            notes: null,
1477            startDate: null,
1478            endDate: null
1479          };
1480
1481        defaultOptions = angular.extend(defaultOptions, options);
1482
1483        $window.plugins.calendar.findEvent(
1484          defaultOptions.title,
1485          defaultOptions.location,
1486          defaultOptions.notes,
1487          new Date(defaultOptions.startDate),
1488          new Date(defaultOptions.endDate),
1489          function (foundEvent) {
1490            d.resolve(foundEvent);
1491          }, function (error) {
1492            d.reject(error);
1493          }
1494        );
1495
1496        return d.promise;
1497      },
1498
1499      listEventsInRange: function (startDate, endDate) {
1500        var d = $q.defer();
1501
1502        $window.plugins.calendar.listEventsInRange(startDate, endDate, function (events) {
1503          d.resolve(events);
1504        }, function (error) {
1505          d.reject(error);
1506        });
1507
1508        return d.promise;
1509      },
1510
1511      listCalendars: function () {
1512        var d = $q.defer();
1513
1514        $window.plugins.calendar.listCalendars(function (calendars) {
1515          d.resolve(calendars);
1516        }, function (error) {
1517          d.reject(error);
1518        });
1519
1520        return d.promise;
1521      },
1522
1523      findAllEventsInNamedCalendar: function (calendarName) {
1524        var d = $q.defer();
1525
1526        $window.plugins.calendar.findAllEventsInNamedCalendar(calendarName, function (events) {
1527          d.resolve(events);
1528        }, function (error) {
1529          d.reject(error);
1530        });
1531
1532        return d.promise;
1533      },
1534
1535      modifyEvent: function (options) {
1536        var d = $q.defer(),
1537          defaultOptions = {
1538            title: null,
1539            location: null,
1540            notes: null,
1541            startDate: null,
1542            endDate: null,
1543            newTitle: null,
1544            newLocation: null,
1545            newNotes: null,
1546            newStartDate: null,
1547            newEndDate: null
1548          };
1549
1550        defaultOptions = angular.extend(defaultOptions, options);
1551
1552        $window.plugins.calendar.modifyEvent(
1553          defaultOptions.title,
1554          defaultOptions.location,
1555          defaultOptions.notes,
1556          new Date(defaultOptions.startDate),
1557          new Date(defaultOptions.endDate),
1558          defaultOptions.newTitle,
1559          defaultOptions.newLocation,
1560          defaultOptions.newNotes,
1561          new Date(defaultOptions.newStartDate),
1562          new Date(defaultOptions.newEndDate),
1563          function (message) {
1564            d.resolve(message);
1565          }, function (error) {
1566            d.reject(error);
1567          }
1568        );
1569
1570        return d.promise;
1571      },
1572
1573      deleteEvent: function (options) {
1574        var d = $q.defer(),
1575          defaultOptions = {
1576            newTitle: null,
1577            location: null,
1578            notes: null,
1579            startDate: null,
1580            endDate: null
1581          };
1582
1583        defaultOptions = angular.extend(defaultOptions, options);
1584
1585        $window.plugins.calendar.deleteEvent(
1586          defaultOptions.newTitle,
1587          defaultOptions.location,
1588          defaultOptions.notes,
1589          new Date(defaultOptions.startDate),
1590          new Date(defaultOptions.endDate),
1591          function (message) {
1592            d.resolve(message);
1593          }, function (error) {
1594            d.reject(error);
1595          }
1596        );
1597
1598        return d.promise;
1599      }
1600    };
1601  }]);
1602
1603// install   :   cordova plugin add cordova-plugin-camera
1604// link      :   https://github.com/apache/cordova-plugin-camera
1605
1606angular.module('ngCordova.plugins.camera', [])
1607
1608  .factory('$cordovaCamera', ['$q', function ($q) {
1609
1610    return {
1611      getPicture: function (options) {
1612        var q = $q.defer();
1613
1614        if (!navigator.camera) {
1615          q.resolve(null);
1616          return q.promise;
1617        }
1618
1619        navigator.camera.getPicture(function (imageData) {
1620          q.resolve(imageData);
1621        }, function (err) {
1622          q.reject(err);
1623        }, options);
1624
1625        return q.promise;
1626      },
1627
1628      cleanup: function () {
1629        var q = $q.defer();
1630
1631        navigator.camera.cleanup(function () {
1632          q.resolve();
1633        }, function (err) {
1634          q.reject(err);
1635        });
1636
1637        return q.promise;
1638      }
1639    };
1640  }]);
1641
1642// install   :    cordova plugin add cordova-plugin-media-capture
1643// link      :    https://github.com/apache/cordova-plugin-media-capture
1644
1645angular.module('ngCordova.plugins.capture', [])
1646
1647  .factory('$cordovaCapture', ['$q', function ($q) {
1648
1649    return {
1650      captureAudio: function (options) {
1651        var q = $q.defer();
1652
1653        if (!navigator.device.capture) {
1654          q.resolve(null);
1655          return q.promise;
1656        }
1657
1658        navigator.device.capture.captureAudio(function (audioData) {
1659          q.resolve(audioData);
1660        }, function (err) {
1661          q.reject(err);
1662        }, options);
1663
1664        return q.promise;
1665      },
1666      captureImage: function (options) {
1667        var q = $q.defer();
1668
1669        if (!navigator.device.capture) {
1670          q.resolve(null);
1671          return q.promise;
1672        }
1673
1674        navigator.device.capture.captureImage(function (imageData) {
1675          q.resolve(imageData);
1676        }, function (err) {
1677          q.reject(err);
1678        }, options);
1679
1680        return q.promise;
1681      },
1682      captureVideo: function (options) {
1683        var q = $q.defer();
1684
1685        if (!navigator.device.capture) {
1686          q.resolve(null);
1687          return q.promise;
1688        }
1689
1690        navigator.device.capture.captureVideo(function (videoData) {
1691          q.resolve(videoData);
1692        }, function (err) {
1693          q.reject(err);
1694        }, options);
1695
1696        return q.promise;
1697      }
1698    };
1699  }]);
1700
1701// install : cordova plugin add https://github.com/vkeepe/card.io.git
1702// link    : https://github.com/vkeepe/card.io.git
1703
1704/* globals CardIO: true */
1705angular.module('ngCordova.plugins.cardIO', [])
1706
1707  .provider(
1708  '$cordovaNgCardIO', [function () {
1709
1710    /**
1711     * Default array of response data from cardIO scan card
1712     */
1713    var defaultRespFields = [
1714      'card_type',
1715      'redacted_card_number',
1716      'card_number',
1717      'expiry_month',
1718      'expiry_year',
1719      'short_expiry_year',
1720      'cvv',
1721      'zip'
1722    ];
1723
1724    /**
1725     * Default config for cardIO scan function
1726     */
1727    var defaultScanConfig = {
1728      'expiry': true,
1729      'cvv': true,
1730      'zip': false,
1731      'suppressManual': false,
1732      'suppressConfirm': false,
1733      'hideLogo': true
1734    };
1735
1736    /**
1737     * Configuring defaultRespFields using $cordovaNgCardIOProvider
1738     *
1739     */
1740    this.setCardIOResponseFields = function (fields) {
1741      if (!fields || !angular.isArray(fields)) {
1742        return;
1743      }
1744      defaultRespFields = fields;
1745    };
1746
1747    /**
1748     *
1749     * Configuring defaultScanConfig using $cordovaNgCardIOProvider
1750     */
1751    this.setScanerConfig = function (config) {
1752      if (!config || !angular.isObject(config)) {
1753        return;
1754      }
1755
1756      defaultScanConfig.expiry = config.expiry || true;
1757      defaultScanConfig.cvv = config.cvv || true;
1758      defaultScanConfig.zip = config.zip || false;
1759      defaultScanConfig.suppressManual = config.suppressManual || false;
1760      defaultScanConfig.suppressConfirm = config.suppressConfirm || false;
1761      defaultScanConfig.hideLogo = config.hideLogo || true;
1762    };
1763
1764    /**
1765     * Function scanCard for $cordovaNgCardIO service to make scan of card
1766     *
1767     */
1768    this.$get = ['$q', function ($q) {
1769      return {
1770        scanCard: function () {
1771
1772          var deferred = $q.defer();
1773          CardIO.scan(
1774            defaultScanConfig,
1775            function (response) {
1776
1777              if (response === null) {
1778                deferred.reject(null);
1779              } else {
1780
1781                var respData = {};
1782                for (
1783                  var i = 0, len = defaultRespFields.length; i < len; i++) {
1784                  var field = defaultRespFields[i];
1785
1786                  if (field === 'short_expiry_year') {
1787                    respData[field] = String(response.expiry_year).substr( // jshint ignore:line
1788                      2, 2
1789                    ) || '';
1790                  } else {
1791                    respData[field] = response[field] || '';
1792                  }
1793                }
1794                deferred.resolve(respData);
1795              }
1796            },
1797            function () {
1798              deferred.reject(null);
1799            }
1800          );
1801          return deferred.promise;
1802        }
1803      };
1804    }];
1805  }]
1806);
1807
1808// install   :     cordova plugin add https://github.com/VersoSolutions/CordovaClipboard.git
1809// link      :     https://github.com/VersoSolutions/CordovaClipboard
1810
1811angular.module('ngCordova.plugins.clipboard', [])
1812
1813  .factory('$cordovaClipboard', ['$q', '$window', function ($q, $window) {
1814
1815    return {
1816      copy: function (text) {
1817        var q = $q.defer();
1818
1819        $window.cordova.plugins.clipboard.copy(text,
1820          function () {
1821            q.resolve();
1822          }, function () {
1823            q.reject();
1824          });
1825
1826        return q.promise;
1827      },
1828
1829      paste: function () {
1830        var q = $q.defer();
1831
1832        $window.cordova.plugins.clipboard.paste(function (text) {
1833          q.resolve(text);
1834        }, function () {
1835          q.reject();
1836        });
1837
1838        return q.promise;
1839      }
1840    };
1841  }]);
1842
1843// install   :     cordova plugin add cordova-plugin-contacts
1844// link      :     https://github.com/apache/cordova-plugin-contacts
1845
1846angular.module('ngCordova.plugins.contacts', [])
1847
1848  .factory('$cordovaContacts', ['$q', function ($q) {
1849
1850    return {
1851      save: function (contact) {
1852        var q = $q.defer();
1853        var deviceContact = navigator.contacts.create(contact);
1854
1855        deviceContact.save(function (result) {
1856          q.resolve(result);
1857        }, function (err) {
1858          q.reject(err);
1859        });
1860        return q.promise;
1861      },
1862
1863      remove: function (contact) {
1864        var q = $q.defer();
1865        var deviceContact = navigator.contacts.create(contact);
1866
1867        deviceContact.remove(function (result) {
1868          q.resolve(result);
1869        }, function (err) {
1870          q.reject(err);
1871        });
1872        return q.promise;
1873      },
1874
1875      clone: function (contact) {
1876        var deviceContact = navigator.contacts.create(contact);
1877        return deviceContact.clone(contact);
1878      },
1879
1880      find: function (options) {
1881        var q = $q.defer();
1882        var fields = options.fields || ['id', 'displayName'];
1883        delete options.fields;
1884        if (Object.keys(options).length === 0) {
1885          navigator.contacts.find(fields, function (results) {
1886            q.resolve(results);
1887          },function (err) {
1888            q.reject(err);
1889          });
1890        }
1891        else {
1892          navigator.contacts.find(fields, function (results) {
1893            q.resolve(results);
1894          }, function (err) {
1895            q.reject(err);
1896          }, options);
1897        }
1898        return q.promise;
1899      },
1900
1901      pickContact: function () {
1902        var q = $q.defer();
1903
1904        navigator.contacts.pickContact(function (contact) {
1905          q.resolve(contact);
1906        }, function (err) {
1907          q.reject(err);
1908        });
1909
1910        return q.promise;
1911      }
1912
1913      // TODO: method to set / get ContactAddress
1914      // TODO: method to set / get ContactError
1915      // TODO: method to set / get ContactField
1916      // TODO: method to set / get ContactName
1917      // TODO: method to set / get ContactOrganization
1918    };
1919  }]);
1920
1921// install   :      cordova plugin add https://github.com/VitaliiBlagodir/cordova-plugin-datepicker.git
1922// link      :      https://github.com/VitaliiBlagodir/cordova-plugin-datepicker
1923
1924angular.module('ngCordova.plugins.datePicker', [])
1925
1926  .factory('$cordovaDatePicker', ['$window', '$q', function ($window, $q) {
1927    
1928    return {
1929      show: function (options) {
1930        var q = $q.defer();
1931        options = options || {date: new Date(), mode: 'date'};
1932        $window.datePicker.show(options, function (date) {
1933          q.resolve(date);
1934        }, function (error){
1935          q.reject(error);
1936        });
1937        return q.promise;
1938      }
1939    };
1940  }]);
1941// install   :     cordova plugin add cordova-plugin-device
1942// link      :     https://github.com/apache/cordova-plugin-device
1943
1944/* globals device: true */
1945angular.module('ngCordova.plugins.device', [])
1946
1947  .factory('$cordovaDevice', [function () {
1948
1949    return {
1950      /**
1951       * Returns the whole device object.
1952       * @see https://github.com/apache/cordova-plugin-device
1953       * @returns {Object} The device object.
1954       */
1955      getDevice: function () {
1956        return device;
1957      },
1958
1959      /**
1960       * Returns the Cordova version.
1961       * @see https://github.com/apache/cordova-plugin-device#devicecordova
1962       * @returns {String} The Cordova version.
1963       */
1964      getCordova: function () {
1965        return device.cordova;
1966      },
1967
1968      /**
1969       * Returns the name of the device's model or product.
1970       * @see https://github.com/apache/cordova-plugin-device#devicemodel
1971       * @returns {String} The name of the device's model or product.
1972       */
1973      getModel: function () {
1974        return device.model;
1975      },
1976
1977      /**
1978       * @deprecated device.name is deprecated as of version 2.3.0. Use device.model instead.
1979       * @returns {String}
1980       */
1981      getName: function () {
1982        return device.name;
1983      },
1984
1985      /**
1986       * Returns the device's operating system name.
1987       * @see https://github.com/apache/cordova-plugin-device#deviceplatform
1988       * @returns {String} The device's operating system name.
1989       */
1990      getPlatform: function () {
1991        return device.platform;
1992      },
1993
1994      /**
1995       * Returns the device's Universally Unique Identifier.
1996       * @see https://github.com/apache/cordova-plugin-device#deviceuuid
1997       * @returns {String} The device's Universally Unique Identifier
1998       */
1999      getUUID: function () {
2000        return device.uuid;
2001      },
2002
2003      /**
2004       * Returns the operating system version.
2005       * @see https://github.com/apache/cordova-plugin-device#deviceversion
2006       * @returns {String}
2007       */
2008      getVersion: function () {
2009        return device.version;
2010      },
2011
2012      /**
2013       * Returns the device manufacturer.
2014       * @returns {String}
2015       */
2016      getManufacturer: function () {
2017        return device.manufacturer;
2018      }
2019    };
2020  }]);
2021
2022// install   :     cordova plugin add cordova-plugin-device-motion
2023// link      :     https://github.com/apache/cordova-plugin-device-motion
2024
2025angular.module('ngCordova.plugins.deviceMotion', [])
2026
2027  .factory('$cordovaDeviceMotion', ['$q', function ($q) {
2028
2029    return {
2030      getCurrentAcceleration: function () {
2031        var q = $q.defer();
2032
2033        if (angular.isUndefined(navigator.accelerometer) ||
2034        !angular.isFunction(navigator.accelerometer.getCurrentAcceleration)) {
2035          q.reject('Device do not support watchAcceleration');
2036          return q.promise;
2037        }
2038
2039        navigator.accelerometer.getCurrentAcceleration(function (result) {
2040          q.resolve(result);
2041        }, function (err) {
2042          q.reject(err);
2043        });
2044
2045        return q.promise;
2046      },
2047
2048      watchAcceleration: function (options) {
2049        var q = $q.defer();
2050
2051        if (angular.isUndefined(navigator.accelerometer) ||
2052        !angular.isFunction(navigator.accelerometer.watchAcceleration)) {
2053          q.reject('Device do not support watchAcceleration');
2054          return q.promise;
2055        }
2056
2057        var watchID = navigator.accelerometer.watchAcceleration(function (result) {
2058          q.notify(result);
2059        }, function (err) {
2060          q.reject(err);
2061        }, options);
2062
2063        q.promise.cancel = function () {
2064          navigator.accelerometer.clearWatch(watchID);
2065        };
2066
2067        q.promise.clearWatch = function (id) {
2068          navigator.accelerometer.clearWatch(id || watchID);
2069        };
2070
2071        q.promise.watchID = watchID;
2072
2073        return q.promise;
2074      },
2075
2076      clearWatch: function (watchID) {
2077        return navigator.accelerometer.clearWatch(watchID);
2078      }
2079    };
2080  }]);
2081
2082// install   :     cordova plugin add cordova-plugin-device-orientation
2083// link      :     https://github.com/apache/cordova-plugin-device-orientation
2084
2085angular.module('ngCordova.plugins.deviceOrientation', [])
2086
2087  .factory('$cordovaDeviceOrientation', ['$q', function ($q) {
2088
2089    var defaultOptions = {
2090      frequency: 3000 // every 3s
2091    };
2092    
2093    return {
2094      getCurrentHeading: function () {
2095        var q = $q.defer();
2096
2097        if(!navigator.compass) {
2098            q.reject('No compass on Device');
2099            return q.promise;
2100        }
2101
2102        navigator.compass.getCurrentHeading(function (result) {
2103          q.resolve(result);
2104        }, function (err) {
2105          q.reject(err);
2106        });
2107
2108        return q.promise;
2109      },
2110
2111      watchHeading: function (options) {
2112        var q = $q.defer();
2113
2114        if(!navigator.compass) {
2115            q.reject('No compass on Device');
2116            return q.promise;
2117        }
2118
2119        var _options = angular.extend(defaultOptions, options);
2120        var watchID = navigator.compass.watchHeading(function (result) {
2121          q.notify(result);
2122        }, function (err) {
2123          q.reject(err);
2124        }, _options);
2125
2126        q.promise.cancel = function () {
2127          navigator.compass.clearWatch(watchID);
2128        };
2129
2130        q.promise.clearWatch = function (id) {
2131          navigator.compass.clearWatch(id || watchID);
2132        };
2133
2134        q.promise.watchID = watchID;
2135
2136        return q.promise;
2137      },
2138
2139      clearWatch: function (watchID) {
2140        return navigator.compass.clearWatch(watchID);
2141      }
2142    };
2143  }]);
2144
2145// install   :     cordova plugin add cordova-plugin-dialogs
2146// link      :     https://github.com/apache/cordova-plugin-dialogs
2147
2148angular.module('ngCordova.plugins.dialogs', [])
2149
2150  .factory('$cordovaDialogs', ['$q', '$window', function ($q, $window) {
2151
2152    return {
2153      alert: function (message, title, buttonName) {
2154        var q = $q.defer();
2155
2156        if (!$window.navigator.notification) {
2157          $window.alert(message);
2158          q.resolve();
2159        } else {
2160          navigator.notification.alert(message, function () {
2161            q.resolve();
2162          }, title, buttonName);
2163        }
2164
2165        return q.promise;
2166      },
2167
2168      confirm: function (message, title, buttonLabels) {
2169        var q = $q.defer();
2170
2171        if (!$window.navigator.notification) {
2172          if ($window.confirm(message)) {
2173            q.resolve(1);
2174          } else {
2175            q.resolve(2);
2176          }
2177        } else {
2178          navigator.notification.confirm(message, function (buttonIndex) {
2179            q.resolve(buttonIndex);
2180          }, title, buttonLabels);
2181        }
2182
2183        return q.promise;
2184      },
2185
2186      prompt: function (message, title, buttonLabels, defaultText) {
2187        var q = $q.defer();
2188
2189        if (!$window.navigator.notification) {
2190          var res = $window.prompt(message, defaultText);
2191          if (res !== null) {
2192            q.resolve({input1: res, buttonIndex: 1});
2193          } else {
2194            q.resolve({input1: res, buttonIndex: 2});
2195          }
2196        } else {
2197          navigator.notification.prompt(message, function (result) {
2198            q.resolve(result);
2199          }, title, buttonLabels, defaultText);
2200        }
2201        return q.promise;
2202      },
2203
2204      beep: function (times) {
2205        return navigator.notification.beep(times);
2206      },
2207
2208      activityStart: function (message, title) {
2209        var q = $q.defer();
2210
2211        if (cordova.platformId === 'android') {
2212          navigator.notification.activityStart(title, message);
2213          q.resolve();
2214        } else {
2215          q.reject(message, title);
2216        }
2217      
2218        return q.promise;
2219      },
2220
2221      activityStop: function () {
2222        var q = $q.defer();
2223
2224        if (cordova.platformId === 'android') {
2225          navigator.notification.activityStop();
2226          q.resolve();
2227        } else {
2228          q.reject();
2229        }
2230      
2231        return q.promise;
2232      },
2233
2234      progressStart: function (message, title) {
2235        var q = $q.defer();
2236
2237        if (cordova.platformId === 'android') {
2238          navigator.notification.progressStart(title, message);
2239          q.resolve();
2240        } else {
2241          q.reject(message, title);
2242        }
2243      
2244        return q.promise;
2245      },
2246
2247      progressStop: function () {
2248        var q = $q.defer();
2249
2250        if (cordova.platformId === 'android') {
2251          navigator.notification.progressStop();
2252          q.resolve();
2253        } else {
2254          q.reject();
2255        }
2256      
2257        return q.promise;
2258      },
2259
2260      progressValue: function (value) {
2261        var q = $q.defer();
2262
2263        if (cordova.platformId === 'android') {
2264          navigator.notification.progressValue(value);
2265          q.resolve();
2266        } else {
2267          q.reject(value);
2268        }
2269      
2270        return q.promise;
2271      }
2272    };
2273  }]);
2274
2275// install  :     cordova plugin add https://github.com/katzer/cordova-plugin-email-composer.git
2276// link     :     https://github.com/katzer/cordova-plugin-email-composer
2277
2278angular.module('ngCordova.plugins.emailComposer', [])
2279
2280  .factory('$cordovaEmailComposer', ['$q', function ($q) {
2281
2282    return {
2283      isAvailable: function () {
2284        var q = $q.defer();
2285
2286        cordova.plugins.email.isAvailable(function (isAvailable) {
2287          if (isAvailable) {
2288            q.resolve();
2289          } else {
2290            q.reject();
2291          }
2292        });
2293
2294        return q.promise;
2295      },
2296
2297      open: function (properties) {
2298        var q = $q.defer();
2299
2300        cordova.plugins.email.open(properties, function () {
2301          q.reject(); // user closed email composer
2302        });
2303
2304        return q.promise;
2305      },
2306
2307      addAlias: function (app, schema) {
2308        cordova.plugins.email.addAlias(app, schema);
2309      }
2310    };
2311  }]);
2312
2313// install   :   cordova -d plugin add https://github.com/Wizcorp/phonegap-facebook-plugin.git --variable APP_ID="123456789" --variable APP_NAME="myApplication"
2314// link      :   https://github.com/Wizcorp/phonegap-facebook-plugin
2315
2316/* globals facebookConnectPlugin: true */
2317angular.module('ngCordova.plugins.facebook', [])
2318
2319  .provider('$cordovaFacebook', [function () {
2320
2321    /**
2322      * Init browser settings for Facebook plugin
2323      *
2324      * @param {number} id
2325      * @param {string} version
2326      */
2327    this.browserInit = function (id, version) {
2328      this.appID = id;
2329      this.appVersion = version || 'v2.0';
2330      facebookConnectPlugin.browserInit(this.appID, this.appVersion);
2331    };
2332
2333    this.$get = ['$q', function ($q) {
2334      return {
2335        login: function (permissions) {
2336          var q = $q.defer();
2337          facebookConnectPlugin.login(permissions, function (res) {
2338            q.resolve(res);
2339          }, function (res) {
2340            q.reject(res);
2341          });
2342
2343          return q.promise;
2344        },
2345
2346        showDialog: function (options) {
2347          var q = $q.defer();
2348          facebookConnectPlugin.showDialog(options, function (res) {
2349            q.resolve(res);
2350          }, function (err) {
2351            q.reject(err);
2352          });
2353          return q.promise;
2354        },
2355
2356        api: function (path, permissions) {
2357          var q = $q.defer();
2358          facebookConnectPlugin.api(path, permissions, function (res) {
2359            q.resolve(res);
2360          }, function (err) {
2361            q.reject(err);
2362          });
2363          return q.promise;
2364        },
2365
2366        getAccessToken: function () {
2367          var q = $q.defer();
2368          facebookConnectPlugin.getAccessToken(function (res) {
2369            q.resolve(res);
2370          }, function (err) {
2371            q.reject(err);
2372          });
2373          return q.promise;
2374        },
2375
2376        getLoginStatus: function () {
2377          var q = $q.defer();
2378          facebookConnectPlugin.getLoginStatus(function (res) {
2379            q.resolve(res);
2380          }, function (err) {
2381            q.reject(err);
2382          });
2383          return q.promise;
2384        },
2385
2386        logout: function () {
2387          var q = $q.defer();
2388          facebookConnectPlugin.logout(function (res) {
2389            q.resolve(res);
2390          }, function (err) {
2391            q.reject(err);
2392          });
2393          return q.promise;
2394        }
2395      };
2396    }];
2397  }]);
2398
2399// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-plugin-facebookads.git
2400// link     :     https://github.com/floatinghotpot/cordova-plugin-facebookads
2401
2402angular.module('ngCordova.plugins.facebookAds', [])
2403
2404  .factory('$cordovaFacebookAds', ['$q', '$window', function ($q, $window) {
2405
2406    return {
2407      setOptions: function (options) {
2408        var d = $q.defer();
2409
2410        $window.FacebookAds.setOptions(options, function () {
2411          d.resolve();
2412        }, function () {
2413          d.reject();
2414        });
2415
2416        return d.promise;
2417      },
2418
2419      createBanner: function (options) {
2420        var d = $q.defer();
2421
2422        $window.FacebookAds.createBanner(options, function () {
2423          d.resolve();
2424        }, function () {
2425          d.reject();
2426        });
2427
2428        return d.promise;
2429      },
2430
2431      removeBanner: function () {
2432        var d = $q.defer();
2433
2434        $window.FacebookAds.removeBanner(function () {
2435          d.resolve();
2436        }, function () {
2437          d.reject();
2438        });
2439
2440        return d.promise;
2441      },
2442
2443      showBanner: function (position) {
2444        var d = $q.defer();
2445
2446        $window.FacebookAds.showBanner(position, function () {
2447          d.resolve();
2448        }, function () {
2449          d.reject();
2450        });
2451
2452        return d.promise;
2453      },
2454
2455      showBannerAtXY: function (x, y) {
2456        var d = $q.defer();
2457
2458        $window.FacebookAds.showBannerAtXY(x, y, function () {
2459          d.resolve();
2460        }, function () {
2461          d.reject();
2462        });
2463
2464        return d.promise;
2465      },
2466
2467      hideBanner: function () {
2468        var d = $q.defer();
2469
2470        $window.FacebookAds.hideBanner(function () {
2471          d.resolve();
2472        }, function () {
2473          d.reject();
2474        });
2475
2476        return d.promise;
2477      },
2478
2479      prepareInterstitial: function (options) {
2480        var d = $q.defer();
2481
2482        $window.FacebookAds.prepareInterstitial(options, function () {
2483          d.resolve();
2484        }, function () {
2485          d.reject();
2486        });
2487
2488        return d.promise;
2489      },
2490
2491      showInterstitial: function () {
2492        var d = $q.defer();
2493
2494        $window.FacebookAds.showInterstitial(function () {
2495          d.resolve();
2496        }, function () {
2497          d.reject();
2498        });
2499
2500        return d.promise;
2501      }
2502    };
2503  }]);
2504
2505// install   :     cordova plugin add cordova-plugin-file
2506// link      :     https://github.com/apache/cordova-plugin-file
2507
2508angular.module('ngCordova.plugins.file', [])
2509
2510  .constant('$cordovaFileError', {
2511    1: 'NOT_FOUND_ERR',
2512    2: 'SECURITY_ERR',
2513    3: 'ABORT_ERR',
2514    4: 'NOT_READABLE_ERR',
2515    5: 'ENCODING_ERR',
2516    6: 'NO_MODIFICATION_ALLOWED_ERR',
2517    7: 'INVALID_STATE_ERR',
2518    8: 'SYNTAX_ERR',
2519    9: 'INVALID_MODIFICATION_ERR',
2520    10: 'QUOTA_EXCEEDED_ERR',
2521    11: 'TYPE_MISMATCH_ERR',
2522    12: 'PATH_EXISTS_ERR'
2523  })
2524
2525  .provider('$cordovaFile', [function () {
2526
2527    this.$get = ['$q', '$window', '$cordovaFileError', function ($q, $window, $cordovaFileError) {
2528
2529      return {
2530
2531        getFreeDiskSpace: function () {
2532          var q = $q.defer();
2533          cordova.exec(function (result) {
2534            q.resolve(result);
2535          }, function (error) {
2536            q.reject(error);
2537          }, 'File', 'getFreeDiskSpace', []);
2538          return q.promise;
2539        },
2540
2541        checkDir: function (path, dir) {
2542          var q = $q.defer();
2543
2544          if ((/^\//.test(dir))) {
2545            q.reject('directory cannot start with \/');
2546          }
2547
2548          try {
2549            var directory = path + dir;
2550            $window.resolveLocalFileSystemURL(directory, function (fileSystem) {
2551              if (fileSystem.isDirectory === true) {
2552                q.resolve(fileSystem);
2553              } else {
2554                q.reject({code: 13, message: 'input is not a directory'});
2555              }
2556            }, function (error) {
2557              error.message = $cordovaFileError[error.code];
2558              q.reject(error);
2559            });
2560          } catch (err) {
2561            err.message = $cordovaFileError[err.code];
2562            q.reject(err);
2563          }
2564
2565          return q.promise;
2566        },
2567
2568        checkFile: function (path, file) {
2569          var q = $q.defer();
2570
2571          if ((/^\//.test(file))) {
2572            q.reject('directory cannot start with \/');
2573          }
2574
2575          try {
2576            var directory = path + file;
2577            $window.resolveLocalFileSystemURL(directory, function (fileSystem) {
2578              if (fileSystem.isFile === true) {
2579                q.resolve(fileSystem);
2580              } else {
2581                q.reject({code: 13, message: 'input is not a file'});
2582              }
2583            }, function (error) {
2584              error.message = $cordovaFileError[error.code];
2585              q.reject(error);
2586            });
2587          } catch (err) {
2588            err.message = $cordovaFileError[err.code];
2589            q.reject(err);
2590          }
2591
2592          return q.promise;
2593        },
2594
2595        createDir: function (path, dirName, replaceBool) {
2596          var q = $q.defer();
2597
2598          if ((/^\//.test(dirName))) {
2599            q.reject('directory cannot start with \/');
2600          }
2601
2602          replaceBool = replaceBool ? false : true;
2603
2604          var options = {
2605            create: true,
2606            exclusive: replaceBool
2607          };
2608
2609          try {
2610            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2611              fileSystem.getDirectory(dirName, options, function (result) {
2612                q.resolve(result);
2613              }, function (error) {
2614                error.message = $cordovaFileError[error.code];
2615                q.reject(error);
2616              });
2617            }, function (err) {
2618              err.message = $cordovaFileError[err.code];
2619              q.reject(err);
2620            });
2621          } catch (e) {
2622            e.message = $cordovaFileError[e.code];
2623            q.reject(e);
2624          }
2625
2626          return q.promise;
2627        },
2628
2629        createFile: function (path, fileName, replaceBool) {
2630          var q = $q.defer();
2631
2632          if ((/^\//.test(fileName))) {
2633            q.reject('file-name cannot start with \/');
2634          }
2635
2636          replaceBool = replaceBool ? false : true;
2637
2638          var options = {
2639            create: true,
2640            exclusive: replaceBool
2641          };
2642
2643          try {
2644            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2645              fileSystem.getFile(fileName, options, function (result) {
2646                q.resolve(result);
2647              }, function (error) {
2648                error.message = $cordovaFileError[error.code];
2649                q.reject(error);
2650              });
2651            }, function (err) {
2652              err.message = $cordovaFileError[err.code];
2653              q.reject(err);
2654            });
2655          } catch (e) {
2656            e.message = $cordovaFileError[e.code];
2657            q.reject(e);
2658          }
2659          return q.promise;
2660        },
2661
2662        removeDir: function (path, dirName) {
2663          var q = $q.defer();
2664
2665          if ((/^\//.test(dirName))) {
2666            q.reject('file-name cannot start with \/');
2667          }
2668
2669          try {
2670            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2671              fileSystem.getDirectory(dirName, {create: false}, function (dirEntry) {
2672                dirEntry.remove(function () {
2673                  q.resolve({success: true, fileRemoved: dirEntry});
2674                }, function (error) {
2675                  error.message = $cordovaFileError[error.code];
2676                  q.reject(error);
2677                });
2678              }, function (err) {
2679                err.message = $cordovaFileError[err.code];
2680                q.reject(err);
2681              });
2682            }, function (er) {
2683              er.message = $cordovaFileError[er.code];
2684              q.reject(er);
2685            });
2686          } catch (e) {
2687            e.message = $cordovaFileError[e.code];
2688            q.reject(e);
2689          }
2690          return q.promise;
2691        },
2692
2693        removeFile: function (path, fileName) {
2694          var q = $q.defer();
2695
2696          if ((/^\//.test(fileName))) {
2697            q.reject('file-name cannot start with \/');
2698          }
2699
2700          try {
2701            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2702              fileSystem.getFile(fileName, {create: false}, function (fileEntry) {
2703                fileEntry.remove(function () {
2704                  q.resolve({success: true, fileRemoved: fileEntry});
2705                }, function (error) {
2706                  error.message = $cordovaFileError[error.code];
2707                  q.reject(error);
2708                });
2709              }, function (err) {
2710                err.message = $cordovaFileError[err.code];
2711                q.reject(err);
2712              });
2713            }, function (er) {
2714              er.message = $cordovaFileError[er.code];
2715              q.reject(er);
2716            });
2717          } catch (e) {
2718            e.message = $cordovaFileError[e.code];
2719            q.reject(e);
2720          }
2721          return q.promise;
2722        },
2723
2724        removeRecursively: function (path, dirName) {
2725          var q = $q.defer();
2726
2727          if ((/^\//.test(dirName))) {
2728            q.reject('file-name cannot start with \/');
2729          }
2730
2731          try {
2732            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2733              fileSystem.getDirectory(dirName, {create: false}, function (dirEntry) {
2734                dirEntry.removeRecursively(function () {
2735                  q.resolve({success: true, fileRemoved: dirEntry});
2736                }, function (error) {
2737                  error.message = $cordovaFileError[error.code];
2738                  q.reject(error);
2739                });
2740              }, function (err) {
2741                err.message = $cordovaFileError[err.code];
2742                q.reject(err);
2743              });
2744            }, function (er) {
2745              er.message = $cordovaFileError[er.code];
2746              q.reject(er);
2747            });
2748          } catch (e) {
2749            e.message = $cordovaFileError[e.code];
2750            q.reject(e);
2751          }
2752          return q.promise;
2753        },
2754
2755        writeFile: function (path, fileName, text, replaceBool) {
2756          var q = $q.defer();
2757
2758          if ((/^\//.test(fileName))) {
2759            q.reject('file-name cannot start with \/');
2760          }
2761
2762          replaceBool = replaceBool ? false : true;
2763
2764          var options = {
2765            create: true,
2766            exclusive: replaceBool
2767          };
2768
2769          try {
2770            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2771              fileSystem.getFile(fileName, options, function (fileEntry) {
2772                fileEntry.createWriter(function (writer) {
2773                  if (options.append === true) {
2774                    writer.seek(writer.length);
2775                  }
2776
2777                  if (options.truncate) {
2778                    writer.truncate(options.truncate);
2779                  }
2780
2781                  writer.onwriteend = function (evt) {
2782                    if (this.error) {
2783                      q.reject(this.error);
2784                    } else {
2785                      q.resolve(evt);
2786                    }
2787                  };
2788
2789                  writer.write(text);
2790
2791                  q.promise.abort = function () {
2792                    writer.abort();
2793                  };
2794                });
2795              }, function (error) {
2796                error.message = $cordovaFileError[error.code];
2797                q.reject(error);
2798              });
2799            }, function (err) {
2800              err.message = $cordovaFileError[err.code];
2801              q.reject(err);
2802            });
2803          } catch (e) {
2804            e.message = $cordovaFileError[e.code];
2805            q.reject(e);
2806          }
2807
2808          return q.promise;
2809        },
2810
2811        writeExistingFile: function (path, fileName, text) {
2812          var q = $q.defer();
2813
2814          if ((/^\//.test(fileName))) {
2815            q.reject('file-name cannot start with \/');
2816          }
2817
2818          try {
2819            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2820              fileSystem.getFile(fileName, {create: false}, function (fileEntry) {
2821                fileEntry.createWriter(function (writer) {
2822                  writer.seek(writer.length);
2823
2824                  writer.onwriteend = function (evt) {
2825                    if (this.error) {
2826                      q.reject(this.error);
2827                    } else {
2828                      q.resolve(evt);
2829                    }
2830                  };
2831
2832                  writer.write(text);
2833
2834                  q.promise.abort = function () {
2835                    writer.abort();
2836                  };
2837                });
2838              }, function (error) {
2839                error.message = $cordovaFileError[error.code];
2840                q.reject(error);
2841              });
2842            }, function (err) {
2843              err.message = $cordovaFileError[err.code];
2844              q.reject(err);
2845            });
2846          } catch (e) {
2847            e.message = $cordovaFileError[e.code];
2848            q.reject(e);
2849          }
2850
2851          return q.promise;
2852        },
2853
2854        readAsText: function (path, file) {
2855          var q = $q.defer();
2856
2857          if ((/^\//.test(file))) {
2858            q.reject('file-name cannot start with \/');
2859          }
2860
2861          try {
2862            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2863              fileSystem.getFile(file, {create: false}, function (fileEntry) {
2864                fileEntry.file(function (fileData) {
2865                  var reader = new FileReader();
2866
2867                  reader.onloadend = function (evt) {
2868                    if (evt.target.result !== undefined || evt.target.result !== null) {
2869                      q.resolve(evt.target.result);
2870                    } else if (evt.target.error !== undefined || evt.target.error !== null) {
2871                      q.reject(evt.target.error);
2872                    } else {
2873                      q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
2874                    }
2875                  };
2876
2877                  reader.readAsText(fileData);
2878                });
2879              }, function (error) {
2880                error.message = $cordovaFileError[error.code];
2881                q.reject(error);
2882              });
2883            }, function (err) {
2884              err.message = $cordovaFileError[err.code];
2885              q.reject(err);
2886            });
2887          } catch (e) {
2888            e.message = $cordovaFileError[e.code];
2889            q.reject(e);
2890          }
2891
2892          return q.promise;
2893        },
2894
2895        readAsDataURL: function (path, file) {
2896          var q = $q.defer();
2897
2898          if ((/^\//.test(file))) {
2899            q.reject('file-name cannot start with \/');
2900          }
2901
2902          try {
2903            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2904              fileSystem.getFile(file, {create: false}, function (fileEntry) {
2905                fileEntry.file(function (fileData) {
2906                  var reader = new FileReader();
2907                  reader.onloadend = function (evt) {
2908                    if (evt.target.result !== undefined || evt.target.result !== null) {
2909                      q.resolve(evt.target.result);
2910                    } else if (evt.target.error !== undefined || evt.target.error !== null) {
2911                      q.reject(evt.target.error);
2912                    } else {
2913                      q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
2914                    }
2915                  };
2916                  reader.readAsDataURL(fileData);
2917                });
2918              }, function (error) {
2919                error.message = $cordovaFileError[error.code];
2920                q.reject(error);
2921              });
2922            }, function (err) {
2923              err.message = $cordovaFileError[err.code];
2924              q.reject(err);
2925            });
2926          } catch (e) {
2927            e.message = $cordovaFileError[e.code];
2928            q.reject(e);
2929          }
2930
2931          return q.promise;
2932        },
2933
2934        readAsBinaryString: function (path, file) {
2935          var q = $q.defer();
2936
2937          if ((/^\//.test(file))) {
2938            q.reject('file-name cannot start with \/');
2939          }
2940
2941          try {
2942            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2943              fileSystem.getFile(file, {create: false}, function (fileEntry) {
2944                fileEntry.file(function (fileData) {
2945                  var reader = new FileReader();
2946                  reader.onloadend = function (evt) {
2947                    if (evt.target.result !== undefined || evt.target.result !== null) {
2948                      q.resolve(evt.target.result);
2949                    } else if (evt.target.error !== undefined || evt.target.error !== null) {
2950                      q.reject(evt.target.error);
2951                    } else {
2952                      q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
2953                    }
2954                  };
2955                  reader.readAsBinaryString(fileData);
2956                });
2957              }, function (error) {
2958                error.message = $cordovaFileError[error.code];
2959                q.reject(error);
2960              });
2961            }, function (err) {
2962              err.message = $cordovaFileError[err.code];
2963              q.reject(err);
2964            });
2965          } catch (e) {
2966            e.message = $cordovaFileError[e.code];
2967            q.reject(e);
2968          }
2969
2970          return q.promise;
2971        },
2972
2973        readAsArrayBuffer: function (path, file) {
2974          var q = $q.defer();
2975
2976          if ((/^\//.test(file))) {
2977            q.reject('file-name cannot start with \/');
2978          }
2979
2980          try {
2981            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
2982              fileSystem.getFile(file, {create: false}, function (fileEntry) {
2983                fileEntry.file(function (fileData) {
2984                  var reader = new FileReader();
2985                  reader.onloadend = function (evt) {
2986                    if (evt.target.result !== undefined || evt.target.result !== null) {
2987                      q.resolve(evt.target.result);
2988                    } else if (evt.target.error !== undefined || evt.target.error !== null) {
2989                      q.reject(evt.target.error);
2990                    } else {
2991                      q.reject({code: null, message: 'READER_ONLOADEND_ERR'});
2992                    }
2993                  };
2994                  reader.readAsArrayBuffer(fileData);
2995                });
2996              }, function (error) {
2997                error.message = $cordovaFileError[error.code];
2998                q.reject(error);
2999              });
3000            }, function (err) {
3001              err.message = $cordovaFileError[err.code];
3002              q.reject(err);
3003            });
3004          } catch (e) {
3005            e.message = $cordovaFileError[e.code];
3006            q.reject(e);
3007          }
3008
3009          return q.promise;
3010        },
3011
3012        moveFile: function (path, fileName, newPath, newFileName) {
3013          var q = $q.defer();
3014
3015          newFileName = newFileName || fileName;
3016
3017          if ((/^\//.test(fileName)) || (/^\//.test(newFileName))) {
3018            q.reject('file-name cannot start with \/');
3019          }
3020
3021          try {
3022            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
3023              fileSystem.getFile(fileName, {create: false}, function (fileEntry) {
3024                $window.resolveLocalFileSystemURL(newPath, function (newFileEntry) {
3025                  fileEntry.moveTo(newFileEntry, newFileName, function (result) {
3026                    q.resolve(result);
3027                  }, function (error) {
3028                    q.reject(error);
3029                  });
3030                }, function (err) {
3031                  q.reject(err);
3032                });
3033              }, function (err) {
3034                q.reject(err);
3035              });
3036            }, function (er) {
3037              q.reject(er);
3038            });
3039          } catch (e) {
3040            q.reject(e);
3041          }
3042          return q.promise;
3043        },
3044
3045        moveDir: function (path, dirName, newPath, newDirName) {
3046          var q = $q.defer();
3047
3048          newDirName = newDirName || dirName;
3049
3050          if (/^\//.test(dirName) || (/^\//.test(newDirName))) {
3051            q.reject('file-name cannot start with \/');
3052          }
3053
3054          try {
3055            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
3056              fileSystem.getDirectory(dirName, {create: false}, function (dirEntry) {
3057                $window.resolveLocalFileSystemURL(newPath, function (newDirEntry) {
3058                  dirEntry.moveTo(newDirEntry, newDirName, function (result) {
3059                    q.resolve(result);
3060                  }, function (error) {
3061                    q.reject(error);
3062                  });
3063                }, function (erro) {
3064                  q.reject(erro);
3065                });
3066              }, function (err) {
3067                q.reject(err);
3068              });
3069            }, function (er) {
3070              q.reject(er);
3071            });
3072          } catch (e) {
3073            q.reject(e);
3074          }
3075          return q.promise;
3076        },
3077
3078        copyDir: function (path, dirName, newPath, newDirName) {
3079          var q = $q.defer();
3080
3081          newDirName = newDirName || dirName;
3082
3083          if (/^\//.test(dirName) || (/^\//.test(newDirName))) {
3084            q.reject('file-name cannot start with \/');
3085          }
3086
3087          try {
3088            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
3089              fileSystem.getDirectory(dirName, {create: false, exclusive: false}, function (dirEntry) {
3090
3091                $window.resolveLocalFileSystemURL(newPath, function (newDirEntry) {
3092                  dirEntry.copyTo(newDirEntry, newDirName, function (result) {
3093                    q.resolve(result);
3094                  }, function (error) {
3095                    error.message = $cordovaFileError[error.code];
3096                    q.reject(error);
3097                  });
3098                }, function (erro) {
3099                  erro.message = $cordovaFileError[erro.code];
3100                  q.reject(erro);
3101                });
3102              }, function (err) {
3103                err.message = $cordovaFileError[err.code];
3104                q.reject(err);
3105              });
3106            }, function (er) {
3107              er.message = $cordovaFileError[er.code];
3108              q.reject(er);
3109            });
3110          } catch (e) {
3111            e.message = $cordovaFileError[e.code];
3112            q.reject(e);
3113          }
3114          return q.promise;
3115        },
3116
3117        copyFile: function (path, fileName, newPath, newFileName) {
3118          var q = $q.defer();
3119
3120          newFileName = newFileName || fileName;
3121
3122          if ((/^\//.test(fileName))) {
3123            q.reject('file-name cannot start with \/');
3124          }
3125
3126          try {
3127            $window.resolveLocalFileSystemURL(path, function (fileSystem) {
3128              fileSystem.getFile(fileName, {create: false, exclusive: false}, function (fileEntry) {
3129
3130                $window.resolveLocalFileSystemURL(newPath, function (newFileEntry) {
3131                  fileEntry.copyTo(newFileEntry, newFileName, function (result) {
3132                    q.resolve(result);
3133                  }, function (error) {
3134                    error.message = $cordovaFileError[error.code];
3135                    q.reject(error);
3136                  });
3137                }, function (erro) {
3138                  erro.message = $cordovaFileError[erro.code];
3139                  q.reject(erro);
3140                });
3141              }, function (err) {
3142                err.message = $cordovaFileError[err.code];
3143                q.reject(err);
3144              });
3145            }, function (er) {
3146              er.message = $cordovaFileError[er.code];
3147              q.reject(er);
3148            });
3149          } catch (e) {
3150            e.message = $cordovaFileError[e.code];
3151            q.reject(e);
3152          }
3153          return q.promise;
3154        },
3155
3156        readFileMetadata: function (path, file) {
3157          var q = $q.defer();
3158
3159          if ((/^\//.test(file))) {
3160            q.reject('directory cannot start with \/');
3161          }
3162
3163          try {
3164            var directory = path + file;
3165            $window.resolveLocalFileSystemURL(directory, function (fileEntry) {
3166              fileEntry.file(function (result) {
3167                q.resolve(result);
3168              }, function (error) {
3169                error.message = $cordovaFileError[error.code];
3170                q.reject(error);
3171              });
3172            }, function (err) {
3173              err.message = $cordovaFileError[err.code];
3174              q.reject(err);
3175            });
3176          } catch (e) {
3177            e.message = $cordovaFileError[e.code];
3178            q.reject(e);
3179          }
3180
3181          return q.promise;
3182        }
3183
3184        /*
3185         listFiles: function (path, dir) {
3186
3187         },
3188
3189         listDir: function (path, dirName) {
3190         var q = $q.defer();
3191
3192         try {
3193         $window.resolveLocalFileSystemURL(path, function (fileSystem) {
3194         fileSystem.getDirectory(dirName, options, function (parent) {
3195         var reader = parent.createReader();
3196         reader.readEntries(function (entries) {
3197         q.resolve(entries);
3198         }, function () {
3199         q.reject('DIR_READ_ERROR : ' + path + dirName);
3200         });
3201         }, function (error) {
3202         error.message = $cordovaFileError[error.code];
3203         q.reject(error);
3204         });
3205         }, function (err) {
3206         err.message = $cordovaFileError[err.code];
3207         q.reject(err);
3208         });
3209         } catch (e) {
3210         e.message = $cordovaFileError[e.code];
3211         q.reject(e);
3212         }
3213
3214         return q.promise;
3215         },
3216
3217         */
3218      };
3219
3220    }];
3221  }]);
3222
3223// install   :      cordova plugin add https://github.com/pwlin/cordova-plugin-file-opener2.git
3224// link      :      https://github.com/pwlin/cordova-plugin-file-opener2
3225
3226angular.module('ngCordova.plugins.fileOpener2', [])
3227
3228  .factory('$cordovaFileOpener2', ['$q', function ($q) {
3229
3230    return {
3231      open: function (file, type) {
3232        var q = $q.defer();
3233        cordova.plugins.fileOpener2.open(file, type, {
3234          error: function (e) {
3235            q.reject(e);
3236          }, success: function () {
3237            q.resolve();
3238          }
3239        });
3240        return q.promise;
3241      },
3242
3243      uninstall: function (pack) {
3244        var q = $q.defer();
3245        cordova.plugins.fileOpener2.uninstall(pack, {
3246          error: function (e) {
3247            q.reject(e);
3248          }, success: function () {
3249            q.resolve();
3250          }
3251        });
3252        return q.promise;
3253      },
3254
3255      appIsInstalled: function (pack) {
3256        var q = $q.defer();
3257        cordova.plugins.fileOpener2.appIsInstalled(pack, {
3258          success: function (res) {
3259            q.resolve(res);
3260          }
3261        });
3262        return q.promise;
3263      }
3264    };
3265  }]);
3266
3267// install   :     cordova plugin add cordova-plugin-file-transfer
3268// link      :     https://github.com/apache/cordova-plugin-file-transfer
3269
3270/* globals FileTransfer: true */
3271angular.module('ngCordova.plugins.fileTransfer', [])
3272
3273  .factory('$cordovaFileTransfer', ['$q', '$timeout', function ($q, $timeout) {
3274    return {
3275      download: function (source, filePath, options, trustAllHosts) {
3276        var q = $q.defer();
3277        var ft = new FileTransfer();
3278        var uri = (options && options.encodeURI === false) ? source : encodeURI(source);
3279
3280        if (options && options.timeout !== undefined && options.timeout !== null) {
3281          $timeout(function () {
3282            ft.abort();
3283          }, options.timeout);
3284          options.timeout = null;
3285        }
3286
3287        ft.onprogress = function (progress) {
3288          q.notify(progress);
3289        };
3290
3291        q.promise.abort = function () {
3292          ft.abort();
3293        };
3294
3295        ft.download(uri, filePath, q.resolve, q.reject, trustAllHosts, options);
3296        return q.promise;
3297      },
3298
3299      upload: function (server, filePath, options, trustAllHosts) {
3300        var q = $q.defer();
3301        var ft = new FileTransfer();
3302        var uri = (options && options.encodeURI === false) ? server : encodeURI(server);
3303
3304        if (options && options.timeout !== undefined && options.timeout !== null) {
3305          $timeout(function () {
3306            ft.abort();
3307          }, options.timeout);
3308          options.timeout = null;
3309        }
3310
3311        ft.onprogress = function (progress) {
3312          q.notify(progress);
3313        };
3314
3315        q.promise.abort = function () {
3316          ft.abort();
3317        };
3318
3319        ft.upload(filePath, uri, q.resolve, q.reject, options, trustAllHosts);
3320        return q.promise;
3321      }
3322    };
3323  }]);
3324
3325// install   :     cordova plugin add https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin.git
3326// link      :     https://github.com/EddyVerbruggen/Flashlight-PhoneGap-Plugin
3327
3328angular.module('ngCordova.plugins.flashlight', [])
3329
3330  .factory('$cordovaFlashlight', ['$q', '$window', function ($q, $window) {
3331
3332    return {
3333      available: function () {
3334        var q = $q.defer();
3335        $window.plugins.flashlight.available(function (isAvailable) {
3336          q.resolve(isAvailable);
3337        });
3338        return q.promise;
3339      },
3340
3341      switchOn: function () {
3342        var q = $q.defer();
3343        $window.plugins.flashlight.switchOn(function (response) {
3344          q.resolve(response);
3345        }, function (error) {
3346          q.reject(error);
3347        });
3348        return q.promise;
3349      },
3350
3351      switchOff: function () {
3352        var q = $q.defer();
3353        $window.plugins.flashlight.switchOff(function (response) {
3354          q.resolve(response);
3355        }, function (error) {
3356          q.reject(error);
3357        });
3358        return q.promise;
3359      },
3360
3361      toggle: function () {
3362        var q = $q.defer();
3363        $window.plugins.flashlight.toggle(function (response) {
3364          q.resolve(response);
3365        }, function (error) {
3366          q.reject(error);
3367        });
3368        return q.promise;
3369      }
3370    };
3371  }]);
3372
3373// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-plugin-flurry.git
3374// link     :     https://github.com/floatinghotpot/cordova-plugin-flurry
3375
3376angular.module('ngCordova.plugins.flurryAds', [])
3377  .factory('$cordovaFlurryAds', ['$q', '$window', function ($q, $window) {
3378
3379    return {
3380      setOptions: function (options) {
3381        var d = $q.defer();
3382
3383        $window.FlurryAds.setOptions(options, function () {
3384          d.resolve();
3385        }, function () {
3386          d.reject();
3387        });
3388
3389        return d.promise;
3390      },
3391
3392      createBanner: function (options) {
3393        var d = $q.defer();
3394
3395        $window.FlurryAds.createBanner(options, function () {
3396          d.resolve();
3397        }, function () {
3398          d.reject();
3399        });
3400
3401        return d.promise;
3402      },
3403
3404      removeBanner: function () {
3405        var d = $q.defer();
3406
3407        $window.FlurryAds.removeBanner(function () {
3408          d.resolve();
3409        }, function () {
3410          d.reject();
3411        });
3412
3413        return d.promise;
3414      },
3415
3416      showBanner: function (position) {
3417        var d = $q.defer();
3418
3419        $window.FlurryAds.showBanner(position, function () {
3420          d.resolve();
3421        }, function () {
3422          d.reject();
3423        });
3424
3425        return d.promise;
3426      },
3427
3428      showBannerAtXY: function (x, y) {
3429        var d = $q.defer();
3430
3431        $window.FlurryAds.showBannerAtXY(x, y, function () {
3432          d.resolve();
3433        }, function () {
3434          d.reject();
3435        });
3436
3437        return d.promise;
3438      },
3439
3440      hideBanner: function () {
3441        var d = $q.defer();
3442
3443        $window.FlurryAds.hideBanner(function () {
3444          d.resolve();
3445        }, function () {
3446          d.reject();
3447        });
3448
3449        return d.promise;
3450      },
3451
3452      prepareInterstitial: function (options) {
3453        var d = $q.defer();
3454
3455        $window.FlurryAds.prepareInterstitial(options, function () {
3456          d.resolve();
3457        }, function () {
3458          d.reject();
3459        });
3460
3461        return d.promise;
3462      },
3463
3464      showInterstitial: function () {
3465        var d = $q.defer();
3466
3467        $window.FlurryAds.showInterstitial(function () {
3468          d.resolve();
3469        }, function () {
3470          d.reject();
3471        });
3472
3473        return d.promise;
3474      }
3475    };
3476  }]);
3477
3478// install   :     cordova plugin add https://github.com/phonegap-build/GAPlugin.git
3479// link      :     https://github.com/phonegap-build/GAPlugin
3480
3481angular.module('ngCordova.plugins.ga', [])
3482
3483  .factory('$cordovaGA', ['$q', '$window', function ($q, $window) {
3484
3485    return {
3486      init: function (id, mingap) {
3487        var q = $q.defer();
3488        mingap = (mingap >= 0) ? mingap : 10;
3489        $window.plugins.gaPlugin.init(function (result) {
3490            q.resolve(result);
3491          },
3492          function (error) {
3493            q.reject(error);
3494          },
3495          id, mingap);
3496        return q.promise;
3497      },
3498
3499      trackEvent: function (success, fail, category, eventAction, eventLabel, eventValue) {
3500        var q = $q.defer();
3501        $window.plugins.gaPlugin.trackEvent(function (result) {
3502            q.resolve(result);
3503          },
3504          function (error) {
3505            q.reject(error);
3506          },
3507          category, eventAction, eventLabel, eventValue);
3508        return q.promise;
3509      },
3510
3511      trackPage: function (success, fail, pageURL) {
3512        var q = $q.defer();
3513        $window.plugins.gaPlugin.trackPage(function (result) {
3514            q.resolve(result);
3515          },
3516          function (error) {
3517            q.reject(error);
3518          },
3519          pageURL);
3520        return q.promise;
3521      },
3522
3523      setVariable: function (success, fail, index, value) {
3524        var q = $q.defer();
3525        $window.plugins.gaPlugin.setVariable(function (result) {
3526            q.resolve(result);
3527          },
3528          function (error) {
3529            q.reject(error);
3530          },
3531          index, value);
3532        return q.promise;
3533      },
3534
3535      exit: function () {
3536        var q = $q.defer();
3537        $window.plugins.gaPlugin.exit(function (result) {
3538            q.resolve(result);
3539          },
3540          function (error) {
3541            q.reject(error);
3542          });
3543        return q.promise;
3544      }
3545    };
3546  }]);
3547
3548// install   :     cordova plugin add cordova-plugin-geolocation
3549// link      :     https://github.com/apache/cordova-plugin-geolocation
3550
3551angular.module('ngCordova.plugins.geolocation', [])
3552
3553  .factory('$cordovaGeolocation', ['$q', function ($q) {
3554
3555    return {
3556      getCurrentPosition: function (options) {
3557        var q = $q.defer();
3558
3559        navigator.geolocation.getCurrentPosition(function (result) {
3560          q.resolve(result);
3561        }, function (err) {
3562          q.reject(err);
3563        }, options);
3564
3565        return q.promise;
3566      },
3567
3568      watchPosition: function (options) {
3569        var q = $q.defer();
3570
3571        var watchID = navigator.geolocation.watchPosition(function (result) {
3572          q.notify(result);
3573        }, function (err) {
3574          q.reject(err);
3575        }, options);
3576
3577        q.promise.cancel = function () {
3578          navigator.geolocation.clearWatch(watchID);
3579        };
3580
3581        q.promise.clearWatch = function (id) {
3582          navigator.geolocation.clearWatch(id || watchID);
3583        };
3584
3585        q.promise.watchID = watchID;
3586
3587        return q.promise;
3588      },
3589
3590      clearWatch: function (watchID) {
3591        return navigator.geolocation.clearWatch(watchID);
3592      }
3593    };
3594  }]);
3595
3596// install   :      cordova plugin add cordova-plugin-globalization
3597// link      :      https://github.com/apache/cordova-plugin-globalization
3598
3599angular.module('ngCordova.plugins.globalization', [])
3600
3601  .factory('$cordovaGlobalization', ['$q', function ($q) {
3602
3603    return {
3604      getPreferredLanguage: function () {
3605        var q = $q.defer();
3606
3607        navigator.globalization.getPreferredLanguage(function (result) {
3608            q.resolve(result);
3609          },
3610          function (err) {
3611            q.reject(err);
3612          });
3613        return q.promise;
3614      },
3615
3616      getLocaleName: function () {
3617        var q = $q.defer();
3618
3619        navigator.globalization.getLocaleName(function (result) {
3620            q.resolve(result);
3621          },
3622          function (err) {
3623            q.reject(err);
3624          });
3625        return q.promise;
3626      },
3627
3628      getFirstDayOfWeek: function () {
3629        var q = $q.defer();
3630
3631        navigator.globalization.getFirstDayOfWeek(function (result) {
3632            q.resolve(result);
3633          },
3634          function (err) {
3635            q.reject(err);
3636          });
3637        return q.promise;
3638      },
3639
3640      // "date" parameter must be a JavaScript Date Object.
3641      dateToString: function (date, options) {
3642        var q = $q.defer();
3643
3644        navigator.globalization.dateToString(
3645          date,
3646          function (result) {
3647            q.resolve(result);
3648          },
3649          function (err) {
3650            q.reject(err);
3651          },
3652          options);
3653        return q.promise;
3654      },
3655
3656      stringToDate: function (dateString, options) {
3657        var q = $q.defer();
3658
3659        navigator.globalization.stringToDate(
3660          dateString,
3661          function (result) {
3662            q.resolve(result);
3663          },
3664          function (err) {
3665            q.reject(err);
3666          },
3667          options);
3668        return q.promise;
3669      },
3670
3671      getDatePattern: function (options) {
3672        var q = $q.defer();
3673
3674        navigator.globalization.getDatePattern(
3675          function (result) {
3676            q.resolve(result);
3677          },
3678          function (err) {
3679            q.reject(err);
3680          },
3681          options);
3682        return q.promise;
3683      },
3684
3685      getDateNames: function (options) {
3686        var q = $q.defer();
3687
3688        navigator.globalization.getDateNames(
3689          function (result) {
3690            q.resolve(result);
3691          },
3692          function (err) {
3693            q.reject(err);
3694          },
3695          options);
3696        return q.promise;
3697      },
3698
3699      // "date" parameter must be a JavaScript Date Object.
3700      isDayLightSavingsTime: function (date) {
3701        var q = $q.defer();
3702
3703        navigator.globalization.isDayLightSavingsTime(
3704          date,
3705          function (result) {
3706            q.resolve(result);
3707          },
3708          function (err) {
3709            q.reject(err);
3710          });
3711        return q.promise;
3712      },
3713
3714      numberToString: function (number, options) {
3715        var q = $q.defer();
3716
3717        navigator.globalization.numberToString(
3718          number,
3719          function (result) {
3720            q.resolve(result);
3721          },
3722          function (err) {
3723            q.reject(err);
3724          },
3725          options);
3726        return q.promise;
3727      },
3728
3729      stringToNumber: function (numberString, options) {
3730        var q = $q.defer();
3731
3732        navigator.globalization.stringToNumber(
3733          numberString,
3734          function (result) {
3735            q.resolve(result);
3736          },
3737          function (err) {
3738            q.reject(err);
3739          },
3740          options);
3741        return q.promise;
3742      },
3743
3744      getNumberPattern: function (options) {
3745        var q = $q.defer();
3746
3747        navigator.globalization.getNumberPattern(
3748          function (result) {
3749            q.resolve(result);
3750          },
3751          function (err) {
3752            q.reject(err);
3753          },
3754          options);
3755        return q.promise;
3756      },
3757
3758      getCurrencyPattern: function (currencyCode) {
3759        var q = $q.defer();
3760
3761        navigator.globalization.getCurrencyPattern(
3762          currencyCode,
3763          function (result) {
3764            q.resolve(result);
3765          },
3766          function (err) {
3767            q.reject(err);
3768          });
3769        return q.promise;
3770      }
3771
3772    };
3773  }]);
3774
3775// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-admob-pro.git
3776// link     :     https://github.com/floatinghotpot/cordova-admob-pro
3777
3778angular.module('ngCordova.plugins.googleAds', [])
3779
3780  .factory('$cordovaGoogleAds', ['$q', '$window', function ($q, $window) {
3781
3782    return {
3783      setOptions: function (options) {
3784        var d = $q.defer();
3785
3786        $window.AdMob.setOptions(options, function () {
3787          d.resolve();
3788        }, function () {
3789          d.reject();
3790        });
3791
3792        return d.promise;
3793      },
3794
3795      createBanner: function (options) {
3796        var d = $q.defer();
3797
3798        $window.AdMob.createBanner(options, function () {
3799          d.resolve();
3800        }, function () {
3801          d.reject();
3802        });
3803
3804        return d.promise;
3805      },
3806
3807      removeBanner: function () {
3808        var d = $q.defer();
3809
3810        $window.AdMob.removeBanner(function () {
3811          d.resolve();
3812        }, function () {
3813          d.reject();
3814        });
3815
3816        return d.promise;
3817      },
3818
3819      showBanner: function (position) {
3820        var d = $q.defer();
3821
3822        $window.AdMob.showBanner(position, function () {
3823          d.resolve();
3824        }, function () {
3825          d.reject();
3826        });
3827
3828        return d.promise;
3829      },
3830
3831      showBannerAtXY: function (x, y) {
3832        var d = $q.defer();
3833
3834        $window.AdMob.showBannerAtXY(x, y, function () {
3835          d.resolve();
3836        }, function () {
3837          d.reject();
3838        });
3839
3840        return d.promise;
3841      },
3842
3843      hideBanner: function () {
3844        var d = $q.defer();
3845
3846        $window.AdMob.hideBanner(function () {
3847          d.resolve();
3848        }, function () {
3849          d.reject();
3850        });
3851
3852        return d.promise;
3853      },
3854
3855      prepareInterstitial: function (options) {
3856        var d = $q.defer();
3857
3858        $window.AdMob.prepareInterstitial(options, function () {
3859          d.resolve();
3860        }, function () {
3861          d.reject();
3862        });
3863
3864        return d.promise;
3865      },
3866
3867      showInterstitial: function () {
3868        var d = $q.defer();
3869
3870        $window.AdMob.showInterstitial(function () {
3871          d.resolve();
3872        }, function () {
3873          d.reject();
3874        });
3875
3876        return d.promise;
3877      }
3878    };
3879  }]);
3880
3881// install   :     cordova plugin add https://github.com/danwilson/google-analytics-plugin.git
3882// link      :     https://github.com/danwilson/google-analytics-plugin
3883
3884angular.module('ngCordova.plugins.googleAnalytics', [])
3885
3886  .factory('$cordovaGoogleAnalytics', ['$q', '$window', function ($q, $window) {
3887
3888    return {
3889      startTrackerWithId: function (id) {
3890        var d = $q.defer();
3891
3892        $window.analytics.startTrackerWithId(id, function (response) {
3893          d.resolve(response);
3894        }, function (error) {
3895          d.reject(error);
3896        });
3897
3898        return d.promise;
3899      },
3900
3901      setUserId: function (id) {
3902        var d = $q.defer();
3903
3904        $window.analytics.setUserId(id, function (response) {
3905          d.resolve(response);
3906        }, function (error) {
3907          d.reject(error);
3908        });
3909
3910        return d.promise;
3911      },
3912
3913      debugMode: function () {
3914        var d = $q.defer();
3915
3916        $window.analytics.debugMode(function (response) {
3917          d.resolve(response);
3918        }, function () {
3919          d.reject();
3920        });
3921
3922        return d.promise;
3923      },
3924
3925      trackView: function (screenName) {
3926        var d = $q.defer();
3927
3928        $window.analytics.trackView(screenName, function (response) {
3929          d.resolve(response);
3930        }, function (error) {
3931          d.reject(error);
3932        });
3933
3934        return d.promise;
3935      },
3936
3937      addCustomDimension: function (key, value) {
3938        var d = $q.defer();
3939        var parsedKey = parseInt(key, 10);
3940
3941        if (isNaN(parsedKey)) {
3942          d.reject('Parameter "key" must be an integer.');
3943        }
3944
3945        $window.analytics.addCustomDimension(parsedKey, value, function () {
3946          d.resolve();
3947        }, function (error) {
3948          d.reject(error);
3949        });
3950
3951        return d.promise;
3952      },
3953
3954      trackEvent: function (category, action, label, value) {
3955        var d = $q.defer();
3956
3957        $window.analytics.trackEvent(category, action, label, value, function (response) {
3958          d.resolve(response);
3959        }, function (error) {
3960          d.reject(error);
3961        });
3962
3963        return d.promise;
3964      },
3965
3966      trackException: function (description, fatal) {
3967        var d = $q.defer();
3968
3969        $window.analytics.trackException(description, fatal, function (response) {
3970          d.resolve(response);
3971        }, function (error) {
3972          d.reject(error);
3973        });
3974
3975        return d.promise;
3976      },
3977
3978      trackTiming: function (category, milliseconds, variable, label) {
3979        var d = $q.defer();
3980
3981        $window.analytics.trackTiming(category, milliseconds, variable, label, function (response) {
3982          d.resolve(response);
3983        }, function (error) {
3984          d.reject(error);
3985        });
3986
3987        return d.promise;
3988      },
3989
3990      addTransaction: function (transactionId, affiliation, revenue, tax, shipping, currencyCode) {
3991        var d = $q.defer();
3992
3993        $window.analytics.addTransaction(transactionId, affiliation, revenue, tax, shipping, currencyCode, function (response) {
3994          d.resolve(response);
3995        }, function (error) {
3996          d.reject(error);
3997        });
3998
3999        return d.promise;
4000      },
4001
4002      addTransactionItem: function (transactionId, name, sku, category, price, quantity, currencyCode) {
4003        var d = $q.defer();
4004
4005        $window.analytics.addTransactionItem(transactionId, name, sku, category, price, quantity, currencyCode, function (response) {
4006          d.resolve(response);
4007        }, function (error) {
4008          d.reject(error);
4009        });
4010
4011        return d.promise;
4012      }
4013    };
4014  }]);
4015
4016// install   :
4017// link      :
4018
4019// Google Maps needs ALOT of work!
4020// Not for production use
4021
4022angular.module('ngCordova.plugins.googleMap', [])
4023
4024  .factory('$cordovaGoogleMap', ['$q', '$window', function ($q, $window) {
4025
4026    var map = null;
4027
4028    return {
4029      getMap: function (options) {
4030        var q = $q.defer();
4031
4032        if (!$window.plugin.google.maps) {
4033          q.reject(null);
4034        } else {
4035          var div = document.getElementById('map_canvas');
4036          map = $window.plugin.google.maps.Map.getMap(options);
4037          map.setDiv(div);
4038          q.resolve(map);
4039        }
4040        return q.promise;
4041      },
4042
4043      isMapLoaded: function () { // check if an instance of the map exists
4044        return !!map;
4045      },
4046      addMarker: function (markerOptions) { // add a marker to the map with given markerOptions
4047        var q = $q.defer();
4048        map.addMarker(markerOptions, function (marker) {
4049          q.resolve(marker);
4050        });
4051
4052        return q.promise;
4053      },
4054      getMapTypeIds: function () {
4055        return $window.plugin.google.maps.mapTypeId;
4056      },
4057      setVisible: function (isVisible) {
4058        var q = $q.defer();
4059        map.setVisible(isVisible);
4060        return q.promise;
4061      },
4062      // I don't know how to deallocate te map and the google map plugin.
4063      cleanup: function () {
4064        map = null;
4065        // delete map;
4066      }
4067    };
4068  }]);
4069
4070// install   :   cordova plugin add https://github.com/ptgamr/cordova-google-play-game.git --variable APP_ID=123456789
4071// link      :   https://github.com/ptgamr/cordova-google-play-game
4072
4073/* globals googleplaygame: true */
4074angular.module('ngCordova.plugins.googlePlayGame', [])
4075
4076  .factory('$cordovaGooglePlayGame', ['$q', function ($q) {
4077
4078    return {
4079      auth: function () {
4080        var q = $q.defer();
4081
4082        googleplaygame.auth(function (success) {
4083          return q.resolve(success);
4084        }, function (err) {
4085          return q.reject(err);
4086        });
4087
4088        return q.promise;
4089      },
4090      signout: function () {
4091        var q = $q.defer();
4092
4093        googleplaygame.signout(function (success) {
4094          return q.resolve(success);
4095        }, function (err) {
4096          return q.reject(err);
4097        });
4098
4099        return q.promise;
4100      },
4101      isSignedIn: function () {
4102        var q = $q.defer();
4103
4104        googleplaygame.isSignedIn(function (success) {
4105          return q.resolve(success);
4106        }, function (err) {
4107          return q.reject(err);
4108        });
4109
4110        return q.promise;
4111      },
4112      showPlayer: function () {
4113        var q = $q.defer();
4114
4115        googleplaygame.showPlayer(function (success) {
4116          return q.resolve(success);
4117        }, function (err) {
4118          return q.reject(err);
4119        });
4120
4121        return q.promise;
4122      },
4123      submitScore: function (data) {
4124        var q = $q.defer();
4125
4126        googleplaygame.submitScore(data, function (success) {
4127          return q.resolve(success);
4128        }, function (err) {
4129          return q.reject(err);
4130        });
4131
4132        return q.promise;
4133      },
4134      showAllLeaderboards: function () {
4135        var q = $q.defer();
4136
4137        googleplaygame.showAllLeaderboards(function (success) {
4138          return q.resolve(success);
4139        }, function (err) {
4140          return q.reject(err);
4141        });
4142
4143        return q.promise;
4144      },
4145      showLeaderboard: function (data) {
4146        var q = $q.defer();
4147
4148        googleplaygame.showLeaderboard(data, function (success) {
4149          return q.resolve(success);
4150        }, function (err) {
4151          return q.reject(err);
4152        });
4153
4154        return q.promise;
4155      },
4156      unlockAchievement: function (data) {
4157        var q = $q.defer();
4158
4159        googleplaygame.unlockAchievement(data, function (success) {
4160          return q.resolve(success);
4161        }, function (err) {
4162          return q.reject(err);
4163        });
4164
4165        return q.promise;
4166      },
4167      incrementAchievement: function (data) {
4168        var q = $q.defer();
4169
4170        googleplaygame.incrementAchievement(data, function (success) {
4171          return q.resolve(success);
4172        }, function (err) {
4173          return q.reject(err);
4174        });
4175
4176        return q.promise;
4177      },
4178      showAchievements: function () {
4179        var q = $q.defer();
4180
4181        googleplaygame.showAchievements(function (success) {
4182          return q.resolve(success);
4183        }, function (err) {
4184          return q.reject(err);
4185        });
4186
4187        return q.promise;
4188      }
4189    };
4190
4191  }]);
4192
4193// install  :     cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-googleplus.git
4194// link     :     https://github.com/EddyVerbruggen/cordova-plugin-googleplus
4195
4196angular.module('ngCordova.plugins.googlePlus', [])
4197
4198  .factory('$cordovaGooglePlus', ['$q', '$window', function ($q, $window) {
4199
4200    return {
4201      login: function (iosKey) {
4202        var q = $q.defer();
4203
4204        if (iosKey === undefined) {
4205          iosKey = {};
4206        }
4207        $window.plugins.googleplus.login({'iOSApiKey': iosKey}, function (response) {
4208          q.resolve(response);
4209        }, function (error) {
4210          q.reject(error);
4211        });
4212
4213        return q.promise;
4214      },
4215
4216      silentLogin: function (iosKey) {
4217        var q = $q.defer();
4218
4219        if (iosKey === undefined) {
4220          iosKey = {};
4221        }
4222        $window.plugins.googleplus.trySilentLogin({'iOSApiKey': iosKey}, function (response) {
4223          q.resolve(response);
4224        }, function (error) {
4225          q.reject(error);
4226        });
4227
4228        return q.promise;
4229      },
4230
4231      logout: function () {
4232        var q = $q.defer();
4233        $window.plugins.googleplus.logout(function (response) {
4234          q.resolve(response);
4235        });
4236      },
4237
4238      disconnect: function () {
4239        var q = $q.defer();
4240        $window.plugins.googleplus.disconnect(function (response) {
4241          q.resolve(response);
4242        });
4243      },
4244
4245      isAvailable: function () {
4246        var q = $q.defer();
4247        $window.plugins.googleplus.isAvailable(function (available) {
4248          if (available) {
4249            q.resolve(available);
4250          } else {
4251            q.reject(available);
4252          }
4253        });
4254        
4255        return q.promise;
4256      }
4257    };
4258
4259  }]);
4260
4261// install   :      cordova plugin add https://github.com/Telerik-Verified-Plugins/HealthKit.git
4262// link      :      https://github.com/Telerik-Verified-Plugins/HealthKit
4263
4264angular.module('ngCordova.plugins.healthKit', [])
4265
4266  .factory('$cordovaHealthKit', ['$q', '$window', function ($q, $window) {
4267
4268    return {
4269      isAvailable: function () {
4270        var q = $q.defer();
4271
4272        $window.plugins.healthkit.available(function (success) {
4273          q.resolve(success);
4274        }, function (err) {
4275          q.reject(err);
4276        });
4277
4278        return q.promise;
4279      },
4280
4281      /**
4282       * Check whether or not the user granted your app access to a specific HealthKit type.
4283       * Reference for possible types:
4284       * https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Constants/
4285       */
4286      checkAuthStatus: function (type) {
4287        var q = $q.defer();
4288
4289        type = type || 'HKQuantityTypeIdentifierHeight';
4290
4291        $window.plugins.healthkit.checkAuthStatus({
4292          'type': type
4293        }, function (success) {
4294          q.resolve(success);
4295        }, function (err) {
4296          q.reject(err);
4297        });
4298
4299        return q.promise;
4300      },
4301
4302      /**
4303       * Request authorization to access HealthKit data. See the full HealthKit constants
4304       * reference for possible read and write types:
4305       * https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Constants/
4306       */
4307      requestAuthorization: function (readTypes, writeTypes) {
4308        var q = $q.defer();
4309
4310        readTypes = readTypes || [
4311          'HKCharacteristicTypeIdentifierDateOfBirth', 'HKQuantityTypeIdentifierActiveEnergyBurned', 'HKQuantityTypeIdentifierHeight'
4312        ];
4313        writeTypes = writeTypes || [
4314          'HKQuantityTypeIdentifierActiveEnergyBurned', 'HKQuantityTypeIdentifierHeight', 'HKQuantityTypeIdentifierDistanceCycling'
4315        ];
4316
4317        $window.plugins.healthkit.requestAuthorization({
4318          'readTypes': readTypes,
4319          'writeTypes': writeTypes
4320        }, function (success) {
4321          q.resolve(success);
4322        }, function (err) {
4323          q.reject(err);
4324        });
4325
4326        return q.promise;
4327      },
4328
4329      readDateOfBirth: function () {
4330        var q = $q.defer();
4331        $window.plugins.healthkit.readDateOfBirth(
4332          function (success) {
4333            q.resolve(success);
4334          },
4335          function (err) {
4336            q.resolve(err);
4337          }
4338        );
4339
4340        return q.promise;
4341      },
4342
4343      readGender: function () {
4344        var q = $q.defer();
4345        $window.plugins.healthkit.readGender(
4346          function (success) {
4347            q.resolve(success);
4348          },
4349          function (err) {
4350            q.resolve(err);
4351          }
4352        );
4353
4354        return q.promise;
4355      },
4356
4357      saveWeight: function (value, units, date) {
4358        var q = $q.defer();
4359        $window.plugins.healthkit.saveWeight({
4360            'unit': units || 'lb',
4361            'amount': value,
4362            'date': date || new Date()
4363          },
4364          function (success) {
4365            q.resolve(success);
4366          },
4367          function (err) {
4368            q.resolve(err);
4369          }
4370        );
4371        return q.promise;
4372      },
4373
4374      readWeight: function (units) {
4375        var q = $q.defer();
4376        $window.plugins.healthkit.readWeight({
4377            'unit': units || 'lb'
4378          },
4379          function (success) {
4380            q.resolve(success);
4381          },
4382          function (err) {
4383            q.resolve(err);
4384          }
4385        );
4386
4387        return q.promise;
4388      },
4389      saveHeight: function (value, units, date) {
4390        var q = $q.defer();
4391        $window.plugins.healthkit.saveHeight({
4392            'unit': units || 'in',
4393            'amount': value,
4394            'date': date || new Date()
4395          },
4396          function (success) {
4397            q.resolve(success);
4398          },
4399          function (err) {
4400            q.resolve(err);
4401          }
4402        );
4403        return q.promise;
4404      },
4405      readHeight: function (units) {
4406        var q = $q.defer();
4407        $window.plugins.healthkit.readHeight({
4408            'unit': units || 'in'
4409          },
4410          function (success) {
4411            q.resolve(success);
4412          },
4413          function (err) {
4414            q.resolve(err);
4415          }
4416        );
4417
4418        return q.promise;
4419      },
4420
4421      findWorkouts: function () {
4422        var q = $q.defer();
4423        $window.plugins.healthkit.findWorkouts({},
4424          function (success) {
4425            q.resolve(success);
4426          },
4427          function (err) {
4428            q.resolve(err);
4429          }
4430        );
4431        return q.promise;
4432      },
4433
4434      /**
4435       * Save a workout.
4436       *
4437       * Workout param should be of the format:
4438       {
4439         'activityType': 'HKWorkoutActivityTypeCycling', // HKWorkoutActivityType constant (https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HKWorkout_Class/#//apple_ref/c/tdef/HKWorkoutActivityType)
4440         'quantityType': 'HKQuantityTypeIdentifierDistanceCycling',
4441         'startDate': new Date(), // mandatory
4442         'endDate': null, // optional, use either this or duration
4443         'duration': 3600, // in seconds, optional, use either this or endDate
4444         'energy': 300, //
4445         'energyUnit': 'kcal', // J|cal|kcal
4446         'distance': 11, // optional
4447         'distanceUnit': 'km' // probably useful with the former param
4448         // 'extraData': "", // Not sure how necessary this is
4449       },
4450       */
4451      saveWorkout: function (workout) {
4452        var q = $q.defer();
4453        $window.plugins.healthkit.saveWorkout(workout,
4454          function (success) {
4455            q.resolve(success);
4456          },
4457          function (err) {
4458            q.resolve(err);
4459          }
4460        );
4461        return q.promise;
4462      },
4463
4464      /**
4465       * Sample any kind of health data through a given date range.
4466       * sampleQuery of the format:
4467       {
4468									'startDate': yesterday, // mandatory
4469									'endDate': tomorrow, // mandatory
4470									'sampleType': 'HKQuantityTypeIdentifierHeight',
4471									'unit' : 'cm'
4472							},
4473       */
4474      querySampleType: function (sampleQuery) {
4475        var q = $q.defer();
4476        $window.plugins.healthkit.querySampleType(sampleQuery,
4477          function (success) {
4478            q.resolve(success);
4479          },
4480          function (err) {
4481            q.resolve(err);
4482          }
4483        );
4484        return q.promise;
4485      }
4486    };
4487  }]);
4488
4489// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-httpd.git
4490// link     :     https://github.com/floatinghotpot/cordova-httpd
4491
4492angular.module('ngCordova.plugins.httpd', [])
4493
4494  .factory('$cordovaHttpd', ['$q', function ($q) {
4495
4496    return {
4497      startServer: function (options) {
4498        var d = $q.defer();
4499
4500        cordova.plugins.CorHttpd.startServer(options, function () {
4501          d.resolve();
4502        }, function () {
4503          d.reject();
4504        });
4505
4506        return d.promise;
4507      },
4508
4509      stopServer: function () {
4510        var d = $q.defer();
4511
4512        cordova.plugins.CorHttpd.stopServer(function () {
4513          d.resolve();
4514        }, function () {
4515          d.reject();
4516        });
4517
4518        return d.promise;
4519      },
4520
4521      getURL: function () {
4522        var d = $q.defer();
4523
4524        cordova.plugins.CorHttpd.getURL(function (url) {
4525          d.resolve(url);
4526        }, function () {
4527          d.reject();
4528        });
4529
4530        return d.promise;
4531      },
4532
4533      getLocalPath: function () {
4534        var d = $q.defer();
4535
4536        cordova.plugins.CorHttpd.getLocalPath(function (path) {
4537          d.resolve(path);
4538        }, function () {
4539          d.reject();
4540        });
4541
4542        return d.promise;
4543      }
4544
4545    };
4546  }]);
4547
4548// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-plugin-iad.git
4549// link     :     https://github.com/floatinghotpot/cordova-plugin-iad
4550
4551angular.module('ngCordova.plugins.iAd', [])
4552  .factory('$cordovaiAd', ['$q', '$window', function ($q, $window) {
4553
4554    return {
4555      setOptions: function (options) {
4556        var d = $q.defer();
4557
4558        $window.iAd.setOptions(options, function () {
4559          d.resolve();
4560        }, function () {
4561          d.reject();
4562        });
4563
4564        return d.promise;
4565      },
4566
4567      createBanner: function (options) {
4568        var d = $q.defer();
4569
4570        $window.iAd.createBanner(options, function () {
4571          d.resolve();
4572        }, function () {
4573          d.reject();
4574        });
4575
4576        return d.promise;
4577      },
4578
4579      removeBanner: function () {
4580        var d = $q.defer();
4581
4582        $window.iAd.removeBanner(function () {
4583          d.resolve();
4584        }, function () {
4585          d.reject();
4586        });
4587
4588        return d.promise;
4589      },
4590
4591      showBanner: function (position) {
4592        var d = $q.defer();
4593
4594        $window.iAd.showBanner(position, function () {
4595          d.resolve();
4596        }, function () {
4597          d.reject();
4598        });
4599
4600        return d.promise;
4601      },
4602
4603      showBannerAtXY: function (x, y) {
4604        var d = $q.defer();
4605
4606        $window.iAd.showBannerAtXY(x, y, function () {
4607          d.resolve();
4608        }, function () {
4609          d.reject();
4610        });
4611
4612        return d.promise;
4613      },
4614
4615      hideBanner: function () {
4616        var d = $q.defer();
4617
4618        $window.iAd.hideBanner(function () {
4619          d.resolve();
4620        }, function () {
4621          d.reject();
4622        });
4623
4624        return d.promise;
4625      },
4626
4627      prepareInterstitial: function (options) {
4628        var d = $q.defer();
4629
4630        $window.iAd.prepareInterstitial(options, function () {
4631          d.resolve();
4632        }, function () {
4633          d.reject();
4634        });
4635
4636        return d.promise;
4637      },
4638
4639      showInterstitial: function () {
4640        var d = $q.defer();
4641
4642        $window.iAd.showInterstitial(function () {
4643          d.resolve();
4644        }, function () {
4645          d.reject();
4646        });
4647
4648        return d.promise;
4649      }
4650    };
4651  }]);
4652
4653// install  :     cordova plugin add https://github.com/wymsee/cordova-imagePicker.git
4654// link     :     https://github.com/wymsee/cordova-imagePicker
4655
4656angular.module('ngCordova.plugins.imagePicker', [])
4657
4658  .factory('$cordovaImagePicker', ['$q', '$window', function ($q, $window) {
4659
4660    return {
4661      getPictures: function (options) {
4662        var q = $q.defer();
4663
4664        $window.imagePicker.getPictures(function (results) {
4665          q.resolve(results);
4666        }, function (error) {
4667          q.reject(error);
4668        }, options);
4669
4670        return q.promise;
4671      }
4672    };
4673  }]);
4674
4675// install   :     cordova plugin add cordova-plugin-inappbrowser
4676// link      :     https://github.com/apache/cordova-plugin-inappbrowser
4677
4678angular.module('ngCordova.plugins.inAppBrowser', [])
4679
4680  .provider('$cordovaInAppBrowser', [function () {
4681
4682    var ref;
4683    var defaultOptions = this.defaultOptions = {};
4684
4685    this.setDefaultOptions = function (config) {
4686      defaultOptions = angular.extend(defaultOptions, config);
4687    };
4688
4689    this.$get = ['$rootScope', '$q', '$window', '$timeout', function ($rootScope, $q, $window, $timeout) {
4690      return {
4691        open: function (url, target, requestOptions) {
4692          var q = $q.defer();
4693
4694          if (requestOptions && !angular.isObject(requestOptions)) {
4695            q.reject('options must be an object');
4696            return q.promise;
4697          }
4698
4699          var options = angular.extend({}, defaultOptions, requestOptions);
4700
4701          var opt = [];
4702          angular.forEach(options, function (value, key) {
4703            opt.push(key + '=' + value);
4704          });
4705          var optionsString = opt.join();
4706
4707          ref = $window.open(url, target, optionsString);
4708
4709          ref.addEventListener('loadstart', function (event) {
4710            $timeout(function () {
4711              $rootScope.$broadcast('$cordovaInAppBrowser:loadstart', event);
4712            });
4713          }, false);
4714
4715          ref.addEventListener('loadstop', function (event) {
4716            q.resolve(event);
4717            $timeout(function () {
4718              $rootScope.$broadcast('$cordovaInAppBrowser:loadstop', event);
4719            });
4720          }, false);
4721
4722          ref.addEventListener('loaderror', function (event) {
4723            q.reject(event);
4724            $timeout(function () {
4725              $rootScope.$broadcast('$cordovaInAppBrowser:loaderror', event);
4726            });
4727          }, false);
4728
4729          ref.addEventListener('exit', function (event) {
4730            $timeout(function () {
4731              $rootScope.$broadcast('$cordovaInAppBrowser:exit', event);
4732            });
4733          }, false);
4734
4735          return q.promise;
4736        },
4737
4738        close: function () {
4739          ref.close();
4740          ref = null;
4741        },
4742
4743        show: function () {
4744          ref.show();
4745        },
4746
4747        executeScript: function (details) {
4748          var q = $q.defer();
4749
4750          ref.executeScript(details, function (result) {
4751            q.resolve(result);
4752          });
4753
4754          return q.promise;
4755        },
4756
4757        insertCSS: function (details) {
4758          var q = $q.defer();
4759
4760          ref.insertCSS(details, function (result) {
4761            q.resolve(result);
4762          });
4763
4764          return q.promise;
4765        }
4766      };
4767    }];
4768  }]);
4769
4770// install  :     cordova plugin add https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin.git
4771// link     :     https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin
4772angular.module('ngCordova.plugins.insomnia', [])
4773
4774  .factory('$cordovaInsomnia', ['$window', function ($window) {
4775
4776    return {
4777      keepAwake: function () {
4778        return $window.plugins.insomnia.keepAwake();
4779      },
4780      allowSleepAgain: function () {
4781        return $window.plugins.insomnia.allowSleepAgain();
4782      }
4783    };
4784
4785  }]);
4786
4787// install   :   cordova plugins add https://github.com/vstirbu/InstagramPlugin.git
4788// link      :   https://github.com/vstirbu/InstagramPlugin
4789
4790/* globals Instagram: true */
4791angular.module('ngCordova.plugins.instagram', [])
4792
4793.factory('$cordovaInstagram', ['$q', function ($q) {
4794
4795  return {
4796    share: function (options) {
4797      var q = $q.defer();
4798
4799      if (!window.Instagram) {
4800        console.error('Tried to call Instagram.share but the Instagram plugin isn\'t installed!');
4801        q.resolve(null);
4802        return q.promise;
4803      }
4804
4805      Instagram.share(options.image, options.caption, function (err) {
4806        if(err) {
4807          q.reject(err);
4808        } else {
4809          q.resolve(true);
4810        }
4811      });
4812      return q.promise;
4813    },
4814    isInstalled: function () {
4815      var q = $q.defer();
4816
4817      if (!window.Instagram) {
4818        console.error('Tried to call Instagram.isInstalled but the Instagram plugin isn\'t installed!');
4819        q.resolve(null);
4820        return q.promise;
4821      }
4822
4823      Instagram.isInstalled(function (err, installed) {
4824        if (err) {
4825          q.reject(err);
4826        } else {
4827          q.resolve(installed);
4828        }
4829      });
4830      return q.promise;
4831    }
4832  };
4833}]);
4834
4835// install   :      cordova plugin add https://github.com/driftyco/ionic-plugins-keyboard.git
4836// link      :      https://github.com/driftyco/ionic-plugins-keyboard
4837
4838angular.module('ngCordova.plugins.keyboard', [])
4839
4840  .factory('$cordovaKeyboard', ['$rootScope', function ($rootScope) {
4841
4842    var keyboardShowEvent = function () {
4843      $rootScope.$evalAsync(function () {
4844        $rootScope.$broadcast('$cordovaKeyboard:show');
4845      });
4846    };
4847
4848    var keyboardHideEvent = function () {
4849      $rootScope.$evalAsync(function () {
4850        $rootScope.$broadcast('$cordovaKeyboard:hide');
4851      });
4852    };
4853
4854    document.addEventListener('deviceready', function () {
4855      if (cordova.plugins.Keyboard) {
4856        window.addEventListener('native.keyboardshow', keyboardShowEvent, false);
4857        window.addEventListener('native.keyboardhide', keyboardHideEvent, false);
4858      }
4859    });
4860
4861    return {
4862      hideAccessoryBar: function (bool) {
4863        return cordova.plugins.Keyboard.hideKeyboardAccessoryBar(bool);
4864      },
4865
4866      close: function () {
4867        return cordova.plugins.Keyboard.close();
4868      },
4869
4870      show: function () {
4871        return cordova.plugins.Keyboard.show();
4872      },
4873
4874      disableScroll: function (bool) {
4875        return cordova.plugins.Keyboard.disableScroll(bool);
4876      },
4877
4878      isVisible: function () {
4879        return cordova.plugins.Keyboard.isVisible;
4880      },
4881
4882      clearShowWatch: function () {
4883        document.removeEventListener('native.keyboardshow', keyboardShowEvent);
4884        $rootScope.$$listeners['$cordovaKeyboard:show'] = [];
4885      },
4886
4887      clearHideWatch: function () {
4888        document.removeEventListener('native.keyboardhide', keyboardHideEvent);
4889        $rootScope.$$listeners['$cordovaKeyboard:hide'] = [];
4890      }
4891    };
4892  }]);
4893
4894// install   :      cordova plugin add https://github.com/shazron/KeychainPlugin.git
4895// link      :      https://github.com/shazron/KeychainPlugin
4896
4897/* globals Keychain: true */
4898angular.module('ngCordova.plugins.keychain', [])
4899
4900  .factory('$cordovaKeychain', ['$q', function ($q) {
4901
4902    return {
4903      getForKey: function (key, serviceName) {
4904        var defer = $q.defer(),
4905            kc = new Keychain();
4906
4907        kc.getForKey(defer.resolve, defer.reject, key, serviceName);
4908
4909        return defer.promise;
4910      },
4911
4912      setForKey: function (key, serviceName, value) {
4913        var defer = $q.defer(),
4914            kc = new Keychain();
4915
4916        kc.setForKey(defer.resolve, defer.reject, key, serviceName, value);
4917
4918        return defer.promise;
4919      },
4920
4921      removeForKey: function (key, serviceName) {
4922        var defer = $q.defer(),
4923            kc = new Keychain();
4924
4925        kc.removeForKey(defer.resolve, defer.reject, key, serviceName);
4926
4927        return defer.promise;
4928      }
4929    };
4930  }]);
4931
4932// install   :      cordova plugin add uk.co.workingedge.phonegap.plugin.launchnavigator
4933// link      :      https://github.com/dpa99c/phonegap-launch-navigator
4934
4935/* globals launchnavigator: true */
4936angular.module('ngCordova.plugins.launchNavigator', [])
4937
4938  .factory('$cordovaLaunchNavigator', ['$q', function ($q) {
4939
4940    return {
4941      navigate: function (destination, start, options) {
4942        var q = $q.defer();
4943        launchnavigator.navigate(
4944          destination,
4945          start,
4946          function (){
4947            q.resolve();
4948          },
4949          function (error){
4950            q.reject(error);
4951          },
4952		  options);
4953        return q.promise;
4954      }
4955    };
4956
4957  }]);
4958
4959// install   :  cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications.git
4960// link      :  https://github.com/katzer/cordova-plugin-local-notifications
4961
4962angular.module('ngCordova.plugins.localNotification', [])
4963
4964  .factory('$cordovaLocalNotification', ['$q', '$window', '$rootScope', '$timeout', function ($q, $window, $rootScope, $timeout) {
4965    document.addEventListener('deviceready', function () {
4966      if ($window.cordova &&
4967        $window.cordova.plugins &&
4968        $window.cordova.plugins.notification &&
4969        $window.cordova.plugins.notification.local) {
4970        // ----- "Scheduling" events
4971
4972        // A local notification was scheduled
4973        $window.cordova.plugins.notification.local.on('schedule', function (notification, state) {
4974          $timeout(function () {
4975            $rootScope.$broadcast('$cordovaLocalNotification:schedule', notification, state);
4976          });
4977        });
4978
4979        // A local notification was triggered
4980        $window.cordova.plugins.notification.local.on('trigger', function (notification, state) {
4981          $timeout(function () {
4982            $rootScope.$broadcast('$cordovaLocalNotification:trigger', notification, state);
4983          });
4984        });
4985
4986        // ----- "Update" events
4987
4988        // A local notification was updated
4989        $window.cordova.plugins.notification.local.on('update', function (notification, state) {
4990          $timeout(function () {
4991            $rootScope.$broadcast('$cordovaLocalNotification:update', notification, state);
4992          });
4993        });
4994
4995        // ----- "Clear" events
4996
4997        // A local notification was cleared from the notification center
4998        $window.cordova.plugins.notification.local.on('clear', function (notification, state) {
4999          $timeout(function () {
5000            $rootScope.$broadcast('$cordovaLocalNotification:clear', notification, state);
5001          });
5002        });
5003
5004        // All local notifications were cleared from the notification center
5005        $window.cordova.plugins.notification.local.on('clearall', function (state) {
5006          $timeout(function () {
5007            $rootScope.$broadcast('$cordovaLocalNotification:clearall', state);
5008          });
5009        });
5010
5011        // ----- "Cancel" events
5012
5013        // A local notification was cancelled
5014        $window.cordova.plugins.notification.local.on('cancel', function (notification, state) {
5015          $timeout(function () {
5016            $rootScope.$broadcast('$cordovaLocalNotification:cancel', notification, state);
5017          });
5018        });
5019
5020        // All local notifications were cancelled
5021        $window.cordova.plugins.notification.local.on('cancelall', function (state) {
5022          $timeout(function () {
5023            $rootScope.$broadcast('$cordovaLocalNotification:cancelall', state);
5024          });
5025        });
5026
5027        // ----- Other events
5028
5029        // A local notification was clicked
5030        $window.cordova.plugins.notification.local.on('click', function (notification, state) {
5031          $timeout(function () {
5032            $rootScope.$broadcast('$cordovaLocalNotification:click', notification, state);
5033          });
5034        });
5035      }
5036    }, false);
5037    return {
5038      schedule: function (options, scope) {
5039        var q = $q.defer();
5040        scope = scope || null;
5041
5042        $window.cordova.plugins.notification.local.schedule(options, function (result) {
5043          q.resolve(result);
5044        }, scope);
5045
5046        return q.promise;
5047      },
5048
5049      add: function (options, scope) {
5050        console.warn('Deprecated: use "schedule" instead.');
5051
5052        var q = $q.defer();
5053        scope = scope || null;
5054
5055        $window.cordova.plugins.notification.local.schedule(options, function (result) {
5056          q.resolve(result);
5057        }, scope);
5058
5059        return q.promise;
5060      },
5061
5062      update: function (options, scope) {
5063        var q = $q.defer();
5064        scope = scope || null;
5065
5066        $window.cordova.plugins.notification.local.update(options, function (result) {
5067          q.resolve(result);
5068        }, scope);
5069
5070        return q.promise;
5071      },
5072
5073      clear: function (ids, scope) {
5074        var q = $q.defer();
5075        scope = scope || null;
5076
5077        $window.cordova.plugins.notification.local.clear(ids, function (result) {
5078          q.resolve(result);
5079        }, scope);
5080
5081        return q.promise;
5082      },
5083
5084      clearAll: function (scope) {
5085        var q = $q.defer();
5086        scope = scope || null;
5087
5088        $window.cordova.plugins.notification.local.clearAll(function (result) {
5089          q.resolve(result);
5090        }, scope);
5091
5092        return q.promise;
5093      },
5094
5095      cancel: function (ids, scope) {
5096        var q = $q.defer();
5097        scope = scope || null;
5098
5099        $window.cordova.plugins.notification.local.cancel(ids, function (result) {
5100          q.resolve(result);
5101        }, scope);
5102
5103        return q.promise;
5104      },
5105
5106      cancelAll: function (scope) {
5107        var q = $q.defer();
5108        scope = scope || null;
5109
5110        $window.cordova.plugins.notification.local.cancelAll(function (result) {
5111          q.resolve(result);
5112        }, scope);
5113
5114        return q.promise;
5115      },
5116
5117      isPresent: function (id, scope) {
5118        var q = $q.defer();
5119        scope = scope || null;
5120
5121        $window.cordova.plugins.notification.local.isPresent(id, function (result) {
5122          q.resolve(result);
5123        }, scope);
5124
5125        return q.promise;
5126      },
5127
5128      isScheduled: function (id, scope) {
5129        var q = $q.defer();
5130        scope = scope || null;
5131
5132        $window.cordova.plugins.notification.local.isScheduled(id, function (result) {
5133          q.resolve(result);
5134        }, scope);
5135
5136        return q.promise;
5137      },
5138
5139      isTriggered: function (id, scope) {
5140        var q = $q.defer();
5141        scope = scope || null;
5142
5143        $window.cordova.plugins.notification.local.isTriggered(id, function (result) {
5144          q.resolve(result);
5145        }, scope);
5146
5147        return q.promise;
5148      },
5149
5150      hasPermission: function (scope) {
5151        var q = $q.defer();
5152        scope = scope || null;
5153
5154        $window.cordova.plugins.notification.local.hasPermission(function (result) {
5155          if (result) {
5156            q.resolve(result);
5157          } else {
5158            q.reject(result);
5159          }
5160        }, scope);
5161
5162        return q.promise;
5163      },
5164
5165      registerPermission: function (scope) {
5166        var q = $q.defer();
5167        scope = scope || null;
5168
5169        $window.cordova.plugins.notification.local.registerPermission(function (result) {
5170          if (result) {
5171            q.resolve(result);
5172          } else {
5173            q.reject(result);
5174          }
5175        }, scope);
5176
5177        return q.promise;
5178      },
5179
5180      promptForPermission: function (scope) {
5181        console.warn('Deprecated: use "registerPermission" instead.');
5182
5183        var q = $q.defer();
5184        scope = scope || null;
5185
5186        $window.cordova.plugins.notification.local.registerPermission(function (result) {
5187          if (result) {
5188            q.resolve(result);
5189          } else {
5190            q.reject(result);
5191          }
5192        }, scope);
5193
5194        return q.promise;
5195      },
5196
5197      getAllIds: function (scope) {
5198        var q = $q.defer();
5199        scope = scope || null;
5200
5201        $window.cordova.plugins.notification.local.getAllIds(function (result) {
5202          q.resolve(result);
5203        }, scope);
5204
5205        return q.promise;
5206      },
5207
5208      getIds: function (scope) {
5209        var q = $q.defer();
5210        scope = scope || null;
5211
5212        $window.cordova.plugins.notification.local.getIds(function (result) {
5213          q.resolve(result);
5214        }, scope);
5215
5216        return q.promise;
5217      },
5218
5219      getScheduledIds: function (scope) {
5220        var q = $q.defer();
5221        scope = scope || null;
5222
5223        $window.cordova.plugins.notification.local.getScheduledIds(function (result) {
5224          q.resolve(result);
5225        }, scope);
5226
5227        return q.promise;
5228      },
5229
5230      getTriggeredIds: function (scope) {
5231        var q = $q.defer();
5232        scope = scope || null;
5233
5234        $window.cordova.plugins.notification.local.getTriggeredIds(function (result) {
5235          q.resolve(result);
5236        }, scope);
5237
5238        return q.promise;
5239      },
5240
5241      get: function (ids, scope) {
5242        var q = $q.defer();
5243        scope = scope || null;
5244
5245        $window.cordova.plugins.notification.local.get(ids, function (result) {
5246          q.resolve(result);
5247        }, scope);
5248
5249        return q.promise;
5250      },
5251
5252      getAll: function (scope) {
5253        var q = $q.defer();
5254        scope = scope || null;
5255
5256        $window.cordova.plugins.notification.local.getAll(function (result) {
5257          q.resolve(result);
5258        }, scope);
5259
5260        return q.promise;
5261      },
5262
5263      getScheduled: function (ids, scope) {
5264        var q = $q.defer();
5265        scope = scope || null;
5266
5267        $window.cordova.plugins.notification.local.getScheduled(ids, function (result) {
5268          q.resolve(result);
5269        }, scope);
5270
5271        return q.promise;
5272      },
5273
5274      getAllScheduled: function (scope) {
5275        var q = $q.defer();
5276        scope = scope || null;
5277
5278        $window.cordova.plugins.notification.local.getAllScheduled(function (result) {
5279          q.resolve(result);
5280        }, scope);
5281
5282        return q.promise;
5283      },
5284
5285      getTriggered: function (ids, scope) {
5286        var q = $q.defer();
5287        scope = scope || null;
5288
5289        $window.cordova.plugins.notification.local.getTriggered(ids, function (result) {
5290          q.resolve(result);
5291        }, scope);
5292
5293        return q.promise;
5294      },
5295
5296      getAllTriggered: function (scope) {
5297        var q = $q.defer();
5298        scope = scope || null;
5299
5300        $window.cordova.plugins.notification.local.getAllTriggered(function (result) {
5301          q.resolve(result);
5302        }, scope);
5303
5304        return q.promise;
5305      },
5306
5307      getDefaults: function () {
5308        return $window.cordova.plugins.notification.local.getDefaults();
5309      },
5310
5311      setDefaults: function (Object) {
5312        $window.cordova.plugins.notification.local.setDefaults(Object);
5313      }
5314    };
5315  }]);
5316
5317// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-plugin-mmedia.git
5318// link     :     https://github.com/floatinghotpot/cordova-plugin-mmedia
5319
5320angular.module('ngCordova.plugins.mMediaAds', [])
5321
5322  .factory('$cordovaMMediaAds', ['$q', '$window', function ($q, $window) {
5323
5324    return {
5325      setOptions: function (options) {
5326        var d = $q.defer();
5327
5328        $window.mMedia.setOptions(options, function () {
5329          d.resolve();
5330        }, function () {
5331          d.reject();
5332        });
5333
5334        return d.promise;
5335      },
5336
5337      createBanner: function (options) {
5338        var d = $q.defer();
5339
5340        $window.mMedia.createBanner(options, function () {
5341          d.resolve();
5342        }, function () {
5343          d.reject();
5344        });
5345
5346        return d.promise;
5347      },
5348
5349      removeBanner: function () {
5350        var d = $q.defer();
5351
5352        $window.mMedia.removeBanner(function () {
5353          d.resolve();
5354        }, function () {
5355          d.reject();
5356        });
5357
5358        return d.promise;
5359      },
5360
5361      showBanner: function (position) {
5362        var d = $q.defer();
5363
5364        $window.mMedia.showBanner(position, function () {
5365          d.resolve();
5366        }, function () {
5367          d.reject();
5368        });
5369
5370        return d.promise;
5371      },
5372
5373      showBannerAtXY: function (x, y) {
5374        var d = $q.defer();
5375
5376        $window.mMedia.showBannerAtXY(x, y, function () {
5377          d.resolve();
5378        }, function () {
5379          d.reject();
5380        });
5381
5382        return d.promise;
5383      },
5384
5385      hideBanner: function () {
5386        var d = $q.defer();
5387
5388        $window.mMedia.hideBanner(function () {
5389          d.resolve();
5390        }, function () {
5391          d.reject();
5392        });
5393
5394        return d.promise;
5395      },
5396
5397      prepareInterstitial: function (options) {
5398        var d = $q.defer();
5399
5400        $window.mMedia.prepareInterstitial(options, function () {
5401          d.resolve();
5402        }, function () {
5403          d.reject();
5404        });
5405
5406        return d.promise;
5407      },
5408
5409      showInterstitial: function () {
5410        var d = $q.defer();
5411
5412        $window.mMedia.showInterstitial(function () {
5413          d.resolve();
5414        }, function () {
5415          d.reject();
5416        });
5417
5418        return d.promise;
5419      }
5420    };
5421  }]);
5422
5423// install   :      cordova plugin add cordova-plugin-media
5424// link      :      https://github.com/apache/cordova-plugin-media
5425
5426/* globals Media: true */
5427angular.module('ngCordova.plugins.media', [])
5428
5429.service('NewMedia', ['$q', '$interval', function ($q, $interval) {
5430  var q, q2, q3, mediaStatus = null, mediaPosition = -1, mediaTimer, mediaDuration = -1;
5431
5432  function setTimer(media) {
5433      if (angular.isDefined(mediaTimer)) {
5434        return;
5435      }
5436
5437      mediaTimer = $interval(function () {
5438          if (mediaDuration < 0) {
5439              mediaDuration = media.getDuration();
5440              if (q && mediaDuration > 0) {
5441                q.notify({duration: mediaDuration});
5442              }
5443          }
5444
5445          media.getCurrentPosition(
5446            // success callback
5447            function (position) {
5448                if (position > -1) {
5449                    mediaPosition = position;
5450                }
5451            },
5452            // error callback
5453            function (e) {
5454                console.log('Error getting pos=' + e);
5455            });
5456
5457          if (q) {
5458            q.notify({position: mediaPosition});
5459          }
5460
5461      }, 1000);
5462  }
5463
5464  function clearTimer() {
5465      if (angular.isDefined(mediaTimer)) {
5466          $interval.cancel(mediaTimer);
5467          mediaTimer = undefined;
5468      }
5469  }
5470
5471  function resetValues() {
5472      mediaPosition = -1;
5473      mediaDuration = -1;
5474  }
5475
5476  function NewMedia(src) {
5477      this.media = new Media(src,
5478        function (success) {
5479            clearTimer();
5480            resetValues();
5481            q.resolve(success);
5482        }, function (error) {
5483            clearTimer();
5484            resetValues();
5485            q.reject(error);
5486        }, function (status) {
5487            mediaStatus = status;
5488            q.notify({status: mediaStatus});
5489        });
5490  }
5491
5492  // iOS quirks :
5493  // -  myMedia.play({ numberOfLoops: 2 }) -> looping
5494  // -  myMedia.play({ playAudioWhenScreenIsLocked : false })
5495  NewMedia.prototype.play = function (options) {
5496      q = $q.defer();
5497
5498      if (typeof options !== 'object') {
5499          options = {};
5500      }
5501
5502      this.media.play(options);
5503
5504      setTimer(this.media);
5505
5506      return q.promise;
5507  };
5508
5509  NewMedia.prototype.pause = function () {
5510      clearTimer();
5511      this.media.pause();
5512  };
5513
5514  NewMedia.prototype.stop  = function () {
5515      this.media.stop();
5516  };
5517
5518  NewMedia.prototype.release  = function () {
5519      this.media.release();
5520      this.media = undefined;
5521  };
5522
5523  NewMedia.prototype.seekTo  = function (timing) {
5524      this.media.seekTo(timing);
5525  };
5526
5527  NewMedia.prototype.setVolume = function (volume) {
5528      this.media.setVolume(volume);
5529  };
5530
5531  NewMedia.prototype.startRecord = function () {
5532      this.media.startRecord();
5533  };
5534
5535  NewMedia.prototype.stopRecord  = function () {
5536      this.media.stopRecord();
5537  };
5538
5539  NewMedia.prototype.currentTime = function () {
5540      q2 = $q.defer();
5541      this.media.getCurrentPosition(function (position){
5542      q2.resolve(position);
5543      });
5544      return q2.promise;
5545  };
5546
5547  NewMedia.prototype.getDuration = function () {
5548    q3 = $q.defer();
5549    this.media.getDuration(function (duration){
5550    q3.resolve(duration);
5551    });
5552    return q3.promise;
5553  };
5554
5555  return NewMedia;
5556
5557}])
5558.factory('$cordovaMedia', ['NewMedia', function (NewMedia) {
5559  return {
5560      newMedia: function (src) {
5561          return new NewMedia(src);
5562      }
5563  };
5564}]);
5565
5566// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-mobfox-pro.git
5567// link     :     https://github.com/floatinghotpot/cordova-mobfox-pro
5568
5569angular.module('ngCordova.plugins.mobfoxAds', [])
5570
5571  .factory('$cordovaMobFoxAds', ['$q', '$window', function ($q, $window) {
5572
5573    return {
5574      setOptions: function (options) {
5575        var d = $q.defer();
5576
5577        $window.MobFox.setOptions(options, function () {
5578          d.resolve();
5579        }, function () {
5580          d.reject();
5581        });
5582
5583        return d.promise;
5584      },
5585
5586      createBanner: function (options) {
5587        var d = $q.defer();
5588
5589        $window.MobFox.createBanner(options, function () {
5590          d.resolve();
5591        }, function () {
5592          d.reject();
5593        });
5594
5595        return d.promise;
5596      },
5597
5598      removeBanner: function () {
5599        var d = $q.defer();
5600
5601        $window.MobFox.removeBanner(function () {
5602          d.resolve();
5603        }, function () {
5604          d.reject();
5605        });
5606
5607        return d.promise;
5608      },
5609
5610      showBanner: function (position) {
5611        var d = $q.defer();
5612
5613        $window.MobFox.showBanner(position, function () {
5614          d.resolve();
5615        }, function () {
5616          d.reject();
5617        });
5618
5619        return d.promise;
5620      },
5621
5622      showBannerAtXY: function (x, y) {
5623        var d = $q.defer();
5624
5625        $window.MobFox.showBannerAtXY(x, y, function () {
5626          d.resolve();
5627        }, function () {
5628          d.reject();
5629        });
5630
5631        return d.promise;
5632      },
5633
5634      hideBanner: function () {
5635        var d = $q.defer();
5636
5637        $window.MobFox.hideBanner(function () {
5638          d.resolve();
5639        }, function () {
5640          d.reject();
5641        });
5642
5643        return d.promise;
5644      },
5645
5646      prepareInterstitial: function (options) {
5647        var d = $q.defer();
5648
5649        $window.MobFox.prepareInterstitial(options, function () {
5650          d.resolve();
5651        }, function () {
5652          d.reject();
5653        });
5654
5655        return d.promise;
5656      },
5657
5658      showInterstitial: function () {
5659        var d = $q.defer();
5660
5661        $window.MobFox.showInterstitial(function () {
5662          d.resolve();
5663        }, function () {
5664          d.reject();
5665        });
5666
5667        return d.promise;
5668      }
5669    };
5670  }]);
5671
5672angular.module('ngCordova.plugins', [
5673  'ngCordova.plugins.3dtouch',
5674  'ngCordova.plugins.actionSheet',
5675  'ngCordova.plugins.adMob',
5676  'ngCordova.plugins.appAvailability',
5677  'ngCordova.plugins.appRate',
5678  'ngCordova.plugins.appVersion',
5679  'ngCordova.plugins.backgroundGeolocation',
5680  'ngCordova.plugins.badge',
5681  'ngCordova.plugins.barcodeScanner',
5682  'ngCordova.plugins.batteryStatus',
5683  'ngCordova.plugins.beacon',
5684  'ngCordova.plugins.ble',
5685  'ngCordova.plugins.bluetoothSerial',
5686  'ngCordova.plugins.brightness',
5687  'ngCordova.plugins.calendar',
5688  'ngCordova.plugins.camera',
5689  'ngCordova.plugins.capture',
5690  'ngCordova.plugins.clipboard',
5691  'ngCordova.plugins.contacts',
5692  'ngCordova.plugins.datePicker',
5693  'ngCordova.plugins.device',
5694  'ngCordova.plugins.deviceMotion',
5695  'ngCordova.plugins.deviceOrientation',
5696  'ngCordova.plugins.dialogs',
5697  'ngCordova.plugins.emailComposer',
5698  'ngCordova.plugins.facebook',
5699  'ngCordova.plugins.facebookAds',
5700  'ngCordova.plugins.file',
5701  'ngCordova.plugins.fileTransfer',
5702  'ngCordova.plugins.fileOpener2',
5703  'ngCordova.plugins.flashlight',
5704  'ngCordova.plugins.flurryAds',
5705  'ngCordova.plugins.ga',
5706  'ngCordova.plugins.geolocation',
5707  'ngCordova.plugins.globalization',
5708  'ngCordova.plugins.googleAds',
5709  'ngCordova.plugins.googleAnalytics',
5710  'ngCordova.plugins.googleMap',
5711  'ngCordova.plugins.googlePlayGame',
5712  'ngCordova.plugins.googlePlus',
5713  'ngCordova.plugins.healthKit',
5714  'ngCordova.plugins.httpd',
5715  'ngCordova.plugins.iAd',
5716  'ngCordova.plugins.imagePicker',
5717  'ngCordova.plugins.inAppBrowser',
5718  'ngCordova.plugins.instagram',
5719  'ngCordova.plugins.keyboard',
5720  'ngCordova.plugins.keychain',
5721  'ngCordova.plugins.launchNavigator',
5722  'ngCordova.plugins.localNotification',
5723  'ngCordova.plugins.media',
5724  'ngCordova.plugins.mMediaAds',
5725  'ngCordova.plugins.mobfoxAds',
5726  'ngCordova.plugins.mopubAds',
5727  'ngCordova.plugins.nativeAudio',
5728  'ngCordova.plugins.network',
5729  'ngCordova.plugins.pinDialog',
5730  'ngCordova.plugins.preferences',
5731  'ngCordova.plugins.printer',
5732  'ngCordova.plugins.progressIndicator',
5733  'ngCordova.plugins.push',
5734  'ngCordova.plugins.push_v5',
5735  'ngCordova.plugins.sms',
5736  'ngCordova.plugins.socialSharing',
5737  'ngCordova.plugins.spinnerDialog',
5738  'ngCordova.plugins.splashscreen',
5739  'ngCordova.plugins.sqlite',
5740  'ngCordova.plugins.statusbar',
5741  'ngCordova.plugins.toast',
5742  'ngCordova.plugins.touchid',
5743  'ngCordova.plugins.vibration',
5744  'ngCordova.plugins.videoCapturePlus',
5745  'ngCordova.plugins.zip',
5746  'ngCordova.plugins.insomnia'
5747]);
5748
5749// install  :     cordova plugin add https://github.com/floatinghotpot/cordova-plugin-mopub.git
5750// link     :     https://github.com/floatinghotpot/cordova-plugin-mopub
5751
5752angular.module('ngCordova.plugins.mopubAds', [])
5753  .factory('$cordovaMoPubAds', ['$q', '$window', function ($q, $window) {
5754
5755    return {
5756      setOptions: function (options) {
5757        var d = $q.defer();
5758
5759        $window.MoPub.setOptions(options, function () {
5760          d.resolve();
5761        }, function () {
5762          d.reject();
5763        });
5764
5765        return d.promise;
5766      },
5767
5768      createBanner: function (options) {
5769        var d = $q.defer();
5770
5771        $window.MoPub.createBanner(options, function () {
5772          d.resolve();
5773        }, function () {
5774          d.reject();
5775        });
5776
5777        return d.promise;
5778      },
5779
5780      removeBanner: function () {
5781        var d = $q.defer();
5782
5783        $window.MoPub.removeBanner(function () {
5784          d.resolve();
5785        }, function () {
5786          d.reject();
5787        });
5788
5789        return d.promise;
5790      },
5791
5792      showBanner: function (position) {
5793        var d = $q.defer();
5794
5795        $window.MoPub.showBanner(position, function () {
5796          d.resolve();
5797        }, function () {
5798          d.reject();
5799        });
5800
5801        return d.promise;
5802      },
5803
5804      showBannerAtXY: function (x, y) {
5805        var d = $q.defer();
5806
5807        $window.MoPub.showBannerAtXY(x, y, function () {
5808          d.resolve();
5809        }, function () {
5810          d.reject();
5811        });
5812
5813        return d.promise;
5814      },
5815
5816      hideBanner: function () {
5817        var d = $q.defer();
5818
5819        $window.MoPub.hideBanner(function () {
5820          d.resolve();
5821        }, function () {
5822          d.reject();
5823        });
5824
5825        return d.promise;
5826      },
5827
5828      prepareInterstitial: function (options) {
5829        var d = $q.defer();
5830
5831        $window.MoPub.prepareInterstitial(options, function () {
5832          d.resolve();
5833        }, function () {
5834          d.reject();
5835        });
5836
5837        return d.promise;
5838      },
5839
5840      showInterstitial: function () {
5841        var d = $q.defer();
5842
5843        $window.MoPub.showInterstitial(function () {
5844          d.resolve();
5845        }, function () {
5846          d.reject();
5847        });
5848
5849        return d.promise;
5850      }
5851    };
5852  }]);
5853
5854// install   : cordova plugin add https://github.com/sidneys/cordova-plugin-nativeaudio.git
5855// link      : https://github.com/sidneys/cordova-plugin-nativeaudio
5856
5857angular.module('ngCordova.plugins.nativeAudio', [])
5858
5859  .factory('$cordovaNativeAudio', ['$q', '$window', function ($q, $window) {
5860
5861    return {
5862      preloadSimple: function (id, assetPath) {
5863        var q = $q.defer();
5864        $window.plugins.NativeAudio.preloadSimple(id, assetPath, function (result) {
5865          q.resolve(result);
5866        }, function (err) {
5867          q.reject(err);
5868        });
5869
5870        return q.promise;
5871      },
5872
5873      preloadComplex: function (id, assetPath, volume, voices, delay) {
5874        var q = $q.defer();
5875        $window.plugins.NativeAudio.preloadComplex(id, assetPath, volume, voices, delay, function (result) {
5876          q.resolve(result);
5877        }, function (err) {
5878          q.reject(err);
5879        });
5880
5881        return q.promise;
5882      },
5883
5884      play: function (id, completeCallback) {
5885        var q = $q.defer();
5886        $window.plugins.NativeAudio.play(id, function (result) {
5887          q.resolve(result);
5888        }, function (err) {
5889          q.reject(err);
5890        }, completeCallback);
5891
5892        return q.promise;
5893      },
5894
5895      stop: function (id) {
5896        var q = $q.defer();
5897        $window.plugins.NativeAudio.stop(id, function (result) {
5898          q.resolve(result);
5899        }, function (err) {
5900          q.reject(err);
5901        });
5902        return q.promise;
5903      },
5904
5905      loop: function (id) {
5906        var q = $q.defer();
5907        $window.plugins.NativeAudio.loop(id, function (result) {
5908          q.resolve(result);
5909        }, function (err) {
5910          q.reject(err);
5911        });
5912
5913        return q.promise;
5914      },
5915
5916      unload: function (id) {
5917        var q = $q.defer();
5918        $window.plugins.NativeAudio.unload(id, function (result) {
5919          q.resolve(result);
5920        }, function (err) {
5921          q.reject(err);
5922        });
5923
5924        return q.promise;
5925      },
5926
5927      setVolumeForComplexAsset: function (id, volume) {
5928        var q = $q.defer();
5929        $window.plugins.NativeAudio.setVolumeForComplexAsset(id, volume, function (result) {
5930          q.resolve(result);
5931        }, function (err) {
5932          q.reject(err);
5933        });
5934
5935        return q.promise;
5936      }
5937    };
5938  }]);
5939
5940// install   :      cordova plugin add cordova-plugin-network-information
5941// link      :      https://github.com/apache/cordova-plugin-network-information
5942
5943/* globals Connection: true */
5944angular.module('ngCordova.plugins.network', [])
5945
5946  .factory('$cordovaNetwork', ['$rootScope', '$timeout', function ($rootScope, $timeout) {
5947
5948    /**
5949      * Fires offline a event
5950      */
5951    var offlineEvent = function () {
5952      var networkState = navigator.connection.type;
5953      $timeout(function () {
5954        $rootScope.$broadcast('$cordovaNetwork:offline', networkState);
5955      });
5956    };
5957
5958    /**
5959      * Fires online a event
5960      */
5961    var onlineEvent = function () {
5962      var networkState = navigator.connection.type;
5963      $timeout(function () {
5964        $rootScope.$broadcast('$cordovaNetwork:online', networkState);
5965      });
5966    };
5967
5968    document.addEventListener('deviceready', function () {
5969      if (navigator.connection) {
5970        document.addEventListener('offline', offlineEvent, false);
5971        document.addEventListener('online', onlineEvent, false);
5972      }
5973    });
5974
5975    return {
5976      getNetwork: function () {
5977        return navigator.connection.type;
5978      },
5979
5980      isOnline: function () {
5981        var networkState = navigator.connection.type;
5982        return networkState !== Connection.UNKNOWN && networkState !== Connection.NONE;
5983      },
5984
5985      isOffline: function () {
5986        var networkState = navigator.connection.type;
5987        return networkState === Connection.UNKNOWN || networkState === Connection.NONE;
5988      },
5989
5990      clearOfflineWatch: function () {
5991        document.removeEventListener('offline', offlineEvent);
5992        $rootScope.$$listeners['$cordovaNetwork:offline'] = [];
5993      },
5994
5995      clearOnlineWatch: function () {
5996        document.removeEventListener('online', onlineEvent);
5997        $rootScope.$$listeners['$cordovaNetwork:online'] = [];
5998      }
5999    };
6000  }])
6001  .run(['$injector', function ($injector) {
6002    $injector.get('$cordovaNetwork'); //ensure the factory always gets initialised
6003  }]);
6004
6005// install   :      cordova plugin add https://github.com/Paldom/PinDialog.git
6006// link      :      https://github.com/Paldom/PinDialog
6007
6008angular.module('ngCordova.plugins.pinDialog', [])
6009
6010  .factory('$cordovaPinDialog', ['$q', '$window', function ($q, $window) {
6011
6012    return {
6013      prompt: function (message, title, buttons) {
6014        var q = $q.defer();
6015
6016        $window.plugins.pinDialog.prompt(message, function (res) {
6017          q.resolve(res);
6018        }, title, buttons);
6019
6020        return q.promise;
6021      }
6022    };
6023  }]);
6024
6025// install   :      cordova plugin add cordova-plugin-app-preferences
6026// link      :      https://github.com/apla/me.apla.cordova.app-preferences
6027
6028angular.module('ngCordova.plugins.preferences', [])
6029
6030  .factory('$cordovaPreferences', ['$window', '$q', function ($window, $q) {
6031
6032     return {
6033         
6034         pluginNotEnabledMessage: 'Plugin not enabled',
6035    	
6036    	/**
6037    	 * Decorate the promise object.
6038    	 * @param promise The promise object.
6039    	 */
6040    	decoratePromise: function (promise){
6041    		promise.success = function (fn) {
6042	            promise.then(fn);
6043	            return promise;
6044	        };
6045
6046	        promise.error = function (fn) {
6047	            promise.then(null, fn);
6048	            return promise;
6049	        };
6050    	},
6051    	
6052    	/**
6053    	 * Store the value of the given dictionary and key.
6054    	 * @param key The key of the preference.
6055    	 * @param value The value to set.
6056         * @param dict The dictionary. It's optional.
6057         * @returns Returns a promise.
6058    	 */
6059	    store: function (key, value, dict) {
6060	    	var deferred = $q.defer();
6061	    	var promise = deferred.promise;
6062            
6063            function ok(value){
6064                deferred.resolve(value);
6065            }
6066            
6067            function errorCallback(error){
6068                deferred.reject(new Error(error));
6069            }
6070            
6071            if($window.plugins){
6072                var storeResult;
6073                if(arguments.length === 3){
6074                    storeResult = $window.plugins.appPreferences.store(dict, key, value);
6075                } else {
6076                    storeResult = $window.plugins.appPreferences.store(key, value);
6077                }
6078                
6079                storeResult.then(ok, errorCallback);
6080            } else {
6081                deferred.reject(new Error(this.pluginNotEnabledMessage));
6082            }
6083            
6084	    	this.decoratePromise(promise);
6085	    	return promise;
6086	    },
6087	    
6088	    /**
6089	     * Fetch the value by the given dictionary and key.
6090	     * @param key The key of the preference to retrieve.
6091         * @param dict The dictionary. It's optional.
6092         * @returns Returns a promise.
6093	     */
6094	    fetch: function (key, dict) {
6095	    	var deferred = $q.defer();
6096	    	var promise = deferred.promise;
6097            
6098            function ok(value){
6099                deferred.resolve(value);
6100            }
6101            
6102            function errorCallback(error){
6103                deferred.reject(new Error(error));
6104            }
6105            
6106            if($window.plugins){
6107                var fetchResult;
6108                if(arguments.length === 2){
6109                    fetchResult = $window.plugins.appPreferences.fetch(dict, key);
6110                } else {
6111                    fetchResult = $window.plugins.appPreferences.fetch(key);
6112                }
6113                fetchResult.then(ok, errorCallback);
6114            } else {
6115                deferred.reject(new Error(this.pluginNotEnabledMessage));
6116            }
6117            
6118	    	this.decoratePromise(promise);
6119	    	return promise;
6120	    },
6121        
6122        /**
6123	     * Remove the value by the given key.
6124	     * @param key The key of the preference to retrieve.
6125         * @param dict The dictionary. It's optional.
6126         * @returns Returns a promise.
6127	     */
6128	    remove: function (key, dict) {
6129	    	var deferred = $q.defer();
6130	    	var promise = deferred.promise;
6131            
6132            function ok(value){
6133                deferred.resolve(value);
6134            }
6135            
6136            function errorCallback(error){
6137                deferred.reject(new Error(error));
6138            }
6139            
6140            if($window.plugins){
6141                var removeResult;
6142                if(arguments.length === 2){
6143                    removeResult = $window.plugins.appPreferences.remove(dict, key);
6144                } else {
6145                    removeResult = $window.plugins.appPreferences.remove(key);
6146                }
6147                removeResult.then(ok, errorCallback);
6148            } else {
6149                deferred.reject(new Error(this.pluginNotEnabledMessage));
6150            }
6151	    	
6152	    	this.decoratePromise(promise);
6153	    	return promise;
6154	    },
6155        
6156        /**
6157	     * Show the application preferences.
6158         * @returns Returns a promise.
6159	     */
6160	    show: function () {
6161	    	var deferred = $q.defer();
6162	    	var promise = deferred.promise;
6163            
6164            function ok(value){
6165                deferred.resolve(value);
6166            }
6167            
6168            function errorCallback(error){
6169                deferred.reject(new Error(error));
6170            }
6171            
6172            if($window.plugins){
6173                $window.plugins.appPreferences.show()
6174                    .then(ok, errorCallback);
6175            } else {
6176                deferred.reject(new Error(this.pluginNotEnabledMessage));
6177            }
6178	    	
6179	    	this.decoratePromise(promise);
6180	    	return promise;
6181	    }
6182    };
6183
6184  }]);
6185
6186// install   : cordova plugin add https://github.com/katzer/cordova-plugin-printer.git
6187// link      : https://github.com/katzer/cordova-plugin-printer
6188
6189angular.module('ngCordova.plugins.printer', [])
6190
6191  .factory('$cordovaPrinter', ['$q', '$window', function ($q, $window) {
6192
6193    return {
6194      isAvailable: function () {
6195        var q = $q.defer();
6196
6197        $window.plugin.printer.isAvailable(function (isAvailable) {
6198          q.resolve(isAvailable);
6199        });
6200
6201        return q.promise;
6202      },
6203
6204      print: function (doc, options) {
6205        var q = $q.defer();
6206        $window.plugin.printer.print(doc, options, function () {
6207          q.resolve();
6208        });
6209        return q.promise;
6210      }
6211    };
6212  }]);
6213
6214// install   :      cordova plugin add https://github.com/pbernasconi/cordova-progressIndicator.git
6215// link      :      http://pbernasconi.github.io/cordova-progressIndicator/
6216
6217/* globals ProgressIndicator: true */
6218angular.module('ngCordova.plugins.progressIndicator', [])
6219
6220  .factory('$cordovaProgress', [function () {
6221
6222    return {
6223      show: function (_message) {
6224        var message = _message || 'Please wait...';
6225        return ProgressIndicator.show(message);
6226      },
6227
6228      showSimple: function (_dim) {
6229        var dim = _dim || false;
6230        return ProgressIndicator.showSimple(dim);
6231      },
6232
6233      showSimpleWithLabel: function (_dim, _label) {
6234        var dim = _dim || false;
6235        var label = _label || 'Loading...';
6236        return ProgressIndicator.showSimpleWithLabel(dim, label);
6237      },
6238
6239      showSimpleWithLabelDetail: function (_dim, _label, _detail) {
6240        var dim = _dim || false;
6241        var label = _label || 'Loading...';
6242        var detail = _detail || 'Please wait';
6243        return ProgressIndicator.showSimpleWithLabelDetail(dim, label, detail);
6244      },
6245
6246      showDeterminate: function (_dim, _timeout) {
6247        var dim = _dim || false;
6248        var timeout = _timeout || 50000;
6249        return ProgressIndicator.showDeterminate(dim, timeout);
6250      },
6251
6252      showDeterminateWithLabel: function (_dim, _timeout, _label) {
6253        var dim = _dim || false;
6254        var timeout = _timeout || 50000;
6255        var label = _label || 'Loading...';
6256
6257        return ProgressIndicator.showDeterminateWithLabel(dim, timeout, label);
6258      },
6259
6260      showAnnular: function (_dim, _timeout) {
6261        var dim = _dim || false;
6262        var timeout = _timeout || 50000;
6263        return ProgressIndicator.showAnnular(dim, timeout);
6264      },
6265
6266      showAnnularWithLabel: function (_dim, _timeout, _label) {
6267        var dim = _dim || false;
6268        var timeout = _timeout || 50000;
6269        var label = _label || 'Loading...';
6270        return ProgressIndicator.showAnnularWithLabel(dim, timeout, label);
6271      },
6272
6273      showBar: function (_dim, _timeout) {
6274        var dim = _dim || false;
6275        var timeout = _timeout || 50000;
6276        return ProgressIndicator.showBar(dim, timeout);
6277      },
6278
6279      showBarWithLabel: function (_dim, _timeout, _label) {
6280        var dim = _dim || false;
6281        var timeout = _timeout || 50000;
6282        var label = _label || 'Loading...';
6283        return ProgressIndicator.showBarWithLabel(dim, timeout, label);
6284      },
6285
6286      showSuccess: function (_dim, _label) {
6287        var dim = _dim || false;
6288        var label = _label || 'Success';
6289        return ProgressIndicator.showSuccess(dim, label);
6290      },
6291
6292      showText: function (_dim, _text, _position) {
6293        var dim = _dim || false;
6294        var text = _text || 'Warning';
6295        var position = _position || 'center';
6296        return ProgressIndicator.showText(dim, text, position);
6297      },
6298
6299      hide: function () {
6300        return ProgressIndicator.hide();
6301      }
6302    };
6303
6304  }]);
6305
6306// install   :      cordova plugin add https://github.com/phonegap-build/PushPlugin.git
6307// link      :      https://github.com/phonegap-build/PushPlugin
6308
6309angular.module('ngCordova.plugins.push', [])
6310
6311  .factory('$cordovaPush', ['$q', '$window', '$rootScope', '$timeout', function ($q, $window, $rootScope, $timeout) {
6312
6313    return {
6314      onNotification: function (notification) {
6315        $timeout(function () {
6316          $rootScope.$broadcast('$cordovaPush:notificationReceived', notification);
6317        });
6318      },
6319
6320      register: function (config) {
6321        var q = $q.defer();
6322        var injector;
6323        if (config !== undefined && config.ecb === undefined) {
6324          if (document.querySelector('[ng-app]') === null) {
6325            injector = 'document.body';
6326          }
6327          else {
6328            injector = 'document.querySelector(\'[ng-app]\')';
6329          }
6330          config.ecb = 'angular.element(' + injector + ').injector().get(\'$cordovaPush\').onNotification';
6331        }
6332
6333        $window.plugins.pushNotification.register(function (token) {
6334          q.resolve(token);
6335        }, function (error) {
6336          q.reject(error);
6337        }, config);
6338
6339        return q.promise;
6340      },
6341
6342      unregister: function (options) {
6343        var q = $q.defer();
6344        $window.plugins.pushNotification.unregister(function (result) {
6345          q.resolve(result);
6346        }, function (error) {
6347          q.reject(error);
6348        }, options);
6349
6350        return q.promise;
6351      },
6352
6353      // iOS only
6354      setBadgeNumber: function (number) {
6355        var q = $q.defer();
6356        $window.plugins.pushNotification.setApplicationIconBadgeNumber(function (result) {
6357          q.resolve(result);
6358        }, function (error) {
6359          q.reject(error);
6360        }, number);
6361        return q.promise;
6362      }
6363    };
6364  }]);
6365
6366
6367// install   :      cordova plugin add phonegap-plugin-push
6368// link      :      https://github.com/phonegap/phonegap-plugin-push
6369
6370angular.module('ngCordova.plugins.push_v5', [])
6371  .factory('$cordovaPushV5',['$q', '$rootScope', '$timeout', function ($q, $rootScope, $timeout) {
6372   /*global PushNotification*/
6373
6374    var push;
6375    return {
6376      initialize : function (options) {
6377        var q = $q.defer();
6378        push = PushNotification.init(options);
6379        q.resolve(push);
6380        return q.promise;
6381      },
6382      onNotification : function () {
6383        $timeout(function () {
6384          push.on('notification', function (notification) {
6385            $rootScope.$emit('$cordovaPushV5:notificationReceived', notification);
6386          });
6387        });
6388      },
6389      onError : function () {
6390        $timeout(function () {
6391          push.on('error', function (error) { $rootScope.$emit('$cordovaPushV5:errorOccurred', error);});
6392        });
6393      },
6394      register : function () {
6395        var q = $q.defer();
6396        if (push === undefined) {
6397          q.reject(new Error('init must be called before any other operation'));
6398        } else {
6399          push.on('registration', function (data) {
6400            q.resolve(data.registrationId);
6401          });
6402        }
6403        return q.promise;
6404      },
6405      unregister : function () {
6406        var q = $q.defer();
6407        if (push === undefined) {
6408          q.reject(new Error('init must be called before any other operation'));
6409        } else {
6410          push.unregister(function (success) {
6411            q.resolve(success);
6412          },function (error) {
6413            q.reject(error);
6414          });
6415        }
6416        return q.promise;
6417      },
6418      getBadgeNumber : function () {
6419        var q = $q.defer();
6420        if (push === undefined) {
6421          q.reject(new Error('init must be called before any other operation'));
6422        } else {
6423          push.getApplicationIconBadgeNumber(function (success) {
6424            q.resolve(success);
6425          }, function (error) {
6426            q.reject(error);
6427          });
6428        }
6429        return q.promise;
6430      },
6431      setBadgeNumber : function (number) {
6432        var q = $q.defer();
6433        if (push === undefined) {
6434          q.reject(new Error('init must be called before any other operation'));
6435        } else {
6436          push.setApplicationIconBadgeNumber(function (success) {
6437            q.resolve(success);
6438          }, function (error) {
6439            q.reject(error);
6440          }, number);
6441        }
6442        return q.promise;
6443      },
6444      finish: function (){
6445        var q = $q.defer();
6446        if (push === undefined) {
6447          q.reject(new Error('init must be called before any other operation'));
6448        } else {
6449          push.finish(function (success) {
6450            q.resolve(success);
6451          }, function (error) {
6452            q.reject(error);
6453          });
6454        }
6455        return q.promise;
6456      }
6457    };
6458  }]);
6459
6460// install   :      cordova plugin add cordova-plugin-recentscontrol
6461// link      :      https://github.com/smcpjames/cordova-plugin-recentscontrol
6462
6463/* globals RecentsControl: true */
6464angular.module('ngCordova.plugins.recentsControl', [])
6465
6466.factory('$cordovaRecents', function () {
6467    return {
6468        setColor: function (color) {
6469            return RecentsControl.setColor(color);
6470        },
6471
6472        setDescription: function (desc) {
6473            return RecentsControl.setDescription(desc);
6474        },
6475
6476        setOptions: function (colorStr, desc) {
6477            return RecentsControl.setOptions(colorStr, desc);
6478        }
6479    };
6480});
6481// install   :     cordova plugin add https://github.com/gitawego/cordova-screenshot.git
6482// link      :     https://github.com/gitawego/cordova-screenshot
6483
6484angular.module('ngCordova.plugins.screenshot', [])
6485.factory('$cordovaScreenshot', ['$q', function ($q) {
6486  return {
6487    captureToFile: function (opts) {
6488
6489      var options = opts || {};
6490
6491      var extension = options.extension || 'jpg';
6492      var quality = options.quality || '100';
6493
6494      var defer = $q.defer();
6495
6496      if (!navigator.screenshot) {
6497        defer.resolve(null);
6498        return defer.promise;
6499      }
6500
6501      navigator.screenshot.save(function (error, res) {
6502        if (error) {
6503          defer.reject(error);
6504        } else {
6505          defer.resolve(res.filePath);
6506        }
6507      }, extension, quality, options.filename);
6508
6509      return defer.promise;
6510    },
6511    captureToUri: function (opts) {
6512
6513      var options = opts || {};
6514
6515      var extension = options.extension || 'jpg';
6516      var quality = options.quality || '100';
6517
6518      var defer = $q.defer();
6519
6520      if (!navigator.screenshot) {
6521        defer.resolve(null);
6522        return defer.promise;
6523      }
6524
6525      navigator.screenshot.URI(function (error, res) {
6526        if (error) {
6527          defer.reject(error);
6528        } else {
6529          defer.resolve(res.URI);
6530        }
6531      }, extension, quality, options.filename);
6532
6533      return defer.promise;
6534    }
6535  };
6536}]);
6537// install   :  cordova plugin add https://github.com/xseignard/cordovarduino.git
6538// link      :  https://github.com/xseignard/cordovarduino
6539
6540/* globals serial: true */
6541angular.module('ngCordova.plugins.serial', [])
6542
6543  .factory('$cordovaSerial', ['$q', function ($q) {
6544
6545    var serialService = {};
6546
6547    serialService.requestPermission = function requestPermission(options) {
6548      var q = $q.defer();
6549
6550      serial.requestPermission(options, function success() {
6551        q.resolve();
6552      }, function error(err) {
6553        q.reject(err);
6554      });
6555
6556      return q.promise;
6557    };
6558
6559    serialService.open = function(options) {
6560      var q = $q.defer();
6561
6562      serial.open(options, function success() {
6563        q.resolve();
6564      }, function error(err) {
6565        q.reject(err);
6566      });
6567
6568      return q.promise;
6569    };
6570
6571    serialService.write = function(data) {
6572      var q = $q.defer();
6573
6574      serial.write(data, function success() {
6575        q.resolve();
6576      }, function error(err) {
6577        q.reject(err);
6578      });
6579
6580      return q.promise;
6581    };
6582
6583    serialService.writeHex = function(data) {
6584      var q = $q.defer();
6585
6586      serial.writeHex(data, function success() {
6587        q.resolve();
6588      }, function error(err) {
6589        q.reject(err);
6590      });
6591
6592      return q.promise;
6593    };
6594
6595    serialService.read = function() {
6596      var q = $q.defer();
6597
6598      serial.read(function success(buffer) {
6599        var view = new Uint8Array(buffer);
6600        q.resolve(view);
6601      }, function error(err) {
6602        q.reject(err);
6603      });
6604
6605      return q.promise;
6606    };
6607
6608    serialService.registerReadCallback = function(successCallback, errorCallback) {
6609      serial.registerReadCallback(function success(buffer) {
6610        var view = new Uint8Array(buffer);
6611        successCallback(view);
6612      }, errorCallback);
6613    };
6614
6615    serialService.close = function() {
6616      var q = $q.defer();
6617
6618      serial.close(function success() {
6619        q.resolve();
6620      }, function error(err) {
6621        q.reject(err);
6622      });
6623
6624      return q.promise;
6625    };
6626
6627    return serialService;
6628  }]);
6629
6630// install   :      cordova plugin add https://github.com/cordova-sms/cordova-sms-plugin.git
6631// link      :      https://github.com/cordova-sms/cordova-sms-plugin
6632
6633/* globals sms: true */
6634angular.module('ngCordova.plugins.sms', [])
6635
6636  .factory('$cordovaSms', ['$q', function ($q) {
6637
6638    return {
6639      send: function (number, message, options) {
6640        var q = $q.defer();
6641        sms.send(number, message, options, function (res) {
6642          q.resolve(res);
6643        }, function (err) {
6644          q.reject(err);
6645        });
6646        return q.promise;
6647      }
6648    };
6649
6650  }]);
6651
6652// install   :      cordova plugin add https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git
6653// link      :      https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin
6654
6655// NOTE: shareViaEmail -> if user cancels sharing email, success is still called
6656// TODO: add support for iPad
6657
6658angular.module('ngCordova.plugins.socialSharing', [])
6659
6660  .factory('$cordovaSocialSharing', ['$q', '$window', function ($q, $window) {
6661
6662    return {
6663      share: function (message, subject, file, link) {
6664        var q = $q.defer();
6665        subject = subject || null;
6666        file = file || null;
6667        link = link || null;
6668        $window.plugins.socialsharing.share(message, subject, file, link, function () {
6669          q.resolve(true);
6670        }, function () {
6671          q.reject(false);
6672        });
6673        return q.promise;
6674      },
6675
6676      shareWithOptions: function (options) {
6677        var q = $q.defer();
6678        $window.plugins.socialsharing.shareWithOptions(options, function () {
6679          q.resolve(true);
6680        }, function () {
6681          q.reject(false);
6682        });
6683        return q.promise;
6684      },
6685
6686      shareViaTwitter: function (message, file, link) {
6687        var q = $q.defer();
6688        file = file || null;
6689        link = link || null;
6690        $window.plugins.socialsharing.shareViaTwitter(message, file, link, function () {
6691          q.resolve(true);
6692        }, function () {
6693          q.reject(false);
6694        });
6695        return q.promise;
6696      },
6697
6698      shareViaWhatsApp: function (message, file, link) {
6699        var q = $q.defer();
6700        file = file || null;
6701        link = link || null;
6702        $window.plugins.socialsharing.shareViaWhatsApp(message, file, link, function () {
6703          q.resolve(true);
6704        }, function () {
6705          q.reject(false);
6706        });
6707        return q.promise;
6708      },
6709
6710      shareViaFacebook: function (message, file, link) {
6711        var q = $q.defer();
6712        message = message || null;
6713        file = file || null;
6714        link = link || null;
6715        $window.plugins.socialsharing.shareViaFacebook(message, file, link, function () {
6716          q.resolve(true);
6717        }, function () {
6718          q.reject(false);
6719        });
6720        return q.promise;
6721      },
6722
6723      shareViaFacebookWithPasteMessageHint: function (message, file, link, pasteMessageHint) {
6724        var q = $q.defer();
6725        file = file || null;
6726        link = link || null;
6727        $window.plugins.socialsharing.shareViaFacebookWithPasteMessageHint(message, file, link, pasteMessageHint, function () {
6728          q.resolve(true);
6729        }, function () {
6730          q.reject(false);
6731        });
6732        return q.promise;
6733      },
6734
6735      shareViaSMS: function (message, commaSeparatedPhoneNumbers) {
6736        var q = $q.defer();
6737        $window.plugins.socialsharing.shareViaSMS(message, commaSeparatedPhoneNumbers, function () {
6738          q.resolve(true);
6739        }, function () {
6740          q.reject(false);
6741        });
6742        return q.promise;
6743      },
6744
6745      shareViaEmail: function (message, subject, toArr, ccArr, bccArr, fileArr) {
6746        var q = $q.defer();
6747        toArr = toArr || null;
6748        ccArr = ccArr || null;
6749        bccArr = bccArr || null;
6750        fileArr = fileArr || null;
6751        $window.plugins.socialsharing.shareViaEmail(message, subject, toArr, ccArr, bccArr, fileArr, function () {
6752          q.resolve(true);
6753        }, function () {
6754          q.reject(false);
6755        });
6756        return q.promise;
6757      },
6758
6759      shareVia: function (via, message, subject, file, link) {
6760        var q = $q.defer();
6761        message = message || null;
6762        subject = subject || null;
6763        file = file || null;
6764        link = link || null;
6765        $window.plugins.socialsharing.shareVia(via, message, subject, file, link, function () {
6766          q.resolve(true);
6767        }, function () {
6768          q.reject(false);
6769        });
6770        return q.promise;
6771      },
6772
6773      canShareViaEmail: function () {
6774        var q = $q.defer();
6775        $window.plugins.socialsharing.canShareViaEmail(function () {
6776          q.resolve(true);
6777        }, function () {
6778          q.reject(false);
6779        });
6780        return q.promise;
6781      },
6782
6783      canShareVia: function (via, message, subject, file, link) {
6784        var q = $q.defer();
6785        $window.plugins.socialsharing.canShareVia(via, message, subject, file, link, function (success) {
6786          q.resolve(success);
6787        }, function (error) {
6788          q.reject(error);
6789        });
6790        return q.promise;
6791      },
6792
6793      available: function () {
6794        var q = $q.defer();
6795        window.plugins.socialsharing.available(function (isAvailable) {
6796          if (isAvailable) {
6797            q.resolve();
6798          }
6799          else {
6800            q.reject();
6801          }
6802        });
6803
6804        return q.promise;
6805      }
6806    };
6807  }]);
6808
6809// install   :       cordova plugin add https://github.com/Paldom/SpinnerDialog.git
6810// link      :       https://github.com/Paldom/SpinnerDialog
6811
6812angular.module('ngCordova.plugins.spinnerDialog', [])
6813
6814  .factory('$cordovaSpinnerDialog', ['$window', function ($window) {
6815
6816    return {
6817      show: function (title, message, fixed, iosOptions) {
6818        fixed = fixed || false;
6819        return $window.plugins.spinnerDialog.show(title, message, fixed, iosOptions);
6820      },
6821      hide: function () {
6822        return $window.plugins.spinnerDialog.hide();
6823      }
6824    };
6825
6826  }]);
6827
6828// install   :      cordova plugin add cordova-plugin-splashscreen
6829// link      :      https://github.com/apache/cordova-plugin-splashscreen
6830
6831angular.module('ngCordova.plugins.splashscreen', [])
6832
6833  .factory('$cordovaSplashscreen', [function () {
6834
6835    return {
6836      hide: function () {
6837        return navigator.splashscreen.hide();
6838      },
6839
6840      show: function () {
6841        return navigator.splashscreen.show();
6842      }
6843    };
6844
6845  }]);
6846
6847// install   :      cordova plugin add https://github.com/litehelpers/Cordova-sqlite-storage.git
6848// link      :      https://github.com/litehelpers/Cordova-sqlite-storage
6849
6850angular.module('ngCordova.plugins.sqlite', [])
6851
6852  .factory('$cordovaSQLite', ['$q', '$window', function ($q, $window) {
6853
6854    return {
6855      openDB: function (options, background) {
6856
6857        if (angular.isObject(options) && !angular.isString(options)) {
6858          if (typeof background !== 'undefined') {
6859            options.bgType = background;
6860          }
6861          return $window.sqlitePlugin.openDatabase(options);
6862        }
6863
6864        return $window.sqlitePlugin.openDatabase({
6865          name: options,
6866          bgType: background
6867        });
6868      },
6869
6870      execute: function (db, query, binding) {
6871        var q = $q.defer();
6872        db.transaction(function (tx) {
6873          tx.executeSql(query, binding, function (tx, result) {
6874              q.resolve(result);
6875            },
6876            function (transaction, error) {
6877              q.reject(error);
6878            });
6879        });
6880        return q.promise;
6881      },
6882
6883      insertCollection: function (db, query, bindings) {
6884        var q = $q.defer();
6885        var coll = bindings.slice(0); // clone collection
6886
6887        db.transaction(function (tx) {
6888          (function insertOne() {
6889            var record = coll.splice(0, 1)[0]; // get the first record of coll and reduce coll by one
6890            try {
6891              tx.executeSql(query, record, function (tx, result) {
6892                if (coll.length === 0) {
6893                  q.resolve(result);
6894                } else {
6895                  insertOne();
6896                }
6897              }, function (transaction, error) {
6898                q.reject(error);
6899                return;
6900              });
6901            } catch (exception) {
6902              q.reject(exception);
6903            }
6904          })();
6905        });
6906        return q.promise;
6907      },
6908
6909      nestedExecute: function (db, query1, query2, binding1, binding2) {
6910        var q = $q.defer();
6911
6912        db.transaction(function (tx) {
6913            tx.executeSql(query1, binding1, function (tx, result) {
6914              q.resolve(result);
6915              tx.executeSql(query2, binding2, function (tx, res) {
6916                q.resolve(res);
6917              });
6918            });
6919          },
6920          function (transaction, error) {
6921            q.reject(error);
6922          });
6923
6924        return q.promise;
6925      },
6926
6927      deleteDB: function (dbName) {
6928        var q = $q.defer();
6929
6930        $window.sqlitePlugin.deleteDatabase(dbName, function (success) {
6931          q.resolve(success);
6932        }, function (error) {
6933          q.reject(error);
6934        });
6935
6936        return q.promise;
6937      }
6938    };
6939  }]);
6940
6941// install   :      cordova plugin add cordova-plugin-statusbar
6942// link      :      https://github.com/apache/cordova-plugin-statusbar
6943
6944/* globals StatusBar: true */
6945angular.module('ngCordova.plugins.statusbar', [])
6946
6947.factory('$cordovaStatusbar', [function () {
6948
6949  return {
6950
6951    /**
6952      * @param {boolean} bool
6953      */
6954    overlaysWebView: function (bool) {
6955      return StatusBar.overlaysWebView(!!bool);
6956    },
6957
6958    STYLES: {
6959      DEFAULT: 0,
6960      LIGHT_CONTENT: 1,
6961      BLACK_TRANSLUCENT: 2,
6962      BLACK_OPAQUE: 3
6963    },
6964
6965    /**
6966      * @param {number} style
6967      */
6968    style: function (style) {
6969      switch (style) {
6970        // Default
6971        case 0:
6972        return StatusBar.styleDefault();
6973
6974        // LightContent
6975        case 1:
6976        return StatusBar.styleLightContent();
6977
6978        // BlackTranslucent
6979        case 2:
6980        return StatusBar.styleBlackTranslucent();
6981
6982        // BlackOpaque
6983        case 3:
6984        return StatusBar.styleBlackOpaque();
6985
6986        default:
6987        return StatusBar.styleDefault();
6988      }
6989    },
6990
6991    // supported names:
6992    // black, darkGray, lightGray, white, gray, red, green,
6993    // blue, cyan, yellow, magenta, orange, purple, brown
6994    styleColor: function (color) {
6995      return StatusBar.backgroundColorByName(color);
6996    },
6997
6998    styleHex: function (colorHex) {
6999      return StatusBar.backgroundColorByHexString(colorHex);
7000    },
7001
7002    hide: function () {
7003      return StatusBar.hide();
7004    },
7005
7006    show: function () {
7007      return StatusBar.show();
7008    },
7009
7010    isVisible: function () {
7011      return StatusBar.isVisible;
7012    }
7013  };
7014}]);
7015
7016// install   :      cordova plugin add https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin.git
7017// link      :      https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin
7018
7019angular.module('ngCordova.plugins.toast', [])
7020
7021  .factory('$cordovaToast', ['$q', '$window', function ($q, $window) {
7022
7023    return {
7024      showShortTop: function (message) {
7025        var q = $q.defer();
7026        $window.plugins.toast.showShortTop(message, function (response) {
7027          q.resolve(response);
7028        }, function (error) {
7029          q.reject(error);
7030        });
7031        return q.promise;
7032      },
7033
7034      showShortCenter: function (message) {
7035        var q = $q.defer();
7036        $window.plugins.toast.showShortCenter(message, function (response) {
7037          q.resolve(response);
7038        }, function (error) {
7039          q.reject(error);
7040        });
7041        return q.promise;
7042      },
7043
7044      showShortBottom: function (message) {
7045        var q = $q.defer();
7046        $window.plugins.toast.showShortBottom(message, function (response) {
7047          q.resolve(response);
7048        }, function (error) {
7049          q.reject(error);
7050        });
7051        return q.promise;
7052      },
7053
7054      showLongTop: function (message) {
7055        var q = $q.defer();
7056        $window.plugins.toast.showLongTop(message, function (response) {
7057          q.resolve(response);
7058        }, function (error) {
7059          q.reject(error);
7060        });
7061        return q.promise;
7062      },
7063
7064      showLongCenter: function (message) {
7065        var q = $q.defer();
7066        $window.plugins.toast.showLongCenter(message, function (response) {
7067          q.resolve(response);
7068        }, function (error) {
7069          q.reject(error);
7070        });
7071        return q.promise;
7072      },
7073
7074      showLongBottom: function (message) {
7075        var q = $q.defer();
7076        $window.plugins.toast.showLongBottom(message, function (response) {
7077          q.resolve(response);
7078        }, function (error) {
7079          q.reject(error);
7080        });
7081        return q.promise;
7082      },
7083
7084      showWithOptions: function (options) {
7085        var q = $q.defer();
7086        $window.plugins.toast.showWithOptions(options, function (response) {
7087          q.resolve(response);
7088        }, function (error) {
7089          q.reject(error);
7090        });
7091        return q.promise;
7092      },
7093
7094      show: function (message, duration, position) {
7095        var q = $q.defer();
7096        $window.plugins.toast.show(message, duration, position, function (response) {
7097          q.resolve(response);
7098        }, function (error) {
7099          q.reject(error);
7100        });
7101        return q.promise;
7102      },
7103
7104      hide: function () {
7105        var q = $q.defer();
7106        try {
7107          $window.plugins.toast.hide();
7108          q.resolve();
7109        } catch (error) {
7110          q.reject(error && error.message);
7111        }
7112        return q.promise;
7113      }
7114    };
7115
7116  }]);
7117
7118// install   :      cordova plugin add https://github.com/leecrossley/cordova-plugin-touchid.git
7119// link      :      https://github.com/leecrossley/cordova-plugin-touchid
7120
7121/* globals touchid: true */
7122angular.module('ngCordova.plugins.touchid', [])
7123
7124  .factory('$cordovaTouchID', ['$q', function ($q) {
7125
7126    return {
7127      checkSupport: function () {
7128        var defer = $q.defer();
7129        if (!window.cordova) {
7130          defer.reject('Not supported without cordova.js');
7131        } else {
7132          touchid.checkSupport(function (value) {
7133            defer.resolve(value);
7134          }, function (err) {
7135            defer.reject(err);
7136          });
7137        }
7138
7139        return defer.promise;
7140      },
7141
7142      authenticate: function (authReasonText) {
7143        var defer = $q.defer();
7144        if (!window.cordova) {
7145          defer.reject('Not supported without cordova.js');
7146        } else {
7147          touchid.authenticate(function (value) {
7148            defer.resolve(value);
7149          }, function (err) {
7150            defer.reject(err);
7151          }, authReasonText);
7152        }
7153
7154        return defer.promise;
7155      }
7156    };
7157  }]);
7158
7159// install   :      cordova plugin add cordova-plugin-tts
7160// link      :      https://github.com/smcpjames/cordova-plugin-tts
7161
7162/* globals TTS: true */
7163angular.module('ngCordova.plugins.tts', [])
7164
7165.factory('$cordovaTTS', function () {
7166    return {
7167        speak: function (text, onfulfilled, onrejected) {
7168            return TTS.speak(text, onfulfilled, onrejected);
7169        }
7170    };
7171});
7172// install   :      cordova plugin add https://github.com/aerogear/aerogear-cordova-push.git
7173// link      :      https://github.com/aerogear/aerogear-cordova-push
7174
7175angular.module('ngCordova.plugins.upsPush', [])
7176
7177  .factory('$cordovaUpsPush', ['$q', '$window', '$rootScope', '$timeout', function ($q, $window, $rootScope, $timeout) {
7178    return {
7179      register: function (config) {
7180        var q = $q.defer();
7181
7182        $window.push.register(function (notification) {
7183          $timeout(function () {
7184            $rootScope.$broadcast('$cordovaUpsPush:notificationReceived', notification);
7185          });
7186        }, function () {
7187          q.resolve();
7188        }, function (error) {
7189          q.reject(error);
7190        }, config);
7191
7192        return q.promise;
7193      },
7194
7195      unregister: function (options) {
7196        var q = $q.defer();
7197        $window.push.unregister(function () {
7198          q.resolve();
7199        }, function (error) {
7200          q.reject(error);
7201        }, options);
7202
7203        return q.promise;
7204      },
7205
7206      // iOS only
7207      setBadgeNumber: function (number) {
7208        var q = $q.defer();
7209        $window.push.setApplicationIconBadgeNumber(function () {
7210          q.resolve();
7211        }, number);
7212        return q.promise;
7213      }
7214    };
7215  }]);
7216
7217// install   :      cordova plugin add cordova-plugin-vibration
7218// link      :      https://github.com/apache/cordova-plugin-vibration
7219
7220angular.module('ngCordova.plugins.vibration', [])
7221
7222  .factory('$cordovaVibration', [function () {
7223
7224    return {
7225      vibrate: function (times) {
7226        return navigator.notification.vibrate(times);
7227      },
7228      vibrateWithPattern: function (pattern, repeat) {
7229        return navigator.notification.vibrateWithPattern(pattern, repeat);
7230      },
7231      cancelVibration: function () {
7232        return navigator.notification.cancelVibration();
7233      }
7234    };
7235  }]);
7236
7237// install   :    cordova plugin add https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin.git
7238// link      :    https://github.com/EddyVerbruggen/VideoCapturePlus-PhoneGap-Plugin
7239
7240angular.module('ngCordova.plugins.videoCapturePlus', [])
7241
7242  .provider('$cordovaVideoCapturePlus', [function () {
7243
7244    var defaultOptions = {};
7245
7246
7247    /**
7248     * the nr of videos to record, default 1 (on iOS always 1)
7249     *
7250     * @param limit
7251     */
7252    this.setLimit = function setLimit(limit) {
7253      defaultOptions.limit = limit;
7254    };
7255
7256
7257    /**
7258     * max duration in seconds, default 0, which is 'forever'
7259     *
7260     * @param seconds
7261     */
7262    this.setMaxDuration = function setMaxDuration(seconds) {
7263      defaultOptions.duration = seconds;
7264    };
7265
7266
7267    /**
7268     * set to true to override the default low quality setting
7269     *
7270     * @param {Boolean} highquality
7271     */
7272    this.setHighQuality = function setHighQuality(highquality) {
7273      defaultOptions.highquality = highquality;
7274    };
7275
7276    /**
7277     * you'll want to sniff the user-Agent/device and pass the best overlay based on that..
7278     * set to true to override the default backfacing camera setting. iOS: works fine, Android: YMMV (#18)
7279     *
7280     * @param {Boolean} frontcamera
7281     */
7282    this.useFrontCamera = function useFrontCamera(frontcamera) {
7283      defaultOptions.frontcamera = frontcamera;
7284    };
7285
7286
7287    /**
7288     * put the png in your www folder
7289     *
7290     * @param {String} imageUrl
7291     */
7292    this.setPortraitOverlay = function setPortraitOverlay(imageUrl) {
7293      defaultOptions.portraitOverlay = imageUrl;
7294    };
7295
7296
7297    /**
7298     *
7299     * @param {String} imageUrl
7300     */
7301    this.setLandscapeOverlay = function setLandscapeOverlay(imageUrl) {
7302      defaultOptions.landscapeOverlay = imageUrl;
7303    };
7304
7305
7306    /**
7307     * iOS only
7308     *
7309     * @param text
7310     */
7311    this.setOverlayText = function setOverlayText(text) {
7312      defaultOptions.overlayText = text;
7313    };
7314
7315
7316    this.$get = ['$q', '$window', function ($q, $window) {
7317      return {
7318        captureVideo: function (options) {
7319          var q = $q.defer();
7320
7321          if (!$window.plugins.videocaptureplus) {
7322            q.resolve(null);
7323            return q.promise;
7324          }
7325
7326          $window.plugins.videocaptureplus.captureVideo(q.resolve, q.reject,
7327            angular.extend({}, defaultOptions, options));
7328
7329          return q.promise;
7330        }
7331      };
7332    }];
7333  }]);
7334
7335// install  :     cordova plugin add https://github.com/MobileChromeApps/zip.git
7336// link     :     https://github.com/MobileChromeApps/zip
7337
7338angular.module('ngCordova.plugins.zip', [])
7339
7340  .factory('$cordovaZip', ['$q', '$window', function ($q, $window) {
7341
7342    return {
7343      unzip: function (source, destination) {
7344        var q = $q.defer();
7345
7346        $window.zip.unzip(source, destination, function (isError) {
7347          if (isError === 0) {
7348            q.resolve();
7349          } else {
7350            q.reject();
7351          }
7352        }, function (progressEvent) {
7353          q.notify(progressEvent);
7354        });
7355
7356        return q.promise;
7357      }
7358    };
7359  }]);
7360
7361})();