Răsfoiți Sursa

add remote injection

xiongzhu 7 ani în urmă
părinte
comite
6209d14aa9
100 a modificat fișierele cu 5023 adăugiri și 89 ștergeri
  1. 12 6
      android.js
  2. 2 1
      config.xml
  3. 6 6
      package-lock.json
  4. 4 3
      package.json
  5. 15 1
      platforms/android/android.json
  6. 2 1
      platforms/android/assets/www/cordova_plugins.js
  7. 1 1
      platforms/android/assets/www/milk.html
  8. 0 0
      platforms/android/assets/www/static/css/app.7409e6a6ea43ab18efb967bd35f248fc.css
  9. 0 0
      platforms/android/assets/www/static/js/0.0473748a8dbcf364447f.js
  10. 0 0
      platforms/android/assets/www/static/js/0.e0e9326384e1b8113845.js
  11. 0 0
      platforms/android/assets/www/static/js/1.0657414e4256754bd077.js
  12. 0 0
      platforms/android/assets/www/static/js/1.92e16ee4f19dd9c20923.js
  13. 0 0
      platforms/android/assets/www/static/js/10.5f750dc57999946c3ba0.js
  14. 0 0
      platforms/android/assets/www/static/js/10.a1fa2d5c57ba34c1afc8.js
  15. 0 0
      platforms/android/assets/www/static/js/11.3b9bdf34eb18d22af090.js
  16. 0 0
      platforms/android/assets/www/static/js/11.c3f97213f3f1eca08a45.js
  17. 0 0
      platforms/android/assets/www/static/js/12.2c370262457040d6fb87.js
  18. 0 0
      platforms/android/assets/www/static/js/12.ea82cdb5e86a9d59314b.js
  19. 0 0
      platforms/android/assets/www/static/js/13.7423fd4dafa430862b39.js
  20. 0 0
      platforms/android/assets/www/static/js/13.884c96f622fdcd908304.js
  21. 0 0
      platforms/android/assets/www/static/js/14.11caa2ec8b35ee899318.js
  22. 0 0
      platforms/android/assets/www/static/js/14.1edcf4091ad60839bec7.js
  23. 0 0
      platforms/android/assets/www/static/js/15.1273661f26ddca8e8789.js
  24. 0 0
      platforms/android/assets/www/static/js/15.47a4f51f575b4b82f49d.js
  25. 0 0
      platforms/android/assets/www/static/js/16.5761cd86c8532510eeb6.js
  26. 0 0
      platforms/android/assets/www/static/js/16.b751445e966564cdaebe.js
  27. 0 0
      platforms/android/assets/www/static/js/17.9caec7aafc5f62b3b63d.js
  28. 0 0
      platforms/android/assets/www/static/js/17.ebb4b0b0dd306c995c6c.js
  29. 0 0
      platforms/android/assets/www/static/js/18.89e72677fc6a7e0a077b.js
  30. 0 0
      platforms/android/assets/www/static/js/18.e3aff34019cf87207433.js
  31. 0 0
      platforms/android/assets/www/static/js/19.2aa4910849cb3aff2d91.js
  32. 0 0
      platforms/android/assets/www/static/js/19.882f4ca7a8f245404e76.js
  33. 0 0
      platforms/android/assets/www/static/js/2.a58a581b946368e4fdd4.js
  34. 0 0
      platforms/android/assets/www/static/js/2.efd997c0cd3cfa25cecc.js
  35. 0 0
      platforms/android/assets/www/static/js/20.46af41c78ca8ad7433a3.js
  36. 0 0
      platforms/android/assets/www/static/js/20.543ec1973297b395ae4a.js
  37. 0 0
      platforms/android/assets/www/static/js/21.80dded26ae9df5f98ddb.js
  38. 0 0
      platforms/android/assets/www/static/js/21.ffe1cff8da466714acd1.js
  39. 0 0
      platforms/android/assets/www/static/js/22.5b809336c4c3767e5737.js
  40. 0 0
      platforms/android/assets/www/static/js/22.96f508e5a38d0e49d54a.js
  41. 0 0
      platforms/android/assets/www/static/js/23.adbd3f4af4a05bbec2cd.js
  42. 0 0
      platforms/android/assets/www/static/js/23.b6d449ff6de6e72cf20b.js
  43. 0 0
      platforms/android/assets/www/static/js/3.23eb6c06cc68424664c5.js
  44. 0 0
      platforms/android/assets/www/static/js/3.f3a8fa14c9216e801b08.js
  45. 0 0
      platforms/android/assets/www/static/js/4.119c68eee53bc87aaec0.js
  46. 0 0
      platforms/android/assets/www/static/js/4.1e49c835122c453a3245.js
  47. 0 0
      platforms/android/assets/www/static/js/5.32db8aa955c95d784ff0.js
  48. 0 0
      platforms/android/assets/www/static/js/5.b8df62c04c96819a29ed.js
  49. 0 0
      platforms/android/assets/www/static/js/6.5a60e1d2040b5a229acb.js
  50. 0 0
      platforms/android/assets/www/static/js/6.f018f649601b6cd8212d.js
  51. 0 0
      platforms/android/assets/www/static/js/7.27d85ae2c89c18af7032.js
  52. 0 0
      platforms/android/assets/www/static/js/7.f5cb93d6e9e4643f2b7b.js
  53. 0 0
      platforms/android/assets/www/static/js/8.633a0bc06ae6adcdec64.js
  54. 0 0
      platforms/android/assets/www/static/js/8.803d1c54542b89e4046c.js
  55. 0 0
      platforms/android/assets/www/static/js/9.1e83e1365dfc5107ef11.js
  56. 0 0
      platforms/android/assets/www/static/js/9.305e1052b9c04aa7b639.js
  57. 0 0
      platforms/android/assets/www/static/js/app.badc7333c080b61610fb.js
  58. 0 0
      platforms/android/assets/www/static/js/app.c7a55afb3489f2936469.js
  59. 0 0
      platforms/android/assets/www/static/js/manifest.9be0bd713a331d9eaca5.js
  60. 0 0
      platforms/android/assets/www/static/js/manifest.ad72cfdf70bd6f7519e0.js
  61. 0 0
      platforms/android/assets/www/static/js/vendor.10d164ea32522da5baa8.js
  62. 0 5
      platforms/android/assets/www/static/js/vendor.72df867588bc99b5cb66.js
  63. 2 1
      platforms/android/platform_www/cordova_plugins.js
  64. 0 6
      platforms/android/release-signing.properties
  65. 4 0
      platforms/android/res/xml/config.xml
  66. 320 0
      platforms/android/src/com/truckmovers/cordova/RemoteInjectionPlugin.java
  67. 0 19
      platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/xiongzhu.xcuserdatad/xcschemes/xcschememanagement.plist
  68. 1 1
      platforms/ios/frameworks.json
  69. 48 19
      platforms/ios/ios.json
  70. 20 19
      platforms/ios/platform_www/cordova_plugins.js
  71. 46 0
      platforms/ios/platform_www/plugins/cordova-plugin-handheld/www/Handheld.js
  72. 262 0
      platforms/ios/www/cordova-js-src/exec.js
  73. 31 0
      platforms/ios/www/cordova-js-src/platform.js
  74. 186 0
      platforms/ios/www/cordova-js-src/plugin/ios/console.js
  75. 354 0
      platforms/ios/www/cordova-js-src/plugin/ios/logger.js
  76. 2431 0
      platforms/ios/www/cordova.js
  77. 120 0
      platforms/ios/www/cordova_plugins.js
  78. 115 0
      platforms/ios/www/css/index.css
  79. BIN
      platforms/ios/www/img/logo.png
  80. 49 0
      platforms/ios/www/index.html
  81. 46 0
      platforms/ios/www/js/index.js
  82. 1 0
      platforms/ios/www/milk.html
  83. 188 0
      platforms/ios/www/plugins/cordova-plugin-camera/www/Camera.js
  84. 104 0
      platforms/ios/www/plugins/cordova-plugin-camera/www/CameraConstants.js
  85. 55 0
      platforms/ios/www/plugins/cordova-plugin-camera/www/CameraPopoverOptions.js
  86. 69 0
      platforms/ios/www/plugins/cordova-plugin-camera/www/ios/CameraPopoverHandle.js
  87. 46 0
      platforms/ios/www/plugins/cordova-plugin-handheld/www/Handheld.js
  88. 32 0
      platforms/ios/www/plugins/cordova-plugin-navigationbar/www/navigationbar.js
  89. 8 0
      platforms/ios/www/plugins/cordova-plugin-pgyer/www/pgyer.js
  90. 36 0
      platforms/ios/www/plugins/cordova-plugin-splashscreen/www/splashscreen.js
  91. 32 0
      platforms/ios/www/plugins/cordova-plugin-tencent-bg-location/www/tencentBgLocation.js
  92. 177 0
      platforms/ios/www/plugins/cordova-plugin-wkwebview-engine/src/www/ios/ios-wkwebview-exec.js
  93. 33 0
      platforms/ios/www/plugins/cordova-plugin-wkwebview-engine/src/www/ios/ios-wkwebview.js
  94. 64 0
      platforms/ios/www/plugins/cordova-plugin-x-toast/test/tests.js
  95. 101 0
      platforms/ios/www/plugins/cordova-plugin-x-toast/www/Toast.js
  96. BIN
      platforms/ios/www/static/img/bg_logo.cfcf94f.png
  97. BIN
      platforms/ios/www/static/img/fast-delivery111@3x.a0e2e8c.png
  98. BIN
      platforms/ios/www/static/img/fast-delivery1@3x.2d764a8.png
  99. BIN
      platforms/ios/www/static/img/fast-delivery5@3x.760324d.png
  100. BIN
      platforms/ios/www/static/img/fast-delivery6@3x.7e1f774.png

+ 12 - 6
android.js

@@ -1,5 +1,5 @@
-var spawn = require('child_process').spawn;
-
+const spawn = require('child_process').spawn;
+const path = require('path')
 function exec(cmd, args, options) {
     return new Promise((resolve, reject) => {
         var s = spawn(cmd, args, options)
@@ -20,12 +20,18 @@ const workDir = '/Users/xiongzhu/Projects/Java/GuangMing/WebSrc/Milk'
 const username = 'xz'
 const password = 'xz'
 
-exec('svn', ['update', '--username', username, '--password', password], { cwd: workDir }).then(() => {
-    return exec('npm', ['run', 'build', 'app'], { cwd: workDir })
+var update = process.argv.splice(2).indexOf('update') > -1
+var run = process.argv.splice(2).indexOf('run') > -1
+!function () {
+    if (update) return exec('svn', ['update', '--username', username, '--password', password], { cwd: path.resolve(workDir) })
+    else return new Promise((resolve, reject) => { resolve() })
+}().then(() => {
+    return exec('npm', ['run', 'build', path.resolve(__dirname)], { cwd: workDir })
+}).then(() => {
+    return exec('cordova', ['clean', 'android'], { cwd: path.resolve(__dirname) })
 }).then(() => {
-    return exec('cordova', ['clean', 'android'], { cwd: './' })
+    return exec('cordova', [run ? 'run' : 'build', 'android', '--release', '--', `--keystore=${path.resolve(__dirname), 'zouma.jks'}`, '--storePassword=zouma123', '--password=zouma123', '--alias=zouma'], { cwd: './' })
 }).then(() => {
-    return exec('cordova', ['build', 'android', '--release', '--', '--keystore="./zouma.jks"', '--storePassword=zouma123', '--password=zouma123', '--alias=zouma'], { cwd: './' })
 }).catch(e => {
     console.log(e)
 })

+ 2 - 1
config.xml

@@ -63,5 +63,6 @@
     <plugin name="cordova-plugin-navigationbar" spec="/Users/xiongzhu/Projects/Cordova/Milk/node_modules/cordova-plugin-navigationbar" />
     <plugin name="cordova-plugin-handheld" spec="../handheld" />
     <engine name="android" spec="^6.3.0" />
-    <engine name="ios" spec="^4.5.4" />
+    <plugin name="cordova-plugin-remote-injection" spec="^0.5.2" />
+    <engine name="ios" spec="~4.5.4" />
 </widget>

+ 6 - 6
package-lock.json

@@ -224,7 +224,7 @@
         },
         "cordova-ios": {
             "version": "4.5.4",
-            "resolved": "https://registry.npmjs.org/cordova-ios/-/cordova-ios-4.5.4.tgz",
+            "resolved": "http://registry.npm.taobao.org/cordova-ios/download/cordova-ios-4.5.4.tgz",
             "integrity": "sha1-yAZIBYlyloVw3BXalzFP+S0H3+c=",
             "requires": {
                 "cordova-common": "2.1.0",
@@ -544,6 +544,11 @@
         "cordova-plugin-pgyer": {
             "version": "file:../pgyer"
         },
+        "cordova-plugin-remote-injection": {
+            "version": "0.5.2",
+            "resolved": "http://registry.npm.taobao.org/cordova-plugin-remote-injection/download/cordova-plugin-remote-injection-0.5.2.tgz",
+            "integrity": "sha1-dUw6UubbLU2r93YRm2/vxPT25eg="
+        },
         "cordova-plugin-splashscreen": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/cordova-plugin-splashscreen/-/cordova-plugin-splashscreen-5.0.1.tgz",
@@ -567,11 +572,6 @@
             "resolved": "https://registry.npmjs.org/cordova-plugin-x-toast/-/cordova-plugin-x-toast-2.6.0.tgz",
             "integrity": "sha1-R3i+y2HjbIlRCRoHWFDCje2PVqU="
         },
-        "node-cmd": {
-            "version": "3.0.0",
-            "resolved": "http://registry.npm.taobao.org/node-cmd/download/node-cmd-3.0.0.tgz",
-            "integrity": "sha1-OP/3CkqqT2WdID61eGJzcBjiT28="
-        },
         "semver": {
             "version": "5.5.0",
             "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",

+ 4 - 3
package.json

@@ -16,12 +16,12 @@
         "cordova-plugin-handheld": "file:../handheld",
         "cordova-plugin-navigationbar": "file:../navigationbar",
         "cordova-plugin-pgyer": "file:../pgyer",
+        "cordova-plugin-remote-injection": "^0.5.2",
         "cordova-plugin-splashscreen": "^5.0.1",
         "cordova-plugin-tencent-bg-location": "file:../tencentBgLocation",
         "cordova-plugin-whitelist": "^1.3.3",
         "cordova-plugin-wkwebview-engine": "^1.1.4",
-        "cordova-plugin-x-toast": "^2.6.0",
-        "node-cmd": "^3.0.0"
+        "cordova-plugin-x-toast": "^2.6.0"
     },
     "cordova": {
         "plugins": {
@@ -37,7 +37,8 @@
                 "API_KEY": "PPQBZ-HCQLO-MMNWE-SHIDE-Y42BH-D3F76"
             },
             "cordova-plugin-navigationbar": {},
-            "cordova-plugin-handheld": {}
+            "cordova-plugin-handheld": {},
+            "cordova-plugin-remote-injection": {}
         },
         "platforms": [
             "android",

+ 15 - 1
platforms/android/android.json

@@ -140,6 +140,16 @@
             }
           ]
         }
+      },
+      "config.xml": {
+        "parents": {
+          "/*": [
+            {
+              "xml": "<feature name=\"RemoteInjection\"><param name=\"android-package\" value=\"com.truckmovers.cordova.RemoteInjectionPlugin\" /><param name=\"onload\" value=\"true\" /></feature>",
+              "count": 1
+            }
+          ]
+        }
       }
     }
   },
@@ -172,6 +182,9 @@
     },
     "cordova-plugin-handheld": {
       "PACKAGE_NAME": "com.izouma.milk"
+    },
+    "cordova-plugin-remote-injection": {
+      "PACKAGE_NAME": "com.izouma.milk"
     }
   },
   "dependent_plugins": {},
@@ -271,6 +284,7 @@
     "cordova-plugin-camera": "4.0.2",
     "cordova-plugin-tencent-bg-location": "1.0.0",
     "cordova-plugin-navigationbar": "1.0.0",
-    "cordova-plugin-handheld": "1.0.0"
+    "cordova-plugin-handheld": "1.0.0",
+    "cordova-plugin-remote-injection": "0.5.2"
   }
 }

+ 2 - 1
platforms/android/assets/www/cordova_plugins.js

@@ -97,7 +97,8 @@ module.exports.metadata =
   "cordova-plugin-camera": "4.0.2",
   "cordova-plugin-tencent-bg-location": "1.0.0",
   "cordova-plugin-navigationbar": "1.0.0",
-  "cordova-plugin-handheld": "1.0.0"
+  "cordova-plugin-handheld": "1.0.0",
+  "cordova-plugin-remote-injection": "0.5.2"
 };
 // BOTTOM OF METADATA
 });

+ 1 - 1
platforms/android/assets/www/milk.html

@@ -1 +1 @@
-<!DOCTYPE html><html><head><meta charset=utf-8><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><script src=http://res.wx.qq.com/open/js/jweixin-1.2.0.js></script><script type=text/javascript src=cordova.js></script><title>光明</title><link href=./static/css/app.7409e6a6ea43ab18efb967bd35f248fc.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.9be0bd713a331d9eaca5.js></script><script type=text/javascript src=./static/js/vendor.72df867588bc99b5cb66.js></script><script type=text/javascript src=./static/js/app.badc7333c080b61610fb.js></script></body></html>
+<!DOCTYPE html><html><head><meta charset=utf-8><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><script src=http://res.wx.qq.com/open/js/jweixin-1.2.0.js></script><script type=text/javascript src=cordova.js></script><title>光明</title></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.ad72cfdf70bd6f7519e0.js></script><script type=text/javascript src=/static/js/vendor.10d164ea32522da5baa8.js></script><script type=text/javascript src=/static/js/app.c7a55afb3489f2936469.js></script></body></html>

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/css/app.7409e6a6ea43ab18efb967bd35f248fc.css


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/0.0473748a8dbcf364447f.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/0.e0e9326384e1b8113845.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/1.0657414e4256754bd077.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/1.92e16ee4f19dd9c20923.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/10.5f750dc57999946c3ba0.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/10.a1fa2d5c57ba34c1afc8.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/11.3b9bdf34eb18d22af090.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/11.c3f97213f3f1eca08a45.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/12.2c370262457040d6fb87.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/12.ea82cdb5e86a9d59314b.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/13.7423fd4dafa430862b39.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/13.884c96f622fdcd908304.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/14.11caa2ec8b35ee899318.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/14.1edcf4091ad60839bec7.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/15.1273661f26ddca8e8789.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/15.47a4f51f575b4b82f49d.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/16.5761cd86c8532510eeb6.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/16.b751445e966564cdaebe.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/17.9caec7aafc5f62b3b63d.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/17.ebb4b0b0dd306c995c6c.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/18.89e72677fc6a7e0a077b.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/18.e3aff34019cf87207433.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/19.2aa4910849cb3aff2d91.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/19.882f4ca7a8f245404e76.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/2.a58a581b946368e4fdd4.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/2.efd997c0cd3cfa25cecc.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/20.46af41c78ca8ad7433a3.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/20.543ec1973297b395ae4a.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/21.80dded26ae9df5f98ddb.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/21.ffe1cff8da466714acd1.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/22.5b809336c4c3767e5737.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/22.96f508e5a38d0e49d54a.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/23.adbd3f4af4a05bbec2cd.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/23.b6d449ff6de6e72cf20b.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/3.23eb6c06cc68424664c5.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/3.f3a8fa14c9216e801b08.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/4.119c68eee53bc87aaec0.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/4.1e49c835122c453a3245.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/5.32db8aa955c95d784ff0.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/5.b8df62c04c96819a29ed.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/6.5a60e1d2040b5a229acb.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/6.f018f649601b6cd8212d.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/7.27d85ae2c89c18af7032.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/7.f5cb93d6e9e4643f2b7b.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/8.633a0bc06ae6adcdec64.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/8.803d1c54542b89e4046c.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/9.1e83e1365dfc5107ef11.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/9.305e1052b9c04aa7b639.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/app.badc7333c080b61610fb.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/app.c7a55afb3489f2936469.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/manifest.9be0bd713a331d9eaca5.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/manifest.ad72cfdf70bd6f7519e0.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
platforms/android/assets/www/static/js/vendor.10d164ea32522da5baa8.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 5
platforms/android/assets/www/static/js/vendor.72df867588bc99b5cb66.js


+ 2 - 1
platforms/android/platform_www/cordova_plugins.js

@@ -97,7 +97,8 @@ module.exports.metadata =
   "cordova-plugin-camera": "4.0.2",
   "cordova-plugin-tencent-bg-location": "1.0.0",
   "cordova-plugin-navigationbar": "1.0.0",
-  "cordova-plugin-handheld": "1.0.0"
+  "cordova-plugin-handheld": "1.0.0",
+  "cordova-plugin-remote-injection": "0.5.2"
 };
 // BOTTOM OF METADATA
 });

+ 0 - 6
platforms/android/release-signing.properties

@@ -1,6 +0,0 @@
-# This file is automatically generated.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-key.store=../../"./zouma.jks"
-key.alias=zouma
-key.store.password=zouma123
-key.alias.password=zouma123

+ 4 - 0
platforms/android/res/xml/config.xml

@@ -51,4 +51,8 @@
     <preference name="forceUpdate" value="true" />
     <preference name="ShowSplashScreenSpinner" value="false" />
     <preference name="SplashMaintainAspectRatio" value="true" />
+    <feature name="RemoteInjection">
+        <param name="android-package" value="com.truckmovers.cordova.RemoteInjectionPlugin" />
+        <param name="onload" value="true" />
+    </feature>
 </widget>

+ 320 - 0
platforms/android/src/com/truckmovers/cordova/RemoteInjectionPlugin.java

@@ -0,0 +1,320 @@
+package com.truckmovers.cordova;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.res.AssetManager;
+import android.util.Base64;
+
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.CordovaWebViewEngine;
+import org.apache.cordova.LOG;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.regex.Pattern;
+
+public class RemoteInjectionPlugin extends CordovaPlugin {
+    private static String TAG = "RemoteInjectionPlugin";
+    private static Pattern REMOTE_URL_REGEX = Pattern.compile("^http(s)?://.*");
+
+
+    // List of files to inject before injecting Cordova.
+    private final ArrayList<String> preInjectionFileNames = new ArrayList<String>();
+    private int promptInterval;  // Delay before prompting user to retry in seconds
+
+    private RequestLifecycle lifecycle;
+
+    protected void pluginInitialize() {
+        String pref = webView.getPreferences().getString("CRIInjectFirstFiles", "");
+        for (String path: pref.split(",")) {
+            preInjectionFileNames.add(path.trim());
+        }
+        promptInterval = webView.getPreferences().getInteger("CRIPageLoadPromptInterval", 10);
+
+        final Activity activity = super.cordova.getActivity();
+        final CordovaWebViewEngine engine = super.webView.getEngine();
+        lifecycle = new RequestLifecycle(activity, engine, promptInterval);
+    }
+
+    private void onMessageTypeFailure(String messageId, Object data) {
+        LOG.e(TAG, messageId + " received a data instance that is not an expected type:" + data.getClass().getName());
+    }
+
+    @Override
+    public void onReset() {
+        super.onReset();
+
+        lifecycle.requestStopped();
+    }
+
+    @Override
+    public Object onMessage(String id, Object data) {
+        if (id.equals("onReceivedError")) {
+            // Data is a JSONObject instance with the following keys:
+            // * errorCode
+            // * description
+            // * url
+
+            if (data instanceof JSONObject) {
+                JSONObject json = (JSONObject) data;
+
+                try {
+                    if (isRemote(json.getString("url"))) {
+                        lifecycle.requestStopped();
+                    }
+                } catch (JSONException e) {
+                    LOG.e(TAG, "Unexpected JSON in onReceiveError", e);
+                }
+            } else {
+                onMessageTypeFailure(id, data);
+            }
+        } else if (id.equals("onPageFinished")) {
+            if (data instanceof String) {
+                String url = (String) data;
+                if (isRemote(url)) {
+                    injectCordova();
+                    lifecycle.requestStopped();
+                }
+            } else {
+                onMessageTypeFailure(id, data);
+            }
+        } else if (id.equals("onPageStarted")) {
+            if (data instanceof String) {
+                String url = (String) data;
+
+                if (isRemote(url)) {
+                    lifecycle.requestStarted(url);
+                }
+            } else {
+                onMessageTypeFailure(id, data);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param url
+     * @return true if the URL over HTTP or HTTPS
+     */
+    private boolean isRemote(String url) {
+        return REMOTE_URL_REGEX.matcher((String) url).matches();
+    }
+
+    private void injectCordova() {
+        List<String> jsPaths = new ArrayList<String>();
+        for (String path: preInjectionFileNames) {
+            jsPaths.add(path);
+        }
+
+        jsPaths.add("www/cordova.js");
+
+        // We load the plugin code manually rather than allow cordova to load them (via
+        // cordova_plugins.js).  The reason for this is the WebView will attempt to load the
+        // file in the origin of the page (e.g. https://truckmover.com/plugins/plugin/plugin.js).
+        // By loading them first cordova will skip its loading process altogether.
+        jsPaths.addAll(jsPathsToInject(cordova.getActivity().getResources().getAssets(), "www/plugins"));
+
+        // Initialize the cordova plugin registry.
+        jsPaths.add("www/cordova_plugins.js");
+
+        // The way that I figured out to inject for android is to inject it as a script
+        // tag with the full JS encoded as a data URI
+        // (https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs).  The script tag
+        // is appended to the DOM and executed via a javascript URL (e.g. javascript:doJsStuff()).
+        StringBuilder jsToInject = new StringBuilder();
+        for (String path: jsPaths) {
+            jsToInject.append(readFile(cordova.getActivity().getResources().getAssets(), path));
+        }
+        String jsUrl = "javascript:var script = document.createElement('script');";
+        jsUrl += "script.src=\"data:text/javascript;charset=utf-8;base64,";
+
+        jsUrl += Base64.encodeToString(jsToInject.toString().getBytes(), Base64.NO_WRAP);
+        jsUrl += "\";";
+
+        jsUrl += "document.getElementsByTagName('head')[0].appendChild(script);";
+
+        webView.getEngine().loadUrl(jsUrl, false);
+    }
+
+    private String readFile(AssetManager assets, String filePath) {
+        StringBuilder out = new StringBuilder();
+        BufferedReader in = null;
+        try {
+            InputStream stream = assets.open(filePath);
+            in = new BufferedReader(new InputStreamReader(stream));
+            String str = "";
+
+            while ((str = in.readLine()) != null) {
+                out.append(str);
+                out.append("\n");
+            }
+        } catch (MalformedURLException e) {
+        } catch (IOException e) {
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return out.toString();
+    }
+
+    /**
+     * Searches the provided path for javascript files recursively.
+     *
+     * @param assets
+     * @param path start path
+     * @return found JS files
+     */
+    private List<String> jsPathsToInject(AssetManager assets, String path){
+        List jsPaths = new ArrayList<String>();
+
+        try {
+            for (String filePath: assets.list(path)) {
+                String fullPath = path + File.separator + filePath;
+
+                if (fullPath.endsWith(".js")) {
+                    jsPaths.add(fullPath);
+                } else {
+                    List<String> childPaths = jsPathsToInject(assets, fullPath);
+                    if (!childPaths.isEmpty()) {
+                        jsPaths.addAll(childPaths);
+                    }
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return jsPaths;
+    }
+
+    private static class RequestLifecycle {
+        private final Activity activity;
+        private final CordovaWebViewEngine engine;
+        private UserPromptTask task;
+        private final int promptInterval;
+
+        RequestLifecycle(Activity activity, CordovaWebViewEngine engine, int promptInterval) {
+            this.activity = activity;
+            this.engine = engine;
+            this.promptInterval = promptInterval;
+        }
+
+        boolean isLoading() {
+            return task != null;
+        }
+
+        void requestStopped() {
+            stopTask();
+        }
+
+        void requestStarted(final String url) {
+            startTask(url);
+        }
+
+        private synchronized void stopTask() {
+            if (task != null) {
+                task.cancel();
+                task = null;
+            }
+        }
+
+        private synchronized void startTask(final String url) {
+            if (task != null) {
+                task.cancel();
+            }
+
+            if (promptInterval > 0 ) {
+                task = new UserPromptTask(this, activity, engine, url);
+                new Timer().schedule(task, promptInterval * 1000);
+            }
+        }
+    }
+
+    /**
+     * Prompt the user asking if they want to wait on the current request or retry.
+     */
+    static class UserPromptTask extends TimerTask {
+        private final RequestLifecycle lifecycle;
+        private final Activity activity;
+        private final CordovaWebViewEngine engine;
+        final String url;
+
+        AlertDialog alertDialog;
+
+        UserPromptTask(RequestLifecycle lifecycle, Activity activity, CordovaWebViewEngine engine, String url) {
+            this.lifecycle = lifecycle;
+            this.activity = activity;
+            this.engine = engine;
+            this.url = url;
+        }
+
+        @Override
+        public boolean cancel() {
+            boolean result = super.cancel();
+            cleanup();
+
+            return result;
+        }
+
+        private void cleanup() {
+            if (alertDialog != null) {
+                alertDialog.dismiss();
+                alertDialog = null;
+            }
+        }
+
+        @Override
+        public void run() {
+            if (lifecycle.isLoading()) {
+                // Prompts the user giving them the choice to wait on the current request or retry.
+                lifecycle.activity.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+                        builder.setMessage("The server is taking longer than expected to respond.")
+                                .setOnDismissListener(new DialogInterface.OnDismissListener() {
+                                    @Override
+                                    public void onDismiss(DialogInterface dialog) {
+                                        UserPromptTask.this.cleanup();
+                                    }
+                                })
+                                .setPositiveButton("Retry", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        // Obviously only works for GETs but good enough.
+                                        engine.loadUrl(engine.getUrl(), false);
+                                    }
+                                })
+                                .setNegativeButton("Wait", new DialogInterface.OnClickListener() {
+                                    @Override
+                                    public void onClick(DialogInterface dialog, int id) {
+                                        lifecycle.startTask(url);
+                                    }
+                                });
+                        AlertDialog dialog = UserPromptTask.this.alertDialog = builder.create();
+                        dialog.show();
+                    }
+                });
+            } else {
+                lifecycle.stopTask();
+            }
+        }
+    }
+}

+ 0 - 19
platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/xiongzhu.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>SchemeUserState</key>
-	<dict>
-		<key>Cordova.xcscheme</key>
-		<dict>
-			<key>orderHint</key>
-			<integer>2</integer>
-		</dict>
-		<key>CordovaLib.xcscheme</key>
-		<dict>
-			<key>orderHint</key>
-			<integer>1</integer>
-		</dict>
-	</dict>
-</dict>
-</plist>

+ 1 - 1
platforms/ios/frameworks.json

@@ -2,9 +2,9 @@
     "ImageIO.framework": 1,
     "CoreLocation.framework": 1,
     "AVFoundation.framework": 1,
+    "WebKit.framework": 2,
     "libz.1.2.5.tbd": 1,
     "libsqlite3.0.tbd": 1,
     "libstdc++.6.0.9.tbd": 1,
-    "WebKit.framework": 1,
     "QuartzCore.framework": 1
 }

+ 48 - 19
platforms/ios/ios.json

@@ -10,10 +10,15 @@
           "CFBundleLocalizations": [
             {
               "xml": "<array><string>zh_CN</string></array>",
-              "count": 23
+              "count": 2
+            }
+          ],
+          "NSCameraUsageDescription": [
+            {
+              "xml": "<string>需要打开相机来扫码</string>",
+              "count": 1
             }
           ],
-          "NSCameraUsageDescription": [],
           "NSLocationWhenInUseUsageDescription": [
             {
               "xml": "<string>我们需要通过您的地理位置信息来获取周边数据</string>",
@@ -39,6 +44,18 @@
               "xml": "<preference name=\"CameraUsesGeolocation\" value=\"false\" />",
               "count": 1
             },
+            {
+              "xml": "<feature name=\"Handheld\"><param name=\"ios-package\" value=\"Handheld\" /><param name=\"onload\" value=\"true\" /></feature>",
+              "count": 1
+            },
+            {
+              "xml": "<feature name=\"navigationbar\"><param name=\"ios-package\" value=\"navigationbar\" /></feature>",
+              "count": 1
+            },
+            {
+              "xml": "<feature name=\"RemoteInjection\"><param name=\"ios-package\" value=\"CDVRemoteInjectionPlugin\" /><param name=\"onload\" value=\"true\" /></feature>",
+              "count": 1
+            },
             {
               "xml": "<feature name=\"SplashScreen\"><param name=\"ios-package\" value=\"CDVSplashScreen\" /><param name=\"onload\" value=\"true\" /></feature>",
               "count": 1
@@ -62,10 +79,6 @@
             {
               "xml": "<feature name=\"Toast\"><param name=\"ios-package\" value=\"Toast\" /></feature>",
               "count": 1
-            },
-            {
-              "xml": "<feature name=\"navigationbar\"><param name=\"ios-package\" value=\"navigationbar\" /></feature>",
-              "count": 1
             }
           ]
         }
@@ -76,10 +89,19 @@
     "cordova-plugin-camera": {
       "PACKAGE_NAME": "com.brightdairy.milk"
     },
+    "cordova-plugin-handheld": {
+      "PACKAGE_NAME": "com.brightdairy.milk"
+    },
+    "cordova-plugin-navigationbar": {
+      "PACKAGE_NAME": "com.brightdairy.milk"
+    },
     "cordova-plugin-pgyer": {
       "APP_ID": "d0f09be14a67a2082bdf777eb0b2a8c2",
       "PACKAGE_NAME": "com.brightdairy.milk"
     },
+    "cordova-plugin-remote-injection": {
+      "PACKAGE_NAME": "com.brightdairy.milk"
+    },
     "cordova-plugin-splashscreen": {
       "PACKAGE_NAME": "com.brightdairy.milk"
     },
@@ -95,9 +117,6 @@
     },
     "cordova-plugin-x-toast": {
       "PACKAGE_NAME": "com.brightdairy.milk"
-    },
-    "cordova-plugin-navigationbar": {
-      "PACKAGE_NAME": "com.brightdairy.milk"
     }
   },
   "dependent_plugins": {},
@@ -134,6 +153,22 @@
         "CameraPopoverHandle"
       ]
     },
+    {
+      "id": "cordova-plugin-handheld.Handheld",
+      "file": "plugins/cordova-plugin-handheld/www/Handheld.js",
+      "pluginId": "cordova-plugin-handheld",
+      "clobbers": [
+        "Handheld"
+      ]
+    },
+    {
+      "id": "cordova-plugin-navigationbar.navigationbar",
+      "file": "plugins/cordova-plugin-navigationbar/www/navigationbar.js",
+      "pluginId": "cordova-plugin-navigationbar",
+      "clobbers": [
+        "cordova.plugins.navigationbar"
+      ]
+    },
     {
       "id": "cordova-plugin-pgyer.pgyer",
       "file": "plugins/cordova-plugin-pgyer/www/pgyer.js",
@@ -186,24 +221,18 @@
       "id": "cordova-plugin-x-toast.tests",
       "file": "plugins/cordova-plugin-x-toast/test/tests.js",
       "pluginId": "cordova-plugin-x-toast"
-    },
-    {
-      "id": "cordova-plugin-navigationbar.navigationbar",
-      "file": "plugins/cordova-plugin-navigationbar/www/navigationbar.js",
-      "pluginId": "cordova-plugin-navigationbar",
-      "clobbers": [
-        "cordova.plugins.navigationbar"
-      ]
     }
   ],
   "plugin_metadata": {
     "cordova-plugin-camera": "4.0.2",
+    "cordova-plugin-handheld": "1.0.0",
+    "cordova-plugin-navigationbar": "1.0.0",
     "cordova-plugin-pgyer": "1.0.0",
+    "cordova-plugin-remote-injection": "0.5.2",
     "cordova-plugin-splashscreen": "5.0.1",
     "cordova-plugin-tencent-bg-location": "1.0.0",
     "cordova-plugin-whitelist": "1.3.3",
     "cordova-plugin-wkwebview-engine": "1.1.4",
-    "cordova-plugin-x-toast": "2.6.0",
-    "cordova-plugin-navigationbar": "1.0.0"
+    "cordova-plugin-x-toast": "2.6.0"
   }
 }

+ 20 - 19
platforms/ios/platform_www/cordova_plugins.js

@@ -32,6 +32,22 @@ module.exports = [
       "CameraPopoverHandle"
     ]
   },
+  {
+    "id": "cordova-plugin-handheld.Handheld",
+    "file": "plugins/cordova-plugin-handheld/www/Handheld.js",
+    "pluginId": "cordova-plugin-handheld",
+    "clobbers": [
+      "Handheld"
+    ]
+  },
+  {
+    "id": "cordova-plugin-navigationbar.navigationbar",
+    "file": "plugins/cordova-plugin-navigationbar/www/navigationbar.js",
+    "pluginId": "cordova-plugin-navigationbar",
+    "clobbers": [
+      "cordova.plugins.navigationbar"
+    ]
+  },
   {
     "id": "cordova-plugin-pgyer.pgyer",
     "file": "plugins/cordova-plugin-pgyer/www/pgyer.js",
@@ -84,36 +100,21 @@ module.exports = [
     "id": "cordova-plugin-x-toast.tests",
     "file": "plugins/cordova-plugin-x-toast/test/tests.js",
     "pluginId": "cordova-plugin-x-toast"
-  },
-  {
-    "id": "cordova-plugin-navigationbar.navigationbar",
-    "file": "plugins/cordova-plugin-navigationbar/www/navigationbar.js",
-    "pluginId": "cordova-plugin-navigationbar",
-    "clobbers": [
-      "cordova.plugins.navigationbar"
-    ]
-  },
-  {
-    "id": "cordova-plugin-handheld.Handheld",
-    "file": "plugins/cordova-plugin-handheld/www/Handheld.js",
-    "pluginId": "cordova-plugin-handheld",
-    "clobbers": [
-      "Handheld"
-    ]
   }
 ];
 module.exports.metadata = 
 // TOP OF METADATA
 {
   "cordova-plugin-camera": "4.0.2",
+  "cordova-plugin-handheld": "1.0.0",
+  "cordova-plugin-navigationbar": "1.0.0",
   "cordova-plugin-pgyer": "1.0.0",
+  "cordova-plugin-remote-injection": "0.5.2",
   "cordova-plugin-splashscreen": "5.0.1",
   "cordova-plugin-tencent-bg-location": "1.0.0",
   "cordova-plugin-whitelist": "1.3.3",
   "cordova-plugin-wkwebview-engine": "1.1.4",
-  "cordova-plugin-x-toast": "2.6.0",
-  "cordova-plugin-navigationbar": "1.0.0",
-  "cordova-plugin-handheld": "1.0.0"
+  "cordova-plugin-x-toast": "2.6.0"
 };
 // BOTTOM OF METADATA
 });

+ 46 - 0
platforms/ios/platform_www/plugins/cordova-plugin-handheld/www/Handheld.js

@@ -0,0 +1,46 @@
+cordova.define("cordova-plugin-handheld.Handheld", function(require, exports, module) {
+var exec = require("cordova/exec");
+
+exports.scanCode = function(success, error) {
+    exec(success, error, "Handheld", "scanCode", []);
+};
+exports.stopScan = function(success, error) {
+    exec(success, error, "Handheld", "stopScan", []);
+};
+exports.readTag = function(success, error, options) {
+    exec(success, error, "Handheld", "readTag", [options]);
+};
+exports.stopRead = function(success, error) {
+    exec(success, error, "Handheld", "stopRead", []);
+};
+exports.getPicture = function(success, error, cameraOptions) {
+    exec(
+        function() {
+            navigator.camera.getPicture(
+                function(res) {
+                    exec(function() {}, function() {}, "Handheld", "resume", []);
+                    try {
+                        success(res);
+                    } catch (e) {}
+                },
+                function(err1) {
+                    exec(function() {}, function() {}, "Handheld", "resume", []);
+                    try {
+                        error(err1);
+                    } catch (e) {}
+                },
+                cameraOptions
+            );
+        },
+        function(err) {
+            try {
+                error(err);
+            } catch (e) {}
+        },
+        "Handheld",
+        "pause",
+        []
+    );
+};
+
+});

+ 262 - 0
platforms/ios/www/cordova-js-src/exec.js

@@ -0,0 +1,262 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/*global require, module, atob, document */
+
+/**
+ * Creates a gap bridge iframe used to notify the native code about queued
+ * commands.
+ */
+var cordova = require('cordova'),
+    utils = require('cordova/utils'),
+    base64 = require('cordova/base64'),
+    execIframe,
+    commandQueue = [], // Contains pending JS->Native messages.
+    isInContextOfEvalJs = 0,
+    failSafeTimerId = 0;
+
+function massageArgsJsToNative(args) {
+    if (!args || utils.typeName(args) != 'Array') {
+        return args;
+    }
+    var ret = [];
+    args.forEach(function(arg, i) {
+        if (utils.typeName(arg) == 'ArrayBuffer') {
+            ret.push({
+                'CDVType': 'ArrayBuffer',
+                'data': base64.fromArrayBuffer(arg)
+            });
+        } else {
+            ret.push(arg);
+        }
+    });
+    return ret;
+}
+
+function massageMessageNativeToJs(message) {
+    if (message.CDVType == 'ArrayBuffer') {
+        var stringToArrayBuffer = function(str) {
+            var ret = new Uint8Array(str.length);
+            for (var i = 0; i < str.length; i++) {
+                ret[i] = str.charCodeAt(i);
+            }
+            return ret.buffer;
+        };
+        var base64ToArrayBuffer = function(b64) {
+            return stringToArrayBuffer(atob(b64));
+        };
+        message = base64ToArrayBuffer(message.data);
+    }
+    return message;
+}
+
+function convertMessageToArgsNativeToJs(message) {
+    var args = [];
+    if (!message || !message.hasOwnProperty('CDVType')) {
+        args.push(message);
+    } else if (message.CDVType == 'MultiPart') {
+        message.messages.forEach(function(e) {
+            args.push(massageMessageNativeToJs(e));
+        });
+    } else {
+        args.push(massageMessageNativeToJs(message));
+    }
+    return args;
+}
+
+function iOSExec() {
+
+    var successCallback, failCallback, service, action, actionArgs;
+    var callbackId = null;
+    if (typeof arguments[0] !== 'string') {
+        // FORMAT ONE
+        successCallback = arguments[0];
+        failCallback = arguments[1];
+        service = arguments[2];
+        action = arguments[3];
+        actionArgs = arguments[4];
+
+        // Since we need to maintain backwards compatibility, we have to pass
+        // an invalid callbackId even if no callback was provided since plugins
+        // will be expecting it. The Cordova.exec() implementation allocates
+        // an invalid callbackId and passes it even if no callbacks were given.
+        callbackId = 'INVALID';
+    } else {
+        throw new Error('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' +
+            'cordova.exec(null, null, \'Service\', \'action\', [ arg1, arg2 ]);'
+        );
+    }
+
+    // If actionArgs is not provided, default to an empty array
+    actionArgs = actionArgs || [];
+
+    // Register the callbacks and add the callbackId to the positional
+    // arguments if given.
+    if (successCallback || failCallback) {
+        callbackId = service + cordova.callbackId++;
+        cordova.callbacks[callbackId] =
+            {success:successCallback, fail:failCallback};
+    }
+
+    actionArgs = massageArgsJsToNative(actionArgs);
+
+    var command = [callbackId, service, action, actionArgs];
+
+    // Stringify and queue the command. We stringify to command now to
+    // effectively clone the command arguments in case they are mutated before
+    // the command is executed.
+    commandQueue.push(JSON.stringify(command));
+
+    // If we're in the context of a stringByEvaluatingJavaScriptFromString call,
+    // then the queue will be flushed when it returns; no need for a poke.
+    // Also, if there is already a command in the queue, then we've already
+    // poked the native side, so there is no reason to do so again.
+    if (!isInContextOfEvalJs && commandQueue.length == 1) {
+        pokeNative();
+    }
+}
+
+// CB-10530
+function proxyChanged() {
+    var cexec = cordovaExec();
+       
+    return (execProxy !== cexec && // proxy objects are different
+            iOSExec !== cexec      // proxy object is not the current iOSExec
+            );
+}
+
+// CB-10106
+function handleBridgeChange() {
+    if (proxyChanged()) {
+        var commandString = commandQueue.shift();
+        while(commandString) {
+            var command = JSON.parse(commandString);
+            var callbackId = command[0];
+            var service = command[1];
+            var action = command[2];
+            var actionArgs = command[3];
+            var callbacks = cordova.callbacks[callbackId] || {};
+            
+            execProxy(callbacks.success, callbacks.fail, service, action, actionArgs);
+            
+            commandString = commandQueue.shift();
+        };
+        return true;
+    }
+    
+    return false;
+}
+
+function pokeNative() {
+    // CB-5488 - Don't attempt to create iframe before document.body is available.
+    if (!document.body) {
+        setTimeout(pokeNative);
+        return;
+    }
+    
+    // Check if they've removed it from the DOM, and put it back if so.
+    if (execIframe && execIframe.contentWindow) {
+        execIframe.contentWindow.location = 'gap://ready';
+    } else {
+        execIframe = document.createElement('iframe');
+        execIframe.style.display = 'none';
+        execIframe.src = 'gap://ready';
+        document.body.appendChild(execIframe);
+    }
+    // Use a timer to protect against iframe being unloaded during the poke (CB-7735).
+    // This makes the bridge ~ 7% slower, but works around the poke getting lost
+    // when the iframe is removed from the DOM.
+    // An onunload listener could be used in the case where the iframe has just been
+    // created, but since unload events fire only once, it doesn't work in the normal
+    // case of iframe reuse (where unload will have already fired due to the attempted
+    // navigation of the page).
+    failSafeTimerId = setTimeout(function() {
+        if (commandQueue.length) {
+            // CB-10106 - flush the queue on bridge change
+            if (!handleBridgeChange()) {
+                pokeNative();
+             }
+        }
+    }, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
+}
+
+iOSExec.nativeFetchMessages = function() {
+    // Stop listing for window detatch once native side confirms poke.
+    if (failSafeTimerId) {
+        clearTimeout(failSafeTimerId);
+        failSafeTimerId = 0;
+    }
+    // Each entry in commandQueue is a JSON string already.
+    if (!commandQueue.length) {
+        return '';
+    }
+    var json = '[' + commandQueue.join(',') + ']';
+    commandQueue.length = 0;
+    return json;
+};
+
+iOSExec.nativeCallback = function(callbackId, status, message, keepCallback, debug) {
+    return iOSExec.nativeEvalAndFetch(function() {
+        var success = status === 0 || status === 1;
+        var args = convertMessageToArgsNativeToJs(message);
+        function nc2() {
+            cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
+        }
+        setTimeout(nc2, 0);
+    });
+};
+
+iOSExec.nativeEvalAndFetch = function(func) {
+    // This shouldn't be nested, but better to be safe.
+    isInContextOfEvalJs++;
+    try {
+        func();
+        return iOSExec.nativeFetchMessages();
+    } finally {
+        isInContextOfEvalJs--;
+    }
+};
+
+// Proxy the exec for bridge changes. See CB-10106
+
+function cordovaExec() {
+    var cexec = require('cordova/exec');
+    var cexec_valid = (typeof cexec.nativeFetchMessages === 'function') && (typeof cexec.nativeEvalAndFetch === 'function') && (typeof cexec.nativeCallback === 'function');
+    return (cexec_valid && execProxy !== cexec)? cexec : iOSExec;
+}
+
+function execProxy() {
+    cordovaExec().apply(null, arguments);
+};
+
+execProxy.nativeFetchMessages = function() {
+    return cordovaExec().nativeFetchMessages.apply(null, arguments);
+};
+
+execProxy.nativeEvalAndFetch = function() {
+    return cordovaExec().nativeEvalAndFetch.apply(null, arguments);
+};
+
+execProxy.nativeCallback = function() {
+    return cordovaExec().nativeCallback.apply(null, arguments);
+};
+
+module.exports = execProxy;

+ 31 - 0
platforms/ios/www/cordova-js-src/platform.js

@@ -0,0 +1,31 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+module.exports = {
+    id: 'ios',
+    bootstrap: function () {
+        // Attach the console polyfill that is iOS-only to window.console
+        // see the file under plugin/ios/console.js
+        require('cordova/modulemapper').clobbers('cordova/plugin/ios/console', 'window.console');
+
+        require('cordova/channel').onNativeReady.fire();
+    }
+};

+ 186 - 0
platforms/ios/www/cordova-js-src/plugin/ios/console.js

@@ -0,0 +1,186 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+//------------------------------------------------------------------------------
+
+var logger = require('cordova/plugin/ios/logger');
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = logger.format.apply(logger.format, [].slice.call(arguments, 1));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrappedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrappedOrigCall(WinConsole[key], console[key]);
+    }
+}

+ 354 - 0
platforms/ios/www/cordova-js-src/plugin/ios/logger.js

@@ -0,0 +1,354 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+
+var UseConsole   = false;
+var UseLogger    = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+var originalConsole = console;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  E.g., the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Getter/Setter for the useLogger functionality
+ *
+ * When useLogger is true, the logger will log via the
+ * native Logger plugin.
+ */
+logger.useLogger = function (value) {
+    // Enforce boolean
+    if (arguments.length) UseLogger = !!value;
+    return UseLogger;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+// return the correct formatString for an object
+function formatStringForMessage(message) {
+    return (typeof message === "string") ? "" : "%o"; 
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 1);
+    var fmtString = formatStringForMessage(formatArgs[0]);
+    if (fmtString.length > 0){
+        formatArgs.unshift(fmtString); // add formatString
+    }
+
+    var message    = logger.format.apply(logger.format, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // Log using the native logger if that is enabled
+    if (UseLogger) {
+        exec(null, null, "Console", "logLevel", [level, message]);
+    }
+
+    // Log using the console if that is enabled
+    if (UseConsole) {
+        // make sure console is not using logger
+        if (console.useLogger()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+
+        // log to the console
+        switch (level) {
+            case logger.LOG:   originalConsole.log(message); break;
+            case logger.ERROR: originalConsole.log("ERROR: " + message); break;
+            case logger.WARN:  originalConsole.log("WARN: "  + message); break;
+            case logger.INFO:  originalConsole.log("INFO: "  + message); break;
+            case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;
+        }
+    }
+};
+
+
+/**
+ * Formats a string and arguments following it ala console.log()
+ *
+ * Any remaining arguments will be appended to the formatted string.
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+logger.format = function(formatString, args) {
+    return __format(arguments[0], [].slice.call(arguments,1)).join(' ');
+};
+
+
+//------------------------------------------------------------------------------
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * Returns an array containing the formatted string and any remaining
+ * arguments.
+ */
+function __format(formatString, args) {
+    if (formatString === null || formatString === undefined) return [""];
+    if (arguments.length == 1) return [formatString.toString()];
+
+    if (typeof formatString != "string")
+        formatString = formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var match = pattern.exec(rest);
+        if (!match) break;
+
+        var arg   = args.shift();
+        rest = match[3];
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(__formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    var remainingArgs = [].slice.call(args);
+    remainingArgs.unshift(result.join(''));
+    return remainingArgs;
+}
+
+function __formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+
+//------------------------------------------------------------------------------
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);

+ 2431 - 0
platforms/ios/www/cordova.js

@@ -0,0 +1,2431 @@
+// Platform: ios
+// 4450a4cea50616e080a82e8ede9e3d6a1fe3c3ec
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+;(function() {
+var PLATFORM_VERSION_BUILD_LABEL = '4.5.4';
+// file: src/scripts/require.js
+
+/* jshint -W079 */
+/* jshint -W020 */
+
+var require;
+var define;
+
+(function () {
+    var modules = {};
+    // Stack of moduleIds currently being built.
+    var requireStack = [];
+    // Map of module ID -> index into requireStack of modules currently being built.
+    var inProgressModules = {};
+    var SEPARATOR = '.';
+
+    function build (module) {
+        var factory = module.factory;
+        var localRequire = function (id) {
+            var resultantId = id;
+            // Its a relative path, so lop off the last portion and add the id (minus "./")
+            if (id.charAt(0) === '.') {
+                resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2);
+            }
+            return require(resultantId);
+        };
+        module.exports = {};
+        delete module.factory;
+        factory(localRequire, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw 'module ' + id + ' not found';
+        } else if (id in inProgressModules) {
+            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+            throw 'Cycle in require graph: ' + cycle;
+        }
+        if (modules[id].factory) {
+            try {
+                inProgressModules[id] = requireStack.length;
+                requireStack.push(id);
+                return build(modules[id]);
+            } finally {
+                delete inProgressModules[id];
+                requireStack.pop();
+            }
+        }
+        return modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw 'module ' + id + ' already defined';
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+    define.moduleMap = modules;
+})();
+
+// Export for use in node
+if (typeof module === 'object' && typeof require === 'function') {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+
+// file: src/cordova.js
+define("cordova", function(require, exports, module) {
+
+// Workaround for Windows 10 in hosted environment case
+// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
+if (window.cordova && !(window.cordova instanceof HTMLElement)) { // eslint-disable-line no-undef
+    throw new Error('cordova already defined');
+}
+
+var channel = require('cordova/channel');
+var platform = require('cordova/platform');
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {};
+var windowEventHandlers = {};
+
+document.addEventListener = function (evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] !== 'undefined') {
+        documentEventHandlers[e].subscribe(handler);
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function (evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] !== 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function (evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] !== 'undefined') {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function (evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] !== 'undefined') {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent (type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+/* eslint-disable no-undef */
+var cordova = {
+    define: define,
+    require: require,
+    version: PLATFORM_VERSION_BUILD_LABEL,
+    platformVersion: PLATFORM_VERSION_BUILD_LABEL,
+    platformId: platform.id,
+
+    /* eslint-enable no-undef */
+
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler: function (event) {
+        return (windowEventHandlers[event] = channel.create(event));
+    },
+    addStickyDocumentEventHandler: function (event) {
+        return (documentEventHandlers[event] = channel.createSticky(event));
+    },
+    addDocumentEventHandler: function (event) {
+        return (documentEventHandlers[event] = channel.create(event));
+    },
+    removeWindowEventHandler: function (event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler: function (event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retrieve original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function () {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+            'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     * bNoDetach is required for events which cause an exception which needs to be caught in native code
+     */
+    fireDocumentEvent: function (type, data, bNoDetach) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] !== 'undefined') {
+            if (bNoDetach) {
+                documentEventHandlers[type].fire(evt);
+            } else {
+                setTimeout(function () {
+                    // Fire deviceready on listeners that were registered before cordova.js was loaded.
+                    if (type === 'deviceready') {
+                        document.dispatchEvent(evt);
+                    }
+                    documentEventHandlers[type].fire(evt);
+                }, 0);
+            }
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function (type, data) {
+        var evt = createEvent(type, data);
+        if (typeof windowEventHandlers[type] !== 'undefined') {
+            setTimeout(function () {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+
+    /**
+     * Plugin callback mechanism.
+     */
+    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+    callbackId: Math.floor(Math.random() * 2000000000),
+    callbacks: {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     */
+    callbackSuccess: function (callbackId, args) {
+        cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     */
+    callbackError: function (callbackId, args) {
+        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+        // Derive success from status.
+        cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
+    },
+
+    /**
+     * Called by native code when returning the result from an action.
+     */
+    callbackFromNative: function (callbackId, isSuccess, status, args, keepCallback) {
+        try {
+            var callback = cordova.callbacks[callbackId];
+            if (callback) {
+                if (isSuccess && status === cordova.callbackStatus.OK) {
+                    callback.success && callback.success.apply(null, args);
+                } else if (!isSuccess) {
+                    callback.fail && callback.fail.apply(null, args);
+                }
+                /*
+                else
+                    Note, this case is intentionally not caught.
+                    this can happen if isSuccess is true, but callbackStatus is NO_RESULT
+                    which is used to remove a callback from the list without calling the callbacks
+                    typically keepCallback is false in this case
+                */
+                // Clear callback if not expecting any more results
+                if (!keepCallback) {
+                    delete cordova.callbacks[callbackId];
+                }
+            }
+        } catch (err) {
+            var msg = 'Error in ' + (isSuccess ? 'Success' : 'Error') + ' callbackId: ' + callbackId + ' : ' + err;
+            console && console.log && console.log(msg);
+            cordova.fireWindowEvent('cordovacallbackerror', { 'message': msg });
+            throw err;
+        }
+    },
+    addConstructor: function (func) {
+        channel.onCordovaReady.subscribe(function () {
+            try {
+                func();
+            } catch (e) {
+                console.log('Failed to run constructor: ' + e);
+            }
+        });
+    }
+};
+
+module.exports = cordova;
+
+});
+
+// file: src/common/argscheck.js
+define("cordova/argscheck", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+    'A': 'Array',
+    'D': 'Date',
+    'N': 'Number',
+    'S': 'String',
+    'F': 'Function',
+    'O': 'Object'
+};
+
+function extractParamName (callee, argIndex) {
+    return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs (spec, functionName, args, opt_callee) {
+    if (!moduleExports.enableChecks) {
+        return;
+    }
+    var errMsg = null;
+    var typeName;
+    for (var i = 0; i < spec.length; ++i) {
+        var c = spec.charAt(i);
+        var cUpper = c.toUpperCase();
+        var arg = args[i];
+        // Asterix means allow anything.
+        if (c === '*') {
+            continue;
+        }
+        typeName = utils.typeName(arg);
+        if ((arg === null || arg === undefined) && c === cUpper) {
+            continue;
+        }
+        if (typeName !== typeMap[cUpper]) {
+            errMsg = 'Expected ' + typeMap[cUpper];
+            break;
+        }
+    }
+    if (errMsg) {
+        errMsg += ', but got ' + typeName + '.';
+        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+        // Don't log when running unit tests.
+        if (typeof jasmine === 'undefined') {
+            console.error(errMsg);
+        }
+        throw TypeError(errMsg);
+    }
+}
+
+function getValue (value, defaultValue) {
+    return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+});
+
+// file: src/common/base64.js
+define("cordova/base64", function(require, exports, module) {
+
+var base64 = exports;
+
+base64.fromArrayBuffer = function (arrayBuffer) {
+    var array = new Uint8Array(arrayBuffer);
+    return uint8ToBase64(array);
+};
+
+base64.toArrayBuffer = function (str) {
+    var decodedStr = typeof atob !== 'undefined' ? atob(str) : Buffer.from(str, 'base64').toString('binary'); // eslint-disable-line no-undef
+    var arrayBuffer = new ArrayBuffer(decodedStr.length);
+    var array = new Uint8Array(arrayBuffer);
+    for (var i = 0, len = decodedStr.length; i < len; i++) {
+        array[i] = decodedStr.charCodeAt(i);
+    }
+    return arrayBuffer;
+};
+
+// ------------------------------------------------------------------------------
+
+/* This code is based on the performance tests at http://jsperf.com/b64tests
+ * This 12-bit-at-a-time algorithm was the best performing version on all
+ * platforms tested.
+ */
+
+var b64_6bit = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+var b64_12bit;
+
+var b64_12bitTable = function () {
+    b64_12bit = [];
+    for (var i = 0; i < 64; i++) {
+        for (var j = 0; j < 64; j++) {
+            b64_12bit[i * 64 + j] = b64_6bit[i] + b64_6bit[j];
+        }
+    }
+    b64_12bitTable = function () { return b64_12bit; };
+    return b64_12bit;
+};
+
+function uint8ToBase64 (rawData) {
+    var numBytes = rawData.byteLength;
+    var output = '';
+    var segment;
+    var table = b64_12bitTable();
+    for (var i = 0; i < numBytes - 2; i += 3) {
+        segment = (rawData[i] << 16) + (rawData[i + 1] << 8) + rawData[i + 2];
+        output += table[segment >> 12];
+        output += table[segment & 0xfff];
+    }
+    if (numBytes - i === 2) {
+        segment = (rawData[i] << 16) + (rawData[i + 1] << 8);
+        output += table[segment >> 12];
+        output += b64_6bit[(segment & 0xfff) >> 6];
+        output += '=';
+    } else if (numBytes - i === 1) {
+        segment = (rawData[i] << 16);
+        output += table[segment >> 12];
+        output += '==';
+    }
+    return output;
+}
+
+});
+
+// file: src/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each (objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function clobber (obj, key, value) {
+    exports.replaceHookForTesting(obj, key);
+    var needsProperty = false;
+    try {
+        obj[key] = value;
+    } catch (e) {
+        needsProperty = true;
+    }
+    // Getters can only be overridden by getters.
+    if (needsProperty || obj[key] !== value) {
+        utils.defineGetter(obj, key, function () {
+            return value;
+        });
+    }
+}
+
+function assignOrWrapInDeprecateGetter (obj, key, value, message) {
+    if (message) {
+        utils.defineGetter(obj, key, function () {
+            console.log(message);
+            delete obj[key];
+            clobber(obj, key, value);
+            return value;
+        });
+    } else {
+        clobber(obj, key, value);
+    }
+}
+
+function include (parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+            var result = obj.path ? require(obj.path) : {};
+
+            if (clobber) {
+                // Clobber if it doesn't exist.
+                if (typeof parent[key] === 'undefined') {
+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                } else if (typeof obj.path !== 'undefined') {
+                    // If merging, merge properties onto parent, otherwise, clobber.
+                    if (merge) {
+                        recursiveMerge(parent[key], result);
+                    } else {
+                        assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                    }
+                }
+                result = parent[key];
+            } else {
+                // Overwrite if not currently defined.
+                if (typeof parent[key] === 'undefined') {
+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                } else {
+                    // Set result to what already exists, so we can build children into it if they exist.
+                    result = parent[key];
+                }
+            }
+
+            if (obj.children) {
+                include(result, obj.children, clobber, merge);
+            }
+        } catch (e) {
+            utils.alert('Exception building Cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge (target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (target.prototype && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                clobber(target.prototype, prop, src[prop]);
+            } else {
+                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+                    recursiveMerge(target[prop], src[prop]);
+                } else {
+                    clobber(target, prop, src[prop]);
+                }
+            }
+        }
+    }
+}
+
+exports.buildIntoButDoNotClobber = function (objects, target) {
+    include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function (objects, target) {
+    include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function (objects, target) {
+    include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function () {};
+
+});
+
+// file: src/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+var nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady*              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
+ * onDeviceReady*              User event fired to indicate that Cordova is ready
+ * onResume                    User event fired to indicate a start/resume lifecycle event
+ * onPause                     User event fired to indicate a pause lifecycle event
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ */
+var Channel = function (type, sticky) {
+    this.type = type;
+    // Map of guid -> function.
+    this.handlers = {};
+    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+    this.state = sticky ? 1 : 0;
+    // Used in sticky mode to remember args passed to fire().
+    this.fireArgs = null;
+    // Used by onHasSubscribersChange to know if there are any listeners.
+    this.numHandlers = 0;
+    // Function that is called when the first listener is subscribed, or when
+    // the last listener is unsubscribed.
+    this.onHasSubscribersChange = null;
+};
+var channel = {
+    /**
+     * Calls the provided function only after all of the channels specified
+     * have been fired. All channels must be sticky channels.
+     */
+    join: function (h, c) {
+        var len = c.length;
+        var i = len;
+        var f = function () {
+            if (!(--i)) h();
+        };
+        for (var j = 0; j < len; j++) {
+            if (c[j].state === 0) {
+                throw Error('Can only use join with sticky channels.');
+            }
+            c[j].subscribe(f);
+        }
+        if (!len) h();
+    },
+    /* eslint-disable no-return-assign */
+    create: function (type) {
+        return channel[type] = new Channel(type, false);
+    },
+    createSticky: function (type) {
+        return channel[type] = new Channel(type, true);
+    },
+    /* eslint-enable no-return-assign */
+    /**
+     * cordova Channels that must fire before "deviceready" is fired.
+     */
+    deviceReadyChannelsArray: [],
+    deviceReadyChannelsMap: {},
+
+    /**
+     * Indicate that a feature needs to be initialized before it is ready to be used.
+     * This holds up Cordova's "deviceready" event until the feature has been initialized
+     * and Cordova.initComplete(feature) is called.
+     *
+     * @param feature {String}     The unique feature name
+     */
+    waitForInitialization: function (feature) {
+        if (feature) {
+            var c = channel[feature] || this.createSticky(feature);
+            this.deviceReadyChannelsMap[feature] = c;
+            this.deviceReadyChannelsArray.push(c);
+        }
+    },
+
+    /**
+     * Indicate that initialization code has completed and the feature is ready to be used.
+     *
+     * @param feature {String}     The unique feature name
+     */
+    initializationComplete: function (feature) {
+        var c = this.deviceReadyChannelsMap[feature];
+        if (c) {
+            c.fire();
+        }
+    }
+};
+
+function checkSubscriptionArgument (argument) {
+    if (typeof argument !== 'function' && typeof argument.handleEvent !== 'function') {
+        throw new Error(
+            'Must provide a function or an EventListener object ' +
+                'implementing the handleEvent interface.'
+        );
+    }
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function (eventListenerOrFunction, eventListener) {
+    checkSubscriptionArgument(eventListenerOrFunction);
+    var handleEvent, guid;
+
+    if (eventListenerOrFunction && typeof eventListenerOrFunction === 'object') {
+        // Received an EventListener object implementing the handleEvent interface
+        handleEvent = eventListenerOrFunction.handleEvent;
+        eventListener = eventListenerOrFunction;
+    } else {
+        // Received a function to handle event
+        handleEvent = eventListenerOrFunction;
+    }
+
+    if (this.state === 2) {
+        handleEvent.apply(eventListener || this, this.fireArgs);
+        return;
+    }
+
+    guid = eventListenerOrFunction.observer_guid;
+    if (typeof eventListener === 'object') {
+        handleEvent = utils.close(eventListener, handleEvent);
+    }
+
+    if (!guid) {
+        // First time any channel has seen this subscriber
+        guid = '' + nextGuid++;
+    }
+    handleEvent.observer_guid = guid;
+    eventListenerOrFunction.observer_guid = guid;
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[guid]) {
+        this.handlers[guid] = handleEvent;
+        this.numHandlers++;
+        if (this.numHandlers === 1) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function (eventListenerOrFunction) {
+    checkSubscriptionArgument(eventListenerOrFunction);
+    var handleEvent, guid, handler;
+
+    if (eventListenerOrFunction && typeof eventListenerOrFunction === 'object') {
+        // Received an EventListener object implementing the handleEvent interface
+        handleEvent = eventListenerOrFunction.handleEvent;
+    } else {
+        // Received a function to handle event
+        handleEvent = eventListenerOrFunction;
+    }
+
+    guid = handleEvent.observer_guid;
+    handler = this.handlers[guid];
+    if (handler) {
+        delete this.handlers[guid];
+        this.numHandlers--;
+        if (this.numHandlers === 0) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function (e) {
+    var fail = false; // eslint-disable-line no-unused-vars
+    var fireArgs = Array.prototype.slice.call(arguments);
+    // Apply stickiness.
+    if (this.state === 1) {
+        this.state = 2;
+        this.fireArgs = fireArgs;
+    }
+    if (this.numHandlers) {
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
+        for (var item in this.handlers) {
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            toCall[i].apply(this, fireArgs);
+        }
+        if (this.state === 2 && this.numHandlers) {
+            this.numHandlers = 0;
+            this.handlers = {};
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+// FIXME remove this
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});
+
+// file: /Users/spindori/Documents/Cordova/cordova-ios/cordova-js-src/exec.js
+define("cordova/exec", function(require, exports, module) {
+
+/*global require, module, atob, document */
+
+/**
+ * Creates a gap bridge iframe used to notify the native code about queued
+ * commands.
+ */
+var cordova = require('cordova'),
+    utils = require('cordova/utils'),
+    base64 = require('cordova/base64'),
+    execIframe,
+    commandQueue = [], // Contains pending JS->Native messages.
+    isInContextOfEvalJs = 0,
+    failSafeTimerId = 0;
+
+function massageArgsJsToNative(args) {
+    if (!args || utils.typeName(args) != 'Array') {
+        return args;
+    }
+    var ret = [];
+    args.forEach(function(arg, i) {
+        if (utils.typeName(arg) == 'ArrayBuffer') {
+            ret.push({
+                'CDVType': 'ArrayBuffer',
+                'data': base64.fromArrayBuffer(arg)
+            });
+        } else {
+            ret.push(arg);
+        }
+    });
+    return ret;
+}
+
+function massageMessageNativeToJs(message) {
+    if (message.CDVType == 'ArrayBuffer') {
+        var stringToArrayBuffer = function(str) {
+            var ret = new Uint8Array(str.length);
+            for (var i = 0; i < str.length; i++) {
+                ret[i] = str.charCodeAt(i);
+            }
+            return ret.buffer;
+        };
+        var base64ToArrayBuffer = function(b64) {
+            return stringToArrayBuffer(atob(b64));
+        };
+        message = base64ToArrayBuffer(message.data);
+    }
+    return message;
+}
+
+function convertMessageToArgsNativeToJs(message) {
+    var args = [];
+    if (!message || !message.hasOwnProperty('CDVType')) {
+        args.push(message);
+    } else if (message.CDVType == 'MultiPart') {
+        message.messages.forEach(function(e) {
+            args.push(massageMessageNativeToJs(e));
+        });
+    } else {
+        args.push(massageMessageNativeToJs(message));
+    }
+    return args;
+}
+
+function iOSExec() {
+
+    var successCallback, failCallback, service, action, actionArgs;
+    var callbackId = null;
+    if (typeof arguments[0] !== 'string') {
+        // FORMAT ONE
+        successCallback = arguments[0];
+        failCallback = arguments[1];
+        service = arguments[2];
+        action = arguments[3];
+        actionArgs = arguments[4];
+
+        // Since we need to maintain backwards compatibility, we have to pass
+        // an invalid callbackId even if no callback was provided since plugins
+        // will be expecting it. The Cordova.exec() implementation allocates
+        // an invalid callbackId and passes it even if no callbacks were given.
+        callbackId = 'INVALID';
+    } else {
+        throw new Error('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' +
+            'cordova.exec(null, null, \'Service\', \'action\', [ arg1, arg2 ]);'
+        );
+    }
+
+    // If actionArgs is not provided, default to an empty array
+    actionArgs = actionArgs || [];
+
+    // Register the callbacks and add the callbackId to the positional
+    // arguments if given.
+    if (successCallback || failCallback) {
+        callbackId = service + cordova.callbackId++;
+        cordova.callbacks[callbackId] =
+            {success:successCallback, fail:failCallback};
+    }
+
+    actionArgs = massageArgsJsToNative(actionArgs);
+
+    var command = [callbackId, service, action, actionArgs];
+
+    // Stringify and queue the command. We stringify to command now to
+    // effectively clone the command arguments in case they are mutated before
+    // the command is executed.
+    commandQueue.push(JSON.stringify(command));
+
+    // If we're in the context of a stringByEvaluatingJavaScriptFromString call,
+    // then the queue will be flushed when it returns; no need for a poke.
+    // Also, if there is already a command in the queue, then we've already
+    // poked the native side, so there is no reason to do so again.
+    if (!isInContextOfEvalJs && commandQueue.length == 1) {
+        pokeNative();
+    }
+}
+
+// CB-10530
+function proxyChanged() {
+    var cexec = cordovaExec();
+       
+    return (execProxy !== cexec && // proxy objects are different
+            iOSExec !== cexec      // proxy object is not the current iOSExec
+            );
+}
+
+// CB-10106
+function handleBridgeChange() {
+    if (proxyChanged()) {
+        var commandString = commandQueue.shift();
+        while(commandString) {
+            var command = JSON.parse(commandString);
+            var callbackId = command[0];
+            var service = command[1];
+            var action = command[2];
+            var actionArgs = command[3];
+            var callbacks = cordova.callbacks[callbackId] || {};
+            
+            execProxy(callbacks.success, callbacks.fail, service, action, actionArgs);
+            
+            commandString = commandQueue.shift();
+        };
+        return true;
+    }
+    
+    return false;
+}
+
+function pokeNative() {
+    // CB-5488 - Don't attempt to create iframe before document.body is available.
+    if (!document.body) {
+        setTimeout(pokeNative);
+        return;
+    }
+    
+    // Check if they've removed it from the DOM, and put it back if so.
+    if (execIframe && execIframe.contentWindow) {
+        execIframe.contentWindow.location = 'gap://ready';
+    } else {
+        execIframe = document.createElement('iframe');
+        execIframe.style.display = 'none';
+        execIframe.src = 'gap://ready';
+        document.body.appendChild(execIframe);
+    }
+    // Use a timer to protect against iframe being unloaded during the poke (CB-7735).
+    // This makes the bridge ~ 7% slower, but works around the poke getting lost
+    // when the iframe is removed from the DOM.
+    // An onunload listener could be used in the case where the iframe has just been
+    // created, but since unload events fire only once, it doesn't work in the normal
+    // case of iframe reuse (where unload will have already fired due to the attempted
+    // navigation of the page).
+    failSafeTimerId = setTimeout(function() {
+        if (commandQueue.length) {
+            // CB-10106 - flush the queue on bridge change
+            if (!handleBridgeChange()) {
+                pokeNative();
+             }
+        }
+    }, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
+}
+
+iOSExec.nativeFetchMessages = function() {
+    // Stop listing for window detatch once native side confirms poke.
+    if (failSafeTimerId) {
+        clearTimeout(failSafeTimerId);
+        failSafeTimerId = 0;
+    }
+    // Each entry in commandQueue is a JSON string already.
+    if (!commandQueue.length) {
+        return '';
+    }
+    var json = '[' + commandQueue.join(',') + ']';
+    commandQueue.length = 0;
+    return json;
+};
+
+iOSExec.nativeCallback = function(callbackId, status, message, keepCallback, debug) {
+    return iOSExec.nativeEvalAndFetch(function() {
+        var success = status === 0 || status === 1;
+        var args = convertMessageToArgsNativeToJs(message);
+        function nc2() {
+            cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
+        }
+        setTimeout(nc2, 0);
+    });
+};
+
+iOSExec.nativeEvalAndFetch = function(func) {
+    // This shouldn't be nested, but better to be safe.
+    isInContextOfEvalJs++;
+    try {
+        func();
+        return iOSExec.nativeFetchMessages();
+    } finally {
+        isInContextOfEvalJs--;
+    }
+};
+
+// Proxy the exec for bridge changes. See CB-10106
+
+function cordovaExec() {
+    var cexec = require('cordova/exec');
+    var cexec_valid = (typeof cexec.nativeFetchMessages === 'function') && (typeof cexec.nativeEvalAndFetch === 'function') && (typeof cexec.nativeCallback === 'function');
+    return (cexec_valid && execProxy !== cexec)? cexec : iOSExec;
+}
+
+function execProxy() {
+    cordovaExec().apply(null, arguments);
+};
+
+execProxy.nativeFetchMessages = function() {
+    return cordovaExec().nativeFetchMessages.apply(null, arguments);
+};
+
+execProxy.nativeEvalAndFetch = function() {
+    return cordovaExec().nativeEvalAndFetch.apply(null, arguments);
+};
+
+execProxy.nativeCallback = function() {
+    return cordovaExec().nativeCallback.apply(null, arguments);
+};
+
+module.exports = execProxy;
+
+});
+
+// file: src/common/exec/proxy.js
+define("cordova/exec/proxy", function(require, exports, module) {
+
+// internal map of proxy function
+var CommandProxyMap = {};
+
+module.exports = {
+
+    // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
+    add: function (id, proxyObj) {
+        console.log('adding proxy for ' + id);
+        CommandProxyMap[id] = proxyObj;
+        return proxyObj;
+    },
+
+    // cordova.commandProxy.remove("Accelerometer");
+    remove: function (id) {
+        var proxy = CommandProxyMap[id];
+        delete CommandProxyMap[id];
+        CommandProxyMap[id] = null;
+        return proxy;
+    },
+
+    get: function (service, action) {
+        return (CommandProxyMap[service] ? CommandProxyMap[service][action] : null);
+    }
+};
+
+});
+
+// file: src/common/init.js
+define("cordova/init", function(require, exports, module) {
+
+var channel = require('cordova/channel');
+var cordova = require('cordova');
+var modulemapper = require('cordova/modulemapper');
+var platform = require('cordova/platform');
+var pluginloader = require('cordova/pluginloader');
+var utils = require('cordova/utils');
+
+var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
+
+function logUnfiredChannels (arr) {
+    for (var i = 0; i < arr.length; ++i) {
+        if (arr[i].state !== 2) {
+            console.log('Channel not fired: ' + arr[i].type);
+        }
+    }
+}
+
+window.setTimeout(function () {
+    if (channel.onDeviceReady.state !== 2) {
+        console.log('deviceready has not fired after 5 seconds.');
+        logUnfiredChannels(platformInitChannelsArray);
+        logUnfiredChannels(channel.deviceReadyChannelsArray);
+    }
+}, 5000);
+
+// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
+// We replace it so that properties that can't be clobbered can instead be overridden.
+function replaceNavigator (origNavigator) {
+    var CordovaNavigator = function () {};
+    CordovaNavigator.prototype = origNavigator;
+    var newNavigator = new CordovaNavigator();
+    // This work-around really only applies to new APIs that are newer than Function.bind.
+    // Without it, APIs such as getGamepads() break.
+    if (CordovaNavigator.bind) {
+        for (var key in origNavigator) {
+            if (typeof origNavigator[key] === 'function') {
+                newNavigator[key] = origNavigator[key].bind(origNavigator);
+            } else {
+                (function (k) {
+                    utils.defineGetterSetter(newNavigator, key, function () {
+                        return origNavigator[k];
+                    });
+                })(key);
+            }
+        }
+    }
+    return newNavigator;
+}
+
+if (window.navigator) {
+    window.navigator = replaceNavigator(window.navigator);
+}
+
+if (!window.console) {
+    window.console = {
+        log: function () {}
+    };
+}
+if (!window.console.warn) {
+    window.console.warn = function (msg) {
+        this.log('warn: ' + msg);
+    };
+}
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onActivated = cordova.addDocumentEventHandler('activated');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+// Listen for DOMContentLoaded and notify our channel subscribers.
+if (document.readyState === 'complete' || document.readyState === 'interactive') {
+    channel.onDOMContentLoaded.fire();
+} else {
+    document.addEventListener('DOMContentLoaded', function () {
+        channel.onDOMContentLoaded.fire();
+    }, false);
+}
+
+// _nativeReady is global variable that the native side can set
+// to signify that the native code is ready. It is a global since
+// it may be called before any cordova JS is ready.
+if (window._nativeReady) {
+    channel.onNativeReady.fire();
+}
+
+modulemapper.clobbers('cordova', 'cordova');
+modulemapper.clobbers('cordova/exec', 'cordova.exec');
+modulemapper.clobbers('cordova/exec', 'Cordova.exec');
+
+// Call the platform-specific initialization.
+platform.bootstrap && platform.bootstrap();
+
+// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
+// The delay allows the attached modules to be defined before the plugin loader looks for them.
+setTimeout(function () {
+    pluginloader.load(function () {
+        channel.onPluginsReady.fire();
+    });
+}, 0);
+
+/**
+ * Create all cordova objects once native side is ready.
+ */
+channel.join(function () {
+    modulemapper.mapModules(window);
+
+    platform.initialize && platform.initialize();
+
+    // Fire event to notify that all objects are created
+    channel.onCordovaReady.fire();
+
+    // Fire onDeviceReady event once page has fully loaded, all
+    // constructors have run and cordova info has been received from native
+    // side.
+    channel.join(function () {
+        require('cordova').fireDocumentEvent('deviceready');
+    }, channel.deviceReadyChannelsArray);
+
+}, platformInitChannelsArray);
+
+});
+
+// file: src/common/init_b.js
+define("cordova/init_b", function(require, exports, module) {
+
+var channel = require('cordova/channel');
+var cordova = require('cordova');
+var modulemapper = require('cordova/modulemapper');
+var platform = require('cordova/platform');
+var pluginloader = require('cordova/pluginloader');
+var utils = require('cordova/utils');
+
+var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
+
+// setting exec
+cordova.exec = require('cordova/exec');
+
+function logUnfiredChannels (arr) {
+    for (var i = 0; i < arr.length; ++i) {
+        if (arr[i].state !== 2) {
+            console.log('Channel not fired: ' + arr[i].type);
+        }
+    }
+}
+
+window.setTimeout(function () {
+    if (channel.onDeviceReady.state !== 2) {
+        console.log('deviceready has not fired after 5 seconds.');
+        logUnfiredChannels(platformInitChannelsArray);
+        logUnfiredChannels(channel.deviceReadyChannelsArray);
+    }
+}, 5000);
+
+// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
+// We replace it so that properties that can't be clobbered can instead be overridden.
+function replaceNavigator (origNavigator) {
+    var CordovaNavigator = function () {};
+    CordovaNavigator.prototype = origNavigator;
+    var newNavigator = new CordovaNavigator();
+    // This work-around really only applies to new APIs that are newer than Function.bind.
+    // Without it, APIs such as getGamepads() break.
+    if (CordovaNavigator.bind) {
+        for (var key in origNavigator) {
+            if (typeof origNavigator[key] === 'function') {
+                newNavigator[key] = origNavigator[key].bind(origNavigator);
+            } else {
+                (function (k) {
+                    utils.defineGetterSetter(newNavigator, key, function () {
+                        return origNavigator[k];
+                    });
+                })(key);
+            }
+        }
+    }
+    return newNavigator;
+}
+if (window.navigator) {
+    window.navigator = replaceNavigator(window.navigator);
+}
+
+if (!window.console) {
+    window.console = {
+        log: function () {}
+    };
+}
+if (!window.console.warn) {
+    window.console.warn = function (msg) {
+        this.log('warn: ' + msg);
+    };
+}
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onActivated = cordova.addDocumentEventHandler('activated');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+// Listen for DOMContentLoaded and notify our channel subscribers.
+if (document.readyState === 'complete' || document.readyState === 'interactive') {
+    channel.onDOMContentLoaded.fire();
+} else {
+    document.addEventListener('DOMContentLoaded', function () {
+        channel.onDOMContentLoaded.fire();
+    }, false);
+}
+
+// _nativeReady is global variable that the native side can set
+// to signify that the native code is ready. It is a global since
+// it may be called before any cordova JS is ready.
+if (window._nativeReady) {
+    channel.onNativeReady.fire();
+}
+
+// Call the platform-specific initialization.
+platform.bootstrap && platform.bootstrap();
+
+// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
+// The delay allows the attached modules to be defined before the plugin loader looks for them.
+setTimeout(function () {
+    pluginloader.load(function () {
+        channel.onPluginsReady.fire();
+    });
+}, 0);
+
+/**
+ * Create all cordova objects once native side is ready.
+ */
+channel.join(function () {
+    modulemapper.mapModules(window);
+
+    platform.initialize && platform.initialize();
+
+    // Fire event to notify that all objects are created
+    channel.onCordovaReady.fire();
+
+    // Fire onDeviceReady event once page has fully loaded, all
+    // constructors have run and cordova info has been received from native
+    // side.
+    channel.join(function () {
+        require('cordova').fireDocumentEvent('deviceready');
+    }, channel.deviceReadyChannelsArray);
+
+}, platformInitChannelsArray);
+
+});
+
+// file: src/common/modulemapper.js
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder');
+var moduleMap = define.moduleMap; // eslint-disable-line no-undef
+var symbolList;
+var deprecationMap;
+
+exports.reset = function () {
+    symbolList = [];
+    deprecationMap = {};
+};
+
+function addEntry (strategy, moduleName, symbolPath, opt_deprecationMessage) {
+    if (!(moduleName in moduleMap)) {
+        throw new Error('Module ' + moduleName + ' does not exist.');
+    }
+    symbolList.push(strategy, moduleName, symbolPath);
+    if (opt_deprecationMessage) {
+        deprecationMap[symbolPath] = opt_deprecationMessage;
+    }
+}
+
+// Note: Android 2.3 does have Function.bind().
+exports.clobbers = function (moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.defaults = function (moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.runs = function (moduleName) {
+    addEntry('r', moduleName, null);
+};
+
+function prepareNamespace (symbolPath, context) {
+    if (!symbolPath) {
+        return context;
+    }
+    var parts = symbolPath.split('.');
+    var cur = context;
+    for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
+        cur = cur[part] = cur[part] || {};
+    }
+    return cur;
+}
+
+exports.mapModules = function (context) {
+    var origSymbols = {};
+    context.CDV_origSymbols = origSymbols;
+    for (var i = 0, len = symbolList.length; i < len; i += 3) {
+        var strategy = symbolList[i];
+        var moduleName = symbolList[i + 1];
+        var module = require(moduleName);
+        // <runs/>
+        if (strategy === 'r') {
+            continue;
+        }
+        var symbolPath = symbolList[i + 2];
+        var lastDot = symbolPath.lastIndexOf('.');
+        var namespace = symbolPath.substr(0, lastDot);
+        var lastName = symbolPath.substr(lastDot + 1);
+
+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
+        var parentObj = prepareNamespace(namespace, context);
+        var target = parentObj[lastName];
+
+        if (strategy === 'm' && target) {
+            builder.recursiveMerge(target, module);
+        } else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
+            if (!(symbolPath in origSymbols)) {
+                origSymbols[symbolPath] = target;
+            }
+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
+        }
+    }
+};
+
+exports.getOriginalSymbol = function (context, symbolPath) {
+    var origSymbols = context.CDV_origSymbols;
+    if (origSymbols && (symbolPath in origSymbols)) {
+        return origSymbols[symbolPath];
+    }
+    var parts = symbolPath.split('.');
+    var obj = context;
+    for (var i = 0; i < parts.length; ++i) {
+        obj = obj && obj[parts[i]];
+    }
+    return obj;
+};
+
+exports.reset();
+
+});
+
+// file: src/common/modulemapper_b.js
+define("cordova/modulemapper_b", function(require, exports, module) {
+
+var builder = require('cordova/builder');
+var symbolList = [];
+var deprecationMap;
+
+exports.reset = function () {
+    symbolList = [];
+    deprecationMap = {};
+};
+
+function addEntry (strategy, moduleName, symbolPath, opt_deprecationMessage) {
+    symbolList.push(strategy, moduleName, symbolPath);
+    if (opt_deprecationMessage) {
+        deprecationMap[symbolPath] = opt_deprecationMessage;
+    }
+}
+
+// Note: Android 2.3 does have Function.bind().
+exports.clobbers = function (moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.defaults = function (moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.runs = function (moduleName) {
+    addEntry('r', moduleName, null);
+};
+
+function prepareNamespace (symbolPath, context) {
+    if (!symbolPath) {
+        return context;
+    }
+    var parts = symbolPath.split('.');
+    var cur = context;
+    for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
+        cur = cur[part] = cur[part] || {};
+    }
+    return cur;
+}
+
+exports.mapModules = function (context) {
+    var origSymbols = {};
+    context.CDV_origSymbols = origSymbols;
+    for (var i = 0, len = symbolList.length; i < len; i += 3) {
+        var strategy = symbolList[i];
+        var moduleName = symbolList[i + 1];
+        var module = require(moduleName);
+        // <runs/>
+        if (strategy === 'r') {
+            continue;
+        }
+        var symbolPath = symbolList[i + 2];
+        var lastDot = symbolPath.lastIndexOf('.');
+        var namespace = symbolPath.substr(0, lastDot);
+        var lastName = symbolPath.substr(lastDot + 1);
+
+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
+        var parentObj = prepareNamespace(namespace, context);
+        var target = parentObj[lastName];
+
+        if (strategy === 'm' && target) {
+            builder.recursiveMerge(target, module);
+        } else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
+            if (!(symbolPath in origSymbols)) {
+                origSymbols[symbolPath] = target;
+            }
+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
+        }
+    }
+};
+
+exports.getOriginalSymbol = function (context, symbolPath) {
+    var origSymbols = context.CDV_origSymbols;
+    if (origSymbols && (symbolPath in origSymbols)) {
+        return origSymbols[symbolPath];
+    }
+    var parts = symbolPath.split('.');
+    var obj = context;
+    for (var i = 0; i < parts.length; ++i) {
+        obj = obj && obj[parts[i]];
+    }
+    return obj;
+};
+
+exports.reset();
+
+});
+
+// file: /Users/spindori/Documents/Cordova/cordova-ios/cordova-js-src/platform.js
+define("cordova/platform", function(require, exports, module) {
+
+module.exports = {
+    id: 'ios',
+    bootstrap: function () {
+        // Attach the console polyfill that is iOS-only to window.console
+        // see the file under plugin/ios/console.js
+        require('cordova/modulemapper').clobbers('cordova/plugin/ios/console', 'window.console');
+
+        require('cordova/channel').onNativeReady.fire();
+    }
+};
+
+});
+
+// file: /Users/spindori/Documents/Cordova/cordova-ios/cordova-js-src/plugin/ios/console.js
+define("cordova/plugin/ios/console", function(require, exports, module) {
+
+//------------------------------------------------------------------------------
+
+var logger = require('cordova/plugin/ios/logger');
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = logger.format.apply(logger.format, [].slice.call(arguments, 1));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrappedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrappedOrigCall(WinConsole[key], console[key]);
+    }
+}
+
+});
+
+// file: /Users/spindori/Documents/Cordova/cordova-ios/cordova-js-src/plugin/ios/logger.js
+define("cordova/plugin/ios/logger", function(require, exports, module) {
+
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+
+var UseConsole   = false;
+var UseLogger    = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+var originalConsole = console;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  E.g., the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Getter/Setter for the useLogger functionality
+ *
+ * When useLogger is true, the logger will log via the
+ * native Logger plugin.
+ */
+logger.useLogger = function (value) {
+    // Enforce boolean
+    if (arguments.length) UseLogger = !!value;
+    return UseLogger;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+// return the correct formatString for an object
+function formatStringForMessage(message) {
+    return (typeof message === "string") ? "" : "%o"; 
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 1);
+    var fmtString = formatStringForMessage(formatArgs[0]);
+    if (fmtString.length > 0){
+        formatArgs.unshift(fmtString); // add formatString
+    }
+
+    var message    = logger.format.apply(logger.format, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // Log using the native logger if that is enabled
+    if (UseLogger) {
+        exec(null, null, "Console", "logLevel", [level, message]);
+    }
+
+    // Log using the console if that is enabled
+    if (UseConsole) {
+        // make sure console is not using logger
+        if (console.useLogger()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+
+        // log to the console
+        switch (level) {
+            case logger.LOG:   originalConsole.log(message); break;
+            case logger.ERROR: originalConsole.log("ERROR: " + message); break;
+            case logger.WARN:  originalConsole.log("WARN: "  + message); break;
+            case logger.INFO:  originalConsole.log("INFO: "  + message); break;
+            case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;
+        }
+    }
+};
+
+
+/**
+ * Formats a string and arguments following it ala console.log()
+ *
+ * Any remaining arguments will be appended to the formatted string.
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+logger.format = function(formatString, args) {
+    return __format(arguments[0], [].slice.call(arguments,1)).join(' ');
+};
+
+
+//------------------------------------------------------------------------------
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * Returns an array containing the formatted string and any remaining
+ * arguments.
+ */
+function __format(formatString, args) {
+    if (formatString === null || formatString === undefined) return [""];
+    if (arguments.length == 1) return [formatString.toString()];
+
+    if (typeof formatString != "string")
+        formatString = formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var match = pattern.exec(rest);
+        if (!match) break;
+
+        var arg   = args.shift();
+        rest = match[3];
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(__formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    var remainingArgs = [].slice.call(args);
+    remainingArgs.unshift(result.join(''));
+    return remainingArgs;
+}
+
+function __formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+
+//------------------------------------------------------------------------------
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);
+
+});
+
+// file: src/common/pluginloader.js
+define("cordova/pluginloader", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+// Helper function to inject a <script> tag.
+// Exported for testing.
+exports.injectScript = function (url, onload, onerror) {
+    var script = document.createElement('script');
+    // onload fires even when script fails loads with an error.
+    script.onload = onload;
+    // onerror fires for malformed URLs.
+    script.onerror = onerror;
+    script.src = url;
+    document.head.appendChild(script);
+};
+
+function injectIfNecessary (id, url, onload, onerror) {
+    onerror = onerror || onload;
+    if (id in define.moduleMap) { // eslint-disable-line no-undef
+        onload();
+    } else {
+        exports.injectScript(url, function () {
+            if (id in define.moduleMap) { // eslint-disable-line no-undef
+                onload();
+            } else {
+                onerror();
+            }
+        }, onerror);
+    }
+}
+
+function onScriptLoadingComplete (moduleList, finishPluginLoading) {
+    // Loop through all the plugins and then through their clobbers and merges.
+    for (var i = 0, module; module = moduleList[i]; i++) { // eslint-disable-line no-cond-assign
+        if (module.clobbers && module.clobbers.length) {
+            for (var j = 0; j < module.clobbers.length; j++) {
+                modulemapper.clobbers(module.id, module.clobbers[j]);
+            }
+        }
+
+        if (module.merges && module.merges.length) {
+            for (var k = 0; k < module.merges.length; k++) {
+                modulemapper.merges(module.id, module.merges[k]);
+            }
+        }
+
+        // Finally, if runs is truthy we want to simply require() the module.
+        if (module.runs) {
+            modulemapper.runs(module.id);
+        }
+    }
+
+    finishPluginLoading();
+}
+
+// Handler for the cordova_plugins.js content.
+// See plugman's plugin_loader.js for the details of this object.
+// This function is only called if the really is a plugins array that isn't empty.
+// Otherwise the onerror response handler will just call finishPluginLoading().
+function handlePluginsObject (path, moduleList, finishPluginLoading) {
+    // Now inject the scripts.
+    var scriptCounter = moduleList.length;
+
+    if (!scriptCounter) {
+        finishPluginLoading();
+        return;
+    }
+    function scriptLoadedCallback () {
+        if (!--scriptCounter) {
+            onScriptLoadingComplete(moduleList, finishPluginLoading);
+        }
+    }
+
+    for (var i = 0; i < moduleList.length; i++) {
+        injectIfNecessary(moduleList[i].id, path + moduleList[i].file, scriptLoadedCallback);
+    }
+}
+
+function findCordovaPath () {
+    var path = null;
+    var scripts = document.getElementsByTagName('script');
+    var term = '/cordova.js';
+    for (var n = scripts.length - 1; n > -1; n--) {
+        var src = scripts[n].src.replace(/\?.*$/, ''); // Strip any query param (CB-6007).
+        if (src.indexOf(term) === (src.length - term.length)) {
+            path = src.substring(0, src.length - term.length) + '/';
+            break;
+        }
+    }
+    return path;
+}
+
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+exports.load = function (callback) {
+    var pathPrefix = findCordovaPath();
+    if (pathPrefix === null) {
+        console.log('Could not find cordova.js script tag. Plugin loading may fail.');
+        pathPrefix = '';
+    }
+    injectIfNecessary('cordova/plugin_list', pathPrefix + 'cordova_plugins.js', function () {
+        var moduleList = require('cordova/plugin_list');
+        handlePluginsObject(pathPrefix, moduleList, callback);
+    }, callback);
+};
+
+});
+
+// file: src/common/pluginloader_b.js
+define("cordova/pluginloader_b", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+// Handler for the cordova_plugins.js content.
+// See plugman's plugin_loader.js for the details of this object.
+function handlePluginsObject (moduleList) {
+    // if moduleList is not defined or empty, we've nothing to do
+    if (!moduleList || !moduleList.length) {
+        return;
+    }
+
+    // Loop through all the modules and then through their clobbers and merges.
+    for (var i = 0, module; module = moduleList[i]; i++) { // eslint-disable-line no-cond-assign
+        if (module.clobbers && module.clobbers.length) {
+            for (var j = 0; j < module.clobbers.length; j++) {
+                modulemapper.clobbers(module.id, module.clobbers[j]);
+            }
+        }
+
+        if (module.merges && module.merges.length) {
+            for (var k = 0; k < module.merges.length; k++) {
+                modulemapper.merges(module.id, module.merges[k]);
+            }
+        }
+
+        // Finally, if runs is truthy we want to simply require() the module.
+        if (module.runs) {
+            modulemapper.runs(module.id);
+        }
+    }
+}
+
+// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
+// but the method accepts callback to be compatible with non-browserify flow.
+// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
+// no plugins to load, or they are all done.
+exports.load = function (callback) {
+    var moduleList = require('cordova/plugin_list');
+    handlePluginsObject(moduleList);
+
+    callback();
+};
+
+});
+
+// file: src/common/urlutil.js
+define("cordova/urlutil", function(require, exports, module) {
+
+/**
+ * For already absolute URLs, returns what is passed in.
+ * For relative URLs, converts them to absolute ones.
+ */
+exports.makeAbsolute = function makeAbsolute (url) {
+    var anchorEl = document.createElement('a');
+    anchorEl.href = url;
+    return anchorEl.href;
+};
+
+});
+
+// file: src/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+
+var utils = exports;
+
+/**
+ * Defines a property getter / setter for obj[key].
+ */
+utils.defineGetterSetter = function (obj, key, getFunc, opt_setFunc) {
+    if (Object.defineProperty) {
+        var desc = {
+            get: getFunc,
+            configurable: true
+        };
+        if (opt_setFunc) {
+            desc.set = opt_setFunc;
+        }
+        Object.defineProperty(obj, key, desc);
+    } else {
+        obj.__defineGetter__(key, getFunc);
+        if (opt_setFunc) {
+            obj.__defineSetter__(key, opt_setFunc);
+        }
+    }
+};
+
+/**
+ * Defines a property getter for obj[key].
+ */
+utils.defineGetter = utils.defineGetterSetter;
+
+utils.arrayIndexOf = function (a, item) {
+    if (a.indexOf) {
+        return a.indexOf(item);
+    }
+    var len = a.length;
+    for (var i = 0; i < len; ++i) {
+        if (a[i] === item) {
+            return i;
+        }
+    }
+    return -1;
+};
+
+/**
+ * Returns whether the item was found in the array.
+ */
+utils.arrayRemove = function (a, item) {
+    var index = utils.arrayIndexOf(a, item);
+    if (index !== -1) {
+        a.splice(index, 1);
+    }
+    return index !== -1;
+};
+
+utils.typeName = function (val) {
+    return Object.prototype.toString.call(val).slice(8, -1);
+};
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = Array.isArray ||
+                function (a) { return utils.typeName(a) === 'Array'; };
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function (d) {
+    return (d instanceof Date);
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function (obj) {
+    if (!obj || typeof obj === 'function' || utils.isDate(obj) || typeof obj !== 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if (utils.isArray(obj)) {
+        retVal = [];
+        for (i = 0; i < obj.length; ++i) {
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for (i in obj) {
+        // https://issues.apache.org/jira/browse/CB-11522 'unknown' type may be returned in
+        // custom protocol activation case on Windows Phone 8.1 causing "No such interface supported" exception
+        // on cloning.
+        if ((!(i in retVal) || retVal[i] !== obj[i]) && typeof obj[i] !== 'undefined' && typeof obj[i] !== 'unknown') { // eslint-disable-line valid-typeof
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrapped version of the function
+ */
+utils.close = function (context, func, params) {
+    return function () {
+        var args = params || arguments;
+        return func.apply(context, args);
+    };
+};
+
+// ------------------------------------------------------------------------------
+function UUIDcreatePart (length) {
+    var uuidpart = '';
+    for (var i = 0; i < length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length === 1) {
+            uuidchar = '0' + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function () {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function () {
+    // proxy used to establish prototype chain
+    var F = function () {};
+    // extend Child from Parent
+    return function (Child, Parent) {
+
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function (msg) {
+    if (window.alert) {
+        window.alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+});
+
+window.cordova = require('cordova');
+// file: src/scripts/bootstrap.js
+
+require('cordova/init');
+
+})();

+ 120 - 0
platforms/ios/www/cordova_plugins.js

@@ -0,0 +1,120 @@
+cordova.define('cordova/plugin_list', function(require, exports, module) {
+module.exports = [
+  {
+    "id": "cordova-plugin-camera.Camera",
+    "file": "plugins/cordova-plugin-camera/www/CameraConstants.js",
+    "pluginId": "cordova-plugin-camera",
+    "clobbers": [
+      "Camera"
+    ]
+  },
+  {
+    "id": "cordova-plugin-camera.CameraPopoverOptions",
+    "file": "plugins/cordova-plugin-camera/www/CameraPopoverOptions.js",
+    "pluginId": "cordova-plugin-camera",
+    "clobbers": [
+      "CameraPopoverOptions"
+    ]
+  },
+  {
+    "id": "cordova-plugin-camera.camera",
+    "file": "plugins/cordova-plugin-camera/www/Camera.js",
+    "pluginId": "cordova-plugin-camera",
+    "clobbers": [
+      "navigator.camera"
+    ]
+  },
+  {
+    "id": "cordova-plugin-camera.CameraPopoverHandle",
+    "file": "plugins/cordova-plugin-camera/www/ios/CameraPopoverHandle.js",
+    "pluginId": "cordova-plugin-camera",
+    "clobbers": [
+      "CameraPopoverHandle"
+    ]
+  },
+  {
+    "id": "cordova-plugin-handheld.Handheld",
+    "file": "plugins/cordova-plugin-handheld/www/Handheld.js",
+    "pluginId": "cordova-plugin-handheld",
+    "clobbers": [
+      "Handheld"
+    ]
+  },
+  {
+    "id": "cordova-plugin-navigationbar.navigationbar",
+    "file": "plugins/cordova-plugin-navigationbar/www/navigationbar.js",
+    "pluginId": "cordova-plugin-navigationbar",
+    "clobbers": [
+      "cordova.plugins.navigationbar"
+    ]
+  },
+  {
+    "id": "cordova-plugin-pgyer.pgyer",
+    "file": "plugins/cordova-plugin-pgyer/www/pgyer.js",
+    "pluginId": "cordova-plugin-pgyer",
+    "clobbers": [
+      "cordova.plugins.pgyer"
+    ]
+  },
+  {
+    "id": "cordova-plugin-splashscreen.SplashScreen",
+    "file": "plugins/cordova-plugin-splashscreen/www/splashscreen.js",
+    "pluginId": "cordova-plugin-splashscreen",
+    "clobbers": [
+      "navigator.splashscreen"
+    ]
+  },
+  {
+    "id": "cordova-plugin-tencent-bg-location.tencentBgLocation",
+    "file": "plugins/cordova-plugin-tencent-bg-location/www/tencentBgLocation.js",
+    "pluginId": "cordova-plugin-tencent-bg-location",
+    "clobbers": [
+      "tencentBgLocation"
+    ]
+  },
+  {
+    "id": "cordova-plugin-wkwebview-engine.ios-wkwebview-exec",
+    "file": "plugins/cordova-plugin-wkwebview-engine/src/www/ios/ios-wkwebview-exec.js",
+    "pluginId": "cordova-plugin-wkwebview-engine",
+    "clobbers": [
+      "cordova.exec"
+    ]
+  },
+  {
+    "id": "cordova-plugin-wkwebview-engine.ios-wkwebview",
+    "file": "plugins/cordova-plugin-wkwebview-engine/src/www/ios/ios-wkwebview.js",
+    "pluginId": "cordova-plugin-wkwebview-engine",
+    "clobbers": [
+      "window.WkWebView"
+    ]
+  },
+  {
+    "id": "cordova-plugin-x-toast.Toast",
+    "file": "plugins/cordova-plugin-x-toast/www/Toast.js",
+    "pluginId": "cordova-plugin-x-toast",
+    "clobbers": [
+      "window.plugins.toast"
+    ]
+  },
+  {
+    "id": "cordova-plugin-x-toast.tests",
+    "file": "plugins/cordova-plugin-x-toast/test/tests.js",
+    "pluginId": "cordova-plugin-x-toast"
+  }
+];
+module.exports.metadata = 
+// TOP OF METADATA
+{
+  "cordova-plugin-camera": "4.0.2",
+  "cordova-plugin-handheld": "1.0.0",
+  "cordova-plugin-navigationbar": "1.0.0",
+  "cordova-plugin-pgyer": "1.0.0",
+  "cordova-plugin-remote-injection": "0.5.2",
+  "cordova-plugin-splashscreen": "5.0.1",
+  "cordova-plugin-tencent-bg-location": "1.0.0",
+  "cordova-plugin-whitelist": "1.3.3",
+  "cordova-plugin-wkwebview-engine": "1.1.4",
+  "cordova-plugin-x-toast": "2.6.0"
+};
+// BOTTOM OF METADATA
+});

+ 115 - 0
platforms/ios/www/css/index.css

@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+* {
+    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
+    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
+    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
+    background-color:#E4E4E4;
+    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, #A7A7A7),
+        color-stop(0.51, #E4E4E4)
+    );
+    background-attachment:fixed;
+    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+    font-size:12px;
+    height:100%;
+    margin:0px;
+    padding:0px;
+    text-transform:uppercase;
+    width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+    position:absolute;             /* position in the center of the screen */
+    left:50%;
+    top:50%;
+    height:50px;                   /* text area height */
+    width:225px;                   /* text area width */
+    text-align:center;
+    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
+    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
+                                   /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+    .app {
+        background-position:left center;
+        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
+        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
+                                      /* offset horizontal: half of image width and text area width */
+    }
+}
+
+h1 {
+    font-size:24px;
+    font-weight:normal;
+    margin:0px;
+    overflow:visible;
+    padding:0px;
+    text-align:center;
+}
+
+.event {
+    border-radius:4px;
+    -webkit-border-radius:4px;
+    color:#FFFFFF;
+    font-size:12px;
+    margin:0px 30px;
+    padding:2px 0px;
+}
+
+.event.listening {
+    background-color:#333333;
+    display:block;
+}
+
+.event.received {
+    background-color:#4B946A;
+    display:none;
+}
+
+@keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+@-webkit-keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+.blink {
+    animation:fade 3000ms infinite;
+    -webkit-animation:fade 3000ms infinite;
+}

BIN
platforms/ios/www/img/logo.png


+ 49 - 0
platforms/ios/www/index.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<html>
+    <head>
+        <!--
+        Customize this policy to fit your own app's needs. For more guidance, see:
+            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
+        Some notes:
+            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
+            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
+            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
+                * Enable inline JS: add 'unsafe-inline' to default-src
+        -->
+        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
+        <meta name="format-detection" content="telephone=no">
+        <meta name="msapplication-tap-highlight" content="no">
+        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
+        <link rel="stylesheet" type="text/css" href="css/index.css">
+        <title>Hello World</title>
+    </head>
+    <body>
+        <div class="app">
+            <h1>Apache Cordova</h1>
+            <div id="deviceready" class="blink">
+                <p class="event listening">Connecting to Device</p>
+                <p class="event received">Device is Ready</p>
+            </div>
+        </div>
+        <script type="text/javascript" src="cordova.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+    </body>
+</html>

+ 46 - 0
platforms/ios/www/js/index.js

@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var app = {
+    // Application Constructor
+    initialize: function() {
+        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
+    },
+
+    // deviceready Event Handler
+    //
+    // Bind any cordova events here. Common events are:
+    // 'pause', 'resume', etc.
+    onDeviceReady: function() {
+        this.receivedEvent('deviceready');
+    },
+
+    // Update DOM on a Received Event
+    receivedEvent: function(id) {
+        var parentElement = document.getElementById(id);
+        var listeningElement = parentElement.querySelector('.listening');
+        var receivedElement = parentElement.querySelector('.received');
+
+        listeningElement.setAttribute('style', 'display:none;');
+        receivedElement.setAttribute('style', 'display:block;');
+
+        console.log('Received Event: ' + id);
+    }
+};
+
+app.initialize();

+ 1 - 0
platforms/ios/www/milk.html

@@ -0,0 +1 @@
+<!DOCTYPE html><html><head><meta charset=utf-8><meta name=format-detection content="telephone=no"><meta name=apple-mobile-web-app-capable content=yes><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><script src=http://res.wx.qq.com/open/js/jweixin-1.2.0.js></script><script type=text/javascript src=cordova.js></script><title>光明</title></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.ad72cfdf70bd6f7519e0.js></script><script type=text/javascript src=/static/js/vendor.10d164ea32522da5baa8.js></script><script type=text/javascript src=/static/js/app.c7a55afb3489f2936469.js></script></body></html>

+ 188 - 0
platforms/ios/www/plugins/cordova-plugin-camera/www/Camera.js

@@ -0,0 +1,188 @@
+cordova.define("cordova-plugin-camera.camera", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var argscheck = require('cordova/argscheck');
+var exec = require('cordova/exec');
+var Camera = require('./Camera');
+// XXX: commented out
+// CameraPopoverHandle = require('./CameraPopoverHandle');
+
+/**
+ * @namespace navigator
+ */
+
+/**
+ * @exports camera
+ */
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+    cameraExport[key] = Camera[key];
+}
+
+/**
+ * Callback function that provides an error message.
+ * @callback module:camera.onError
+ * @param {string} message - The message is provided by the device's native code.
+ */
+
+/**
+ * Callback function that provides the image data.
+ * @callback module:camera.onSuccess
+ * @param {string} imageData - Base64 encoding of the image data, _or_ the image file URI, depending on [`cameraOptions`]{@link module:camera.CameraOptions} in effect.
+ * @example
+ * // Show image
+ * //
+ * function cameraCallback(imageData) {
+ *    var image = document.getElementById('myImage');
+ *    image.src = "data:image/jpeg;base64," + imageData;
+ * }
+ */
+
+/**
+ * Optional parameters to customize the camera settings.
+ * * [Quirks](#CameraOptions-quirks)
+ * @typedef module:camera.CameraOptions
+ * @type {Object}
+ * @property {number} [quality=50] - Quality of the saved image, expressed as a range of 0-100, where 100 is typically full resolution with no loss from file compression. (Note that information about the camera's resolution is unavailable.)
+ * @property {module:Camera.DestinationType} [destinationType=FILE_URI] - Choose the format of the return value.
+ * @property {module:Camera.PictureSourceType} [sourceType=CAMERA] - Set the source of the picture.
+ * @property {Boolean} [allowEdit=true] - Allow simple editing of image before selection.
+ * @property {module:Camera.EncodingType} [encodingType=JPEG] - Choose the  returned image file's encoding.
+ * @property {number} [targetWidth] - Width in pixels to scale image. Must be used with `targetHeight`. Aspect ratio remains constant.
+ * @property {number} [targetHeight] - Height in pixels to scale image. Must be used with `targetWidth`. Aspect ratio remains constant.
+ * @property {module:Camera.MediaType} [mediaType=PICTURE] - Set the type of media to select from.  Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`.
+ * @property {Boolean} [correctOrientation] - Rotate the image to correct for the orientation of the device during capture.
+ * @property {Boolean} [saveToPhotoAlbum] - Save the image to the photo album on the device after capture.
+ * @property {module:CameraPopoverOptions} [popoverOptions] - iOS-only options that specify popover location in iPad.
+ * @property {module:Camera.Direction} [cameraDirection=BACK] - Choose the camera to use (front- or back-facing).
+ */
+
+/**
+ * @description Takes a photo using the camera, or retrieves a photo from the device's
+ * image gallery.  The image is passed to the success callback as a
+ * Base64-encoded `String`, or as the URI for the image file.
+ *
+ * The `camera.getPicture` function opens the device's default camera
+ * application that allows users to snap pictures by default - this behavior occurs,
+ * when `Camera.sourceType` equals [`Camera.PictureSourceType.CAMERA`]{@link module:Camera.PictureSourceType}.
+ * Once the user snaps the photo, the camera application closes and the application is restored.
+ *
+ * If `Camera.sourceType` is `Camera.PictureSourceType.PHOTOLIBRARY` or
+ * `Camera.PictureSourceType.SAVEDPHOTOALBUM`, then a dialog displays
+ * that allows users to select an existing image.
+ *
+ * The return value is sent to the [`cameraSuccess`]{@link module:camera.onSuccess} callback function, in
+ * one of the following formats, depending on the specified
+ * `cameraOptions`:
+ *
+ * - A `String` containing the Base64-encoded photo image.
+ * - A `String` representing the image file location on local storage (default).
+ *
+ * You can do whatever you want with the encoded image or URI, for
+ * example:
+ *
+ * - Render the image in an `<img>` tag, as in the example below
+ * - Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
+ * - Post the data to a remote server
+ *
+ * __NOTE__: Photo resolution on newer devices is quite good. Photos
+ * selected from the device's gallery are not downscaled to a lower
+ * quality, even if a `quality` parameter is specified.  To avoid common
+ * memory problems, set `Camera.destinationType` to `FILE_URI` rather
+ * than `DATA_URL`.
+ *
+ * __Supported Platforms__
+ *
+ * - Android
+ * - BlackBerry
+ * - Browser
+ * - Firefox
+ * - FireOS
+ * - iOS
+ * - Windows
+ * - WP8
+ * - Ubuntu
+ *
+ * More examples [here](#camera-getPicture-examples). Quirks [here](#camera-getPicture-quirks).
+ *
+ * @example
+ * navigator.camera.getPicture(cameraSuccess, cameraError, cameraOptions);
+ * @param {module:camera.onSuccess} successCallback
+ * @param {module:camera.onError} errorCallback
+ * @param {module:camera.CameraOptions} options CameraOptions
+ */
+cameraExport.getPicture = function (successCallback, errorCallback, options) {
+    argscheck.checkArgs('fFO', 'Camera.getPicture', arguments);
+    options = options || {};
+    var getValue = argscheck.getValue;
+
+    var quality = getValue(options.quality, 50);
+    var destinationType = getValue(options.destinationType, Camera.DestinationType.FILE_URI);
+    var sourceType = getValue(options.sourceType, Camera.PictureSourceType.CAMERA);
+    var targetWidth = getValue(options.targetWidth, -1);
+    var targetHeight = getValue(options.targetHeight, -1);
+    var encodingType = getValue(options.encodingType, Camera.EncodingType.JPEG);
+    var mediaType = getValue(options.mediaType, Camera.MediaType.PICTURE);
+    var allowEdit = !!options.allowEdit;
+    var correctOrientation = !!options.correctOrientation;
+    var saveToPhotoAlbum = !!options.saveToPhotoAlbum;
+    var popoverOptions = getValue(options.popoverOptions, null);
+    var cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
+
+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+        mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
+
+    exec(successCallback, errorCallback, 'Camera', 'takePicture', args);
+    // XXX: commented out
+    // return new CameraPopoverHandle();
+};
+
+/**
+ * Removes intermediate image files that are kept in temporary storage
+ * after calling [`camera.getPicture`]{@link module:camera.getPicture}. Applies only when the value of
+ * `Camera.sourceType` equals `Camera.PictureSourceType.CAMERA` and the
+ * `Camera.destinationType` equals `Camera.DestinationType.FILE_URI`.
+ *
+ * __Supported Platforms__
+ *
+ * - iOS
+ *
+ * @example
+ * navigator.camera.cleanup(onSuccess, onFail);
+ *
+ * function onSuccess() {
+ *     console.log("Camera cleanup success.")
+ * }
+ *
+ * function onFail(message) {
+ *     alert('Failed because: ' + message);
+ * }
+ */
+cameraExport.cleanup = function (successCallback, errorCallback) {
+    exec(successCallback, errorCallback, 'Camera', 'cleanup', []);
+};
+
+module.exports = cameraExport;
+
+});

+ 104 - 0
platforms/ios/www/plugins/cordova-plugin-camera/www/CameraConstants.js

@@ -0,0 +1,104 @@
+cordova.define("cordova-plugin-camera.Camera", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * @module Camera
+ */
+module.exports = {
+    /**
+     * @description
+     * Defines the output format of `Camera.getPicture` call.
+     * _Note:_ On iOS passing `DestinationType.NATIVE_URI` along with
+     * `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM` will
+     * disable any image modifications (resize, quality change, cropping, etc.) due
+     * to implementation specific.
+     *
+     * @enum {number}
+     */
+    DestinationType: {
+        /** Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI or NATIVE_URI if possible */
+        DATA_URL: 0,
+        /** Return file uri (content://media/external/images/media/2 for Android) */
+        FILE_URI: 1,
+        /** Return native uri (eg. asset-library://... for iOS) */
+        NATIVE_URI: 2
+    },
+    /**
+     * @enum {number}
+     */
+    EncodingType: {
+        /** Return JPEG encoded image */
+        JPEG: 0,
+        /** Return PNG encoded image */
+        PNG: 1
+    },
+    /**
+     * @enum {number}
+     */
+    MediaType: {
+        /** Allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType */
+        PICTURE: 0,
+        /** Allow selection of video only, ONLY RETURNS URL */
+        VIDEO: 1,
+        /** Allow selection from all media types */
+        ALLMEDIA: 2
+    },
+    /**
+     * @description
+     * Defines the output format of `Camera.getPicture` call.
+     * _Note:_ On iOS passing `PictureSourceType.PHOTOLIBRARY` or `PictureSourceType.SAVEDPHOTOALBUM`
+     * along with `DestinationType.NATIVE_URI` will disable any image modifications (resize, quality
+     * change, cropping, etc.) due to implementation specific.
+     *
+     * @enum {number}
+     */
+    PictureSourceType: {
+        /** Choose image from the device's photo library (same as SAVEDPHOTOALBUM for Android) */
+        PHOTOLIBRARY: 0,
+        /** Take picture from camera */
+        CAMERA: 1,
+        /** Choose image only from the device's Camera Roll album (same as PHOTOLIBRARY for Android) */
+        SAVEDPHOTOALBUM: 2
+    },
+    /**
+     * Matches iOS UIPopoverArrowDirection constants to specify arrow location on popover.
+     * @enum {number}
+     */
+    PopoverArrowDirection: {
+        ARROW_UP: 1,
+        ARROW_DOWN: 2,
+        ARROW_LEFT: 4,
+        ARROW_RIGHT: 8,
+        ARROW_ANY: 15
+    },
+    /**
+     * @enum {number}
+     */
+    Direction: {
+        /** Use the back-facing camera */
+        BACK: 0,
+        /** Use the front-facing camera */
+        FRONT: 1
+    }
+};
+
+});

+ 55 - 0
platforms/ios/www/plugins/cordova-plugin-camera/www/CameraPopoverOptions.js

@@ -0,0 +1,55 @@
+cordova.define("cordova-plugin-camera.CameraPopoverOptions", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var Camera = require('./Camera');
+
+/**
+ * @namespace navigator
+ */
+
+/**
+ * iOS-only parameters that specify the anchor element location and arrow
+ * direction of the popover when selecting images from an iPad's library
+ * or album.
+ * Note that the size of the popover may change to adjust to the
+ * direction of the arrow and orientation of the screen.  Make sure to
+ * account for orientation changes when specifying the anchor element
+ * location.
+ * @module CameraPopoverOptions
+ * @param {Number} [x=0] - x pixel coordinate of screen element onto which to anchor the popover.
+ * @param {Number} [y=32] - y pixel coordinate of screen element onto which to anchor the popover.
+ * @param {Number} [width=320] - width, in pixels, of the screen element onto which to anchor the popover.
+ * @param {Number} [height=480] - height, in pixels, of the screen element onto which to anchor the popover.
+ * @param {module:Camera.PopoverArrowDirection} [arrowDir=ARROW_ANY] - Direction the arrow on the popover should point.
+ */
+var CameraPopoverOptions = function (x, y, width, height, arrowDir) {
+    // information of rectangle that popover should be anchored to
+    this.x = x || 0;
+    this.y = y || 32;
+    this.width = width || 320;
+    this.height = height || 480;
+    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+
+});

+ 69 - 0
platforms/ios/www/plugins/cordova-plugin-camera/www/ios/CameraPopoverHandle.js

@@ -0,0 +1,69 @@
+cordova.define("cordova-plugin-camera.CameraPopoverHandle", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+
+/**
+ * @namespace navigator
+ */
+
+/**
+ * A handle to an image picker popover.
+ *
+ * __Supported Platforms__
+ *
+ * - iOS
+ *
+ * @example
+ * navigator.camera.getPicture(onSuccess, onFail,
+ * {
+ *     destinationType: Camera.DestinationType.FILE_URI,
+ *     sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
+ *     popoverOptions: new CameraPopoverOptions(300, 300, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY)
+ * });
+ *
+ * // Reposition the popover if the orientation changes.
+ * window.onorientationchange = function() {
+ *     var cameraPopoverHandle = new CameraPopoverHandle();
+ *     var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
+ *     cameraPopoverHandle.setPosition(cameraPopoverOptions);
+ * }
+ * @module CameraPopoverHandle
+ */
+var CameraPopoverHandle = function () {
+    /**
+     * Can be used to reposition the image selection dialog,
+     * for example, when the device orientation changes.
+     * @memberof CameraPopoverHandle
+     * @instance
+     * @method setPosition
+     * @param {module:CameraPopoverOptions} popoverOptions
+     */
+    this.setPosition = function (popoverOptions) {
+        var args = [ popoverOptions ];
+        exec(null, null, 'Camera', 'repositionPopover', args);
+    };
+};
+
+module.exports = CameraPopoverHandle;
+
+});

+ 46 - 0
platforms/ios/www/plugins/cordova-plugin-handheld/www/Handheld.js

@@ -0,0 +1,46 @@
+cordova.define("cordova-plugin-handheld.Handheld", function(require, exports, module) {
+var exec = require("cordova/exec");
+
+exports.scanCode = function(success, error) {
+    exec(success, error, "Handheld", "scanCode", []);
+};
+exports.stopScan = function(success, error) {
+    exec(success, error, "Handheld", "stopScan", []);
+};
+exports.readTag = function(success, error, options) {
+    exec(success, error, "Handheld", "readTag", [options]);
+};
+exports.stopRead = function(success, error) {
+    exec(success, error, "Handheld", "stopRead", []);
+};
+exports.getPicture = function(success, error, cameraOptions) {
+    exec(
+        function() {
+            navigator.camera.getPicture(
+                function(res) {
+                    exec(function() {}, function() {}, "Handheld", "resume", []);
+                    try {
+                        success(res);
+                    } catch (e) {}
+                },
+                function(err1) {
+                    exec(function() {}, function() {}, "Handheld", "resume", []);
+                    try {
+                        error(err1);
+                    } catch (e) {}
+                },
+                cameraOptions
+            );
+        },
+        function(err) {
+            try {
+                error(err);
+            } catch (e) {}
+        },
+        "Handheld",
+        "pause",
+        []
+    );
+};
+
+});

+ 32 - 0
platforms/ios/www/plugins/cordova-plugin-navigationbar/www/navigationbar.js

@@ -0,0 +1,32 @@
+cordova.define("cordova-plugin-navigationbar.navigationbar", function(require, exports, module) {
+var exec = require("cordova/exec");
+
+exports.coolMethod = function(arg0, success, error) {
+    exec(success, error, "navigationbar", "coolMethod", [arg0]);
+};
+exports.create = function() {
+    exec(function() {}, function() {}, "navigationbar", "create", [{}]);
+};
+exports.setBg = function(color) {
+    exec(function() {}, function() {}, "navigationbar", "setBg", [color]);
+};
+exports.setGradientBg = function(color1, color2) {
+    exec(function() {}, function() {}, "navigationbar", "setGradientBg", [
+        color1,
+        color2
+    ]);
+};
+exports.setStyle = function(style) {
+    exec(function() {}, function() {}, "navigationbar", "setStyle", [style]);
+};
+exports.setTitle = function(title) {
+    exec(function() {}, function() {}, "navigationbar", "setTitle", [title]);
+};
+exports.showBack = function(title) {
+    exec(function() {}, function() {}, "navigationbar", "showBack", [""]);
+};
+exports.hideBack = function(title) {
+    exec(function() {}, function() {}, "navigationbar", "hideBack", [""]);
+};
+
+});

+ 8 - 0
platforms/ios/www/plugins/cordova-plugin-pgyer/www/pgyer.js

@@ -0,0 +1,8 @@
+cordova.define("cordova-plugin-pgyer.pgyer", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+exports.coolMethod = function (arg0, success, error) {
+    exec(success, error, 'pgyer', 'coolMethod', [arg0]);
+};
+
+});

+ 36 - 0
platforms/ios/www/plugins/cordova-plugin-splashscreen/www/splashscreen.js

@@ -0,0 +1,36 @@
+cordova.define("cordova-plugin-splashscreen.SplashScreen", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+
+var splashscreen = {
+    show:function() {
+        exec(null, null, "SplashScreen", "show", []);
+    },
+    hide:function() {
+        exec(null, null, "SplashScreen", "hide", []);
+    }
+};
+
+module.exports = splashscreen;
+
+});

+ 32 - 0
platforms/ios/www/plugins/cordova-plugin-tencent-bg-location/www/tencentBgLocation.js

@@ -0,0 +1,32 @@
+cordova.define("cordova-plugin-tencent-bg-location.tencentBgLocation", function(require, exports, module) {
+var exec = require("cordova/exec");
+
+exports.start = function(content) {
+    exec(
+        function(message) {
+            console.log(message);
+        },
+        function(message) {
+            console.log(message);
+        },
+        "tencentBgLocation",
+        "start",
+        [content]
+    );
+};
+
+exports.stop = function() {
+    exec(
+        function(message) {
+            console.log(message);
+        },
+        function(message) {
+            console.log(message);
+        },
+        "tencentBgLocation",
+        "stop",
+        [{}]
+    );
+};
+
+});

+ 177 - 0
platforms/ios/www/plugins/cordova-plugin-wkwebview-engine/src/www/ios/ios-wkwebview-exec.js

@@ -0,0 +1,177 @@
+cordova.define("cordova-plugin-wkwebview-engine.ios-wkwebview-exec", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * Creates the exec bridge used to notify the native code of
+ * commands.
+ */
+var cordova = require('cordova');
+var utils = require('cordova/utils');
+var base64 = require('cordova/base64');
+
+function massageArgsJsToNative (args) {
+    if (!args || utils.typeName(args) !== 'Array') {
+        return args;
+    }
+    var ret = [];
+    args.forEach(function (arg, i) {
+        if (utils.typeName(arg) === 'ArrayBuffer') {
+            ret.push({
+                'CDVType': 'ArrayBuffer',
+                'data': base64.fromArrayBuffer(arg)
+            });
+        } else {
+            ret.push(arg);
+        }
+    });
+    return ret;
+}
+
+function massageMessageNativeToJs (message) {
+    if (message.CDVType === 'ArrayBuffer') {
+        var stringToArrayBuffer = function (str) {
+            var ret = new Uint8Array(str.length);
+            for (var i = 0; i < str.length; i++) {
+                ret[i] = str.charCodeAt(i);
+            }
+            return ret.buffer;
+        };
+        var base64ToArrayBuffer = function (b64) {
+            return stringToArrayBuffer(atob(b64)); // eslint-disable-line no-undef
+        };
+        message = base64ToArrayBuffer(message.data);
+    }
+    return message;
+}
+
+function convertMessageToArgsNativeToJs (message) {
+    var args = [];
+    if (!message || !message.hasOwnProperty('CDVType')) {
+        args.push(message);
+    } else if (message.CDVType === 'MultiPart') {
+        message.messages.forEach(function (e) {
+            args.push(massageMessageNativeToJs(e));
+        });
+    } else {
+        args.push(massageMessageNativeToJs(message));
+    }
+    return args;
+}
+
+var iOSExec = function () {
+    // detect change in bridge, if there is a change, we forward to new bridge
+
+    // if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.cordova && window.webkit.messageHandlers.cordova.postMessage) {
+    //     bridgeMode = jsToNativeModes.WK_WEBVIEW_BINDING;
+    // }
+
+    var successCallback, failCallback, service, action, actionArgs;
+    var callbackId = null;
+    if (typeof arguments[0] !== 'string') {
+        // FORMAT ONE
+        successCallback = arguments[0];
+        failCallback = arguments[1];
+        service = arguments[2];
+        action = arguments[3];
+        actionArgs = arguments[4];
+
+        // Since we need to maintain backwards compatibility, we have to pass
+        // an invalid callbackId even if no callback was provided since plugins
+        // will be expecting it. The Cordova.exec() implementation allocates
+        // an invalid callbackId and passes it even if no callbacks were given.
+        callbackId = 'INVALID';
+    } else {
+   	    throw new Error('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' + // eslint-disable-line
+            'cordova.exec(null, null, \'Service\', \'action\', [ arg1, arg2 ]);');
+    }
+
+    // If actionArgs is not provided, default to an empty array
+    actionArgs = actionArgs || [];
+
+    // Register the callbacks and add the callbackId to the positional
+    // arguments if given.
+    if (successCallback || failCallback) {
+        callbackId = service + cordova.callbackId++;
+        cordova.callbacks[callbackId] =
+            {success: successCallback, fail: failCallback};
+    }
+
+    actionArgs = massageArgsJsToNative(actionArgs);
+
+    // CB-10133 DataClone DOM Exception 25 guard (fast function remover)
+    var command = [callbackId, service, action, JSON.parse(JSON.stringify(actionArgs))];
+    window.webkit.messageHandlers.cordova.postMessage(command);
+};
+
+iOSExec.nativeCallback = function (callbackId, status, message, keepCallback, debug) {
+    var success = status === 0 || status === 1;
+    var args = convertMessageToArgsNativeToJs(message);
+    setTimeout(function () {
+    	cordova.callbackFromNative(callbackId, success, status, args, keepCallback); // eslint-disable-line
+    }, 0);
+};
+
+// for backwards compatibility
+iOSExec.nativeEvalAndFetch = function (func) {
+    try {
+        func();
+    } catch (e) {
+        console.log(e);
+    }
+};
+
+// Proxy the exec for bridge changes. See CB-10106
+
+function cordovaExec () {
+    var cexec = require('cordova/exec');
+    var cexec_valid = (typeof cexec.nativeFetchMessages === 'function') && (typeof cexec.nativeEvalAndFetch === 'function') && (typeof cexec.nativeCallback === 'function');
+    return (cexec_valid && execProxy !== cexec) ? cexec : iOSExec;
+}
+
+function execProxy () {
+    cordovaExec().apply(null, arguments);
+}
+
+execProxy.nativeFetchMessages = function () {
+    return cordovaExec().nativeFetchMessages.apply(null, arguments);
+};
+
+execProxy.nativeEvalAndFetch = function () {
+    return cordovaExec().nativeEvalAndFetch.apply(null, arguments);
+};
+
+execProxy.nativeCallback = function () {
+    return cordovaExec().nativeCallback.apply(null, arguments);
+};
+
+module.exports = execProxy;
+
+if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.cordova && window.webkit.messageHandlers.cordova.postMessage) {
+    // unregister the old bridge
+    cordova.define.remove('cordova/exec');
+    // redefine bridge to our new bridge
+    cordova.define('cordova/exec', function (require, exports, module) {
+        module.exports = execProxy;
+    });
+}
+
+});

+ 33 - 0
platforms/ios/www/plugins/cordova-plugin-wkwebview-engine/src/www/ios/ios-wkwebview.js

@@ -0,0 +1,33 @@
+cordova.define("cordova-plugin-wkwebview-engine.ios-wkwebview", function(require, exports, module) {
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+
+var WkWebKit = {
+    allowsBackForwardNavigationGestures: function (allow) {
+        exec(null, null, 'CDVWKWebViewEngine', 'allowsBackForwardNavigationGestures', [allow]);
+    }
+};
+
+module.exports = WkWebKit;
+
+});

+ 64 - 0
platforms/ios/www/plugins/cordova-plugin-x-toast/test/tests.js

@@ -0,0 +1,64 @@
+cordova.define("cordova-plugin-x-toast.tests", function(require, exports, module) {
+exports.defineAutoTests = function() {
+
+  var fail = function (done) {
+    expect(true).toBe(false);
+    done();
+  },
+  succeed = function (done) {
+    expect(true).toBe(true);
+    done();
+  };
+
+  describe('Plugin availability', function () {
+    it("window.plugins.toast should exist", function() {
+      expect(window.plugins.toast).toBeDefined();
+    });
+  });
+
+  describe('API functions', function () {
+    it("should define show", function() {
+      expect(window.plugins.toast.show).toBeDefined();
+    });
+
+    it("should define showWithOptions", function() {
+      expect(window.plugins.toast.showWithOptions).toBeDefined();
+    });
+
+    it("should define optionsBuilder", function() {
+      expect(window.plugins.toast.optionsBuilder).toBeDefined();
+    });
+
+    it("should define showShortTop", function() {
+      expect(window.plugins.toast.showShortTop).toBeDefined();
+    });
+
+    it("should define showShortCenter", function() {
+      expect(window.plugins.toast.showShortCenter).toBeDefined();
+    });
+
+    it("should define showShortBottom", function() {
+      expect(window.plugins.toast.showShortBottom).toBeDefined();
+    });
+
+    it("should define showLongTop", function() {
+      expect(window.plugins.toast.showLongTop).toBeDefined();
+    });
+
+    it("should define showLongCenter", function() {
+      expect(window.plugins.toast.showLongCenter).toBeDefined();
+    });
+
+    it("should define showLongBottom", function() {
+      expect(window.plugins.toast.showLongBottom).toBeDefined();
+    });
+  });
+
+  describe('Invalid usage', function () {
+    it("should fail due to an invalid position", function(done) {
+      window.plugins.toast.show('hi', 'short', 'nowhere', fail.bind(null, done), succeed.bind(null, done));
+    });
+  });
+};
+
+});

+ 101 - 0
platforms/ios/www/plugins/cordova-plugin-x-toast/www/Toast.js

@@ -0,0 +1,101 @@
+cordova.define("cordova-plugin-x-toast.Toast", function(require, exports, module) {
+function Toast() {
+}
+
+Toast.prototype.optionsBuilder = function () {
+
+  // defaults
+  var message = null;
+  var duration = "short";
+  var position = "center";
+  var addPixelsY = 0;
+
+  return {
+    withMessage: function(m) {
+      message = m.toString();
+      return this;
+    },
+
+    withDuration: function(d) {
+      duration = d.toString();
+      return this;
+    },
+
+    withPosition: function(p) {
+      position = p;
+      return this;
+    },
+
+    withAddPixelsY: function(y) {
+      addPixelsY = y;
+      return this;
+    },
+
+    build: function() {
+      return {
+        message: message,
+        duration: duration,
+        position: position,
+        addPixelsY: addPixelsY
+      };
+    }
+  };
+};
+
+
+Toast.prototype.showWithOptions = function (options, successCallback, errorCallback) {
+  options.duration = (options.duration === undefined ? 'long' : options.duration.toString());
+  options.message = options.message.toString();
+  cordova.exec(successCallback, errorCallback, "Toast", "show", [options]);
+};
+
+Toast.prototype.show = function (message, duration, position, successCallback, errorCallback) {
+  this.showWithOptions(
+      this.optionsBuilder()
+          .withMessage(message)
+          .withDuration(duration)
+          .withPosition(position)
+          .build(),
+      successCallback,
+      errorCallback);
+};
+
+Toast.prototype.showShortTop = function (message, successCallback, errorCallback) {
+  this.show(message, "short", "top", successCallback, errorCallback);
+};
+
+Toast.prototype.showShortCenter = function (message, successCallback, errorCallback) {
+  this.show(message, "short", "center", successCallback, errorCallback);
+};
+
+Toast.prototype.showShortBottom = function (message, successCallback, errorCallback) {
+  this.show(message, "short", "bottom", successCallback, errorCallback);
+};
+
+Toast.prototype.showLongTop = function (message, successCallback, errorCallback) {
+  this.show(message, "long", "top", successCallback, errorCallback);
+};
+
+Toast.prototype.showLongCenter = function (message, successCallback, errorCallback) {
+  this.show(message, "long", "center", successCallback, errorCallback);
+};
+
+Toast.prototype.showLongBottom = function (message, successCallback, errorCallback) {
+  this.show(message, "long", "bottom", successCallback, errorCallback);
+};
+
+Toast.prototype.hide = function (successCallback, errorCallback) {
+  cordova.exec(successCallback, errorCallback, "Toast", "hide", []);
+};
+
+Toast.install = function () {
+  if (!window.plugins) {
+    window.plugins = {};
+  }
+
+  window.plugins.toast = new Toast();
+  return window.plugins.toast;
+};
+
+cordova.addConstructor(Toast.install);
+});

BIN
platforms/ios/www/static/img/bg_logo.cfcf94f.png


BIN
platforms/ios/www/static/img/fast-delivery111@3x.a0e2e8c.png


BIN
platforms/ios/www/static/img/fast-delivery1@3x.2d764a8.png


BIN
platforms/ios/www/static/img/fast-delivery5@3x.760324d.png


BIN
platforms/ios/www/static/img/fast-delivery6@3x.7e1f774.png


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff