From 30c49550c89c1b69c680170d2dc247eac76bd463 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 16 Feb 2017 01:24:12 +0100 Subject: push plugin --- StoneIsland/google-services.json | 4 + StoneIsland/platforms/android/AndroidManifest.xml | 25 +- .../platforms/android/CordovaLib/build.gradle | 28 +- .../platforms/android/CordovaLib/cordova.gradle | 13 +- .../android/CordovaLib/project.properties | 2 +- .../org/apache/cordova/AuthenticationToken.java | 0 .../src/org/apache/cordova/CallbackContext.java | 14 +- .../src/org/apache/cordova/CallbackMap.java | 65 + .../CordovaLib/src/org/apache/cordova/Config.java | 3 +- .../src/org/apache/cordova/ConfigXmlParser.java | 0 .../src/org/apache/cordova/CordovaActivity.java | 121 +- .../src/org/apache/cordova/CordovaArgs.java | 0 .../src/org/apache/cordova/CordovaBridge.java | 16 +- .../apache/cordova/CordovaClientCertRequest.java | 0 .../org/apache/cordova/CordovaDialogsHelper.java | 0 .../org/apache/cordova/CordovaHttpAuthHandler.java | 0 .../src/org/apache/cordova/CordovaInterface.java | 16 + .../org/apache/cordova/CordovaInterfaceImpl.java | 85 +- .../src/org/apache/cordova/CordovaPlugin.java | 70 +- .../src/org/apache/cordova/CordovaPreferences.java | 0 .../src/org/apache/cordova/CordovaResourceApi.java | 0 .../src/org/apache/cordova/CordovaWebView.java | 2 +- .../org/apache/cordova/CordovaWebViewEngine.java | 6 +- .../src/org/apache/cordova/CordovaWebViewImpl.java | 12 +- .../src/org/apache/cordova/CoreAndroid.java | 77 +- .../src/org/apache/cordova/ExposedJsApi.java | 0 .../apache/cordova/ICordovaClientCertRequest.java | 0 .../org/apache/cordova/ICordovaCookieManager.java | 0 .../apache/cordova/ICordovaHttpAuthHandler.java | 0 .../CordovaLib/src/org/apache/cordova/LOG.java | 10 + .../org/apache/cordova/NativeToJsMessageQueue.java | 71 +- .../src/org/apache/cordova/PluginManager.java | 29 +- .../src/org/apache/cordova/PluginResult.java | 0 .../src/org/apache/cordova/ResumeCallback.java | 76 + .../src/org/apache/cordova/Whitelist.java | 0 .../apache/cordova/engine/SystemCookieManager.java | 6 + .../cordova/engine/SystemWebChromeClient.java | 41 +- .../org/apache/cordova/engine/SystemWebView.java | 0 .../apache/cordova/engine/SystemWebViewEngine.java | 58 +- StoneIsland/platforms/android/android.json | 79 +- .../cordova-js-src/android/nativeapiprovider.js | 0 .../cordova-js-src/android/promptbasednativeapi.js | 0 .../android/assets/www/cordova-js-src/exec.js | 20 +- .../android/assets/www/cordova-js-src/platform.js | 36 +- .../www/cordova-js-src/plugin/android/app.js | 0 .../platforms/android/assets/www/cordova.js | 291 +- .../android/assets/www/cordova_plugins.js | 13 +- .../platforms/android/assets/www/css/products.css | 7 +- .../android/assets/www/img/angle-down.png | Bin 0 -> 5562 bytes .../platforms/android/assets/www/index.html | 3 +- .../platforms/android/assets/www/js/index.js | 2 +- .../android/assets/www/js/lib/auth/SignupView.js | 2 +- .../android/assets/www/js/lib/blogs/BlogView.js | 8 +- .../android/assets/www/js/lib/blogs/HubView.js | 1 + .../assets/www/js/lib/products/CollectionView.js | 9 +- .../assets/www/js/lib/products/ProductView.js | 4 +- .../android/assets/www/js/lib/products/Selector.js | 4 +- .../js/lib/products/filters/DepartmentFilter.js | 31 + .../www/plugins/phonegap-plugin-push/www/push.js | 329 ++ StoneIsland/platforms/android/build.gradle | 59 +- StoneIsland/platforms/android/cordova/.jshintrc | 10 + StoneIsland/platforms/android/cordova/Api.js | 415 ++ StoneIsland/platforms/android/cordova/build | 45 +- StoneIsland/platforms/android/cordova/build.bat | 0 .../platforms/android/cordova/check_reqs.bat | 0 StoneIsland/platforms/android/cordova/clean | 39 +- StoneIsland/platforms/android/cordova/clean.bat | 0 StoneIsland/platforms/android/cordova/defaults.xml | 0 StoneIsland/platforms/android/cordova/lib/Adb.js | 105 + .../android/cordova/lib/AndroidManifest.js | 161 + .../android/cordova/lib/AndroidProject.js | 210 + .../platforms/android/cordova/lib/AndroidStudio.js | 42 + .../platforms/android/cordova/lib/appinfo.js | 41 - StoneIsland/platforms/android/cordova/lib/build.js | 596 +-- .../android/cordova/lib/builders/AntBuilder.js | 156 + .../android/cordova/lib/builders/GenericBuilder.js | 147 + .../android/cordova/lib/builders/GradleBuilder.js | 266 + .../android/cordova/lib/builders/builders.js | 47 + .../platforms/android/cordova/lib/check_reqs.js | 87 +- .../platforms/android/cordova/lib/device.js | 81 +- .../platforms/android/cordova/lib/emulator.js | 343 +- StoneIsland/platforms/android/cordova/lib/exec.js | 68 - .../android/cordova/lib/install-device.bat | 0 .../android/cordova/lib/install-emulator.bat | 0 .../platforms/android/cordova/lib/list-devices | 15 +- .../platforms/android/cordova/lib/list-devices.bat | 0 .../android/cordova/lib/list-emulator-images | 14 +- .../android/cordova/lib/list-emulator-images.bat | 0 .../android/cordova/lib/list-started-emulators | 14 +- .../android/cordova/lib/list-started-emulators.bat | 0 StoneIsland/platforms/android/cordova/lib/log.js | 0 .../android/cordova/lib/plugin-build.gradle | 17 +- .../android/cordova/lib/pluginHandlers.js | 308 ++ .../platforms/android/cordova/lib/prepare.js | 431 ++ StoneIsland/platforms/android/cordova/lib/retry.js | 6 +- StoneIsland/platforms/android/cordova/lib/run.js | 99 +- StoneIsland/platforms/android/cordova/lib/spawn.js | 50 - .../android/cordova/lib/start-emulator.bat | 0 StoneIsland/platforms/android/cordova/log.bat | 0 .../platforms/android/cordova/loggingHelper.js | 18 + StoneIsland/platforms/android/cordova/run | 44 +- StoneIsland/platforms/android/cordova/run.bat | 0 StoneIsland/platforms/android/cordova/version | 8 +- StoneIsland/platforms/android/cordova/version.bat | 0 StoneIsland/platforms/android/google-services.json | 4 + .../phonegap-plugin-push/stoneisland-push.gradle | 21 + .../cordova-js-src/android/nativeapiprovider.js | 0 .../cordova-js-src/android/promptbasednativeapi.js | 0 .../android/platform_www/cordova-js-src/exec.js | 20 +- .../platform_www/cordova-js-src/platform.js | 36 +- .../cordova-js-src/plugin/android/app.js | 0 .../platforms/android/platform_www/cordova.js | 291 +- .../android/platform_www/cordova_plugins.js | 13 +- .../plugins/phonegap-plugin-push/www/push.js | 329 ++ StoneIsland/platforms/android/project.properties | 6 +- .../platforms/android/res/values/strings.xml | 1 + StoneIsland/platforms/android/res/xml/config.xml | 5 +- .../push/BackgroundActionButtonHandler.java | 41 + .../com/adobe/phonegap/push/GCMIntentService.java | 802 +++ .../com/adobe/phonegap/push/PermissionUtils.java | 55 + .../src/com/adobe/phonegap/push/PushConstants.java | 72 + .../adobe/phonegap/push/PushHandlerActivity.java | 120 + .../push/PushInstanceIDListenerService.java | 27 + .../src/com/adobe/phonegap/push/PushPlugin.java | 458 ++ .../phonegap/push/RegistrationIntentService.java | 38 + .../xcschemes/CordovaLib.xcscheme | 80 - .../xcschemes/xcschememanagement.plist | 22 - StoneIsland/platforms/ios/Podfile | 7 + StoneIsland/platforms/ios/Podfile.lock | 30 + .../platforms/ios/Pods/GGLInstanceID/CHANGELOG.md | 28 + .../GGLInstanceID/Headers/Public/GGLInstanceID.h | 273 ++ .../Headers/Public/GGLInstanceIDConfig.h | 32 + .../Headers/Public/GGLInstanceIDDelegate.h | 13 + .../Headers/Public/GGLInstanceIDHeaders.h | 4 + .../GGLInstanceID/Libraries/libGGLInstanceIDLib.a | Bin 0 -> 2553392 bytes .../platforms/ios/Pods/GGLInstanceID/README.md | 10 + .../ios/Pods/GoogleCloudMessaging/CHANGELOG.md | 32 + .../Headers/Public/GCMConfig.h | 49 + .../Headers/Public/GCMPubSub.h | 82 + .../Headers/Public/GCMReceiverDelegate.h | 35 + .../Headers/Public/GCMService.h | 243 + .../Headers/Public/GoogleCloudMessaging.h | 5 + .../GoogleCloudMessaging/Libraries/libGcmLib.a | Bin 0 -> 3813312 bytes .../ios/Pods/GoogleCloudMessaging/README.md | 10 + .../GoogleIPhoneUtilities | Bin 0 -> 263512 bytes .../GoogleInterchangeUtilities | Bin 0 -> 4461712 bytes .../GoogleSymbolUtilities | Bin 0 -> 37696 bytes .../GoogleUtilities.framework/GoogleUtilities | Bin 0 -> 2567216 bytes .../Headers/Private/GGLInstanceID/GGLInstanceID.h | 1 + .../Private/GGLInstanceID/GGLInstanceIDConfig.h | 1 + .../Private/GGLInstanceID/GGLInstanceIDDelegate.h | 1 + .../Private/GGLInstanceID/GGLInstanceIDHeaders.h | 1 + .../Private/GoogleCloudMessaging/GCMConfig.h | 1 + .../Private/GoogleCloudMessaging/GCMPubSub.h | 1 + .../GoogleCloudMessaging/GCMReceiverDelegate.h | 1 + .../Private/GoogleCloudMessaging/GCMService.h | 1 + .../GoogleCloudMessaging/GoogleCloudMessaging.h | 1 + .../Headers/Public/GGLInstanceID/GGLInstanceID.h | 1 + .../Public/GGLInstanceID/GGLInstanceIDConfig.h | 1 + .../Public/GGLInstanceID/GGLInstanceIDDelegate.h | 1 + .../Public/GGLInstanceID/GGLInstanceIDHeaders.h | 1 + .../Public/GoogleCloudMessaging/GCMConfig.h | 1 + .../Public/GoogleCloudMessaging/GCMPubSub.h | 1 + .../GoogleCloudMessaging/GCMReceiverDelegate.h | 1 + .../Public/GoogleCloudMessaging/GCMService.h | 1 + .../GoogleCloudMessaging/GoogleCloudMessaging.h | 1 + StoneIsland/platforms/ios/Pods/Manifest.lock | 30 + .../ios/Pods/Pods.xcodeproj/project.pbxproj | 447 ++ .../xcschemes/Pods-Stone Island.xcscheme | 60 + .../xcschemes/xcschememanagement.plist | 16 + .../Pods-Stone Island-acknowledgements.markdown | 27 + .../Pods-Stone Island-acknowledgements.plist | 89 + .../Pods-Stone Island/Pods-Stone Island-dummy.m | 5 + .../Pods-Stone Island-frameworks.sh | 92 + .../Pods-Stone Island-resources.sh | 99 + .../Pods-Stone Island.debug.xcconfig | 9 + .../Pods-Stone Island.release.xcconfig | 9 + .../ios/Stone Island.xcarchive/Info.plist | 27 - .../Applications/Stone Island.app/AppIcon29x29.png | Bin 1927 -> 0 bytes .../Stone Island.app/AppIcon29x29@2x.png | Bin 5324 -> 0 bytes .../Stone Island.app/AppIcon29x29@2x~ipad.png | Bin 5324 -> 0 bytes .../Stone Island.app/AppIcon29x29@3x.png | Bin 9625 -> 0 bytes .../Stone Island.app/AppIcon29x29~ipad.png | Bin 1927 -> 0 bytes .../Stone Island.app/AppIcon40x40@2x.png | Bin 8512 -> 0 bytes .../Stone Island.app/AppIcon40x40@2x~ipad.png | Bin 8512 -> 0 bytes .../Stone Island.app/AppIcon40x40@3x.png | Bin 14319 -> 0 bytes .../Stone Island.app/AppIcon40x40~ipad.png | Bin 3199 -> 0 bytes .../Stone Island.app/AppIcon50x50@2x~ipad.png | Bin 11262 -> 0 bytes .../Stone Island.app/AppIcon50x50~ipad.png | Bin 4305 -> 0 bytes .../Applications/Stone Island.app/AppIcon57x57.png | Bin 5130 -> 0 bytes .../Stone Island.app/AppIcon57x57@2x.png | Bin 13447 -> 0 bytes .../Stone Island.app/AppIcon60x60@2x.png | Bin 14319 -> 0 bytes .../Stone Island.app/AppIcon60x60@3x.png | Bin 22453 -> 0 bytes .../Stone Island.app/AppIcon72x72@2x~ipad.png | Bin 17447 -> 0 bytes .../Stone Island.app/AppIcon72x72~ipad.png | Bin 7457 -> 0 bytes .../Stone Island.app/AppIcon76x76@2x~ipad.png | Bin 18630 -> 0 bytes .../Stone Island.app/AppIcon76x76~ipad.png | Bin 8003 -> 0 bytes .../Stone Island.app/AppIcon83.5x83.5@2x~ipad.png | Bin 20416 -> 0 bytes .../01J-lp-oVM-view-Ze5-6b-2t3.nib | Bin 2280 -> 0 bytes .../CDVLaunchScreen.storyboardc/Info.plist | Bin 258 -> 0 bytes .../UIViewController-01J-lp-oVM.nib | Bin 832 -> 0 bytes .../CDVNotification.bundle/beep.wav | Bin 8114 -> 0 bytes .../Applications/Stone Island.app/Info.plist | Bin 2049 -> 0 bytes .../Stone Island.app/LaunchImage-568h@2x.png | Bin 85510 -> 0 bytes .../Stone Island.app/LaunchImage-700-568h@2x.png | Bin 85510 -> 0 bytes .../LaunchImage-700-Landscape@2x~ipad.png | Bin 225619 -> 0 bytes .../LaunchImage-700-Landscape~ipad.png | Bin 78622 -> 0 bytes .../LaunchImage-700-Portrait@2x~ipad.png | Bin 222021 -> 0 bytes .../LaunchImage-700-Portrait~ipad.png | Bin 77977 -> 0 bytes .../Stone Island.app/LaunchImage-700@2x.png | Bin 70632 -> 0 bytes .../Stone Island.app/LaunchImage-800-667h@2x.png | Bin 107909 -> 0 bytes .../LaunchImage-800-Landscape-736h@3x.png | Bin 223784 -> 0 bytes .../LaunchImage-800-Portrait-736h@3x.png | Bin 217213 -> 0 bytes .../LaunchImage-Portrait@2x~ipad.png | Bin 222021 -> 0 bytes .../Stone Island.app/LaunchImage-Portrait~ipad.png | Bin 77977 -> 0 bytes .../Applications/Stone Island.app/LaunchImage.png | Bin 29198 -> 0 bytes .../Stone Island.app/LaunchImage@2x.png | Bin 70632 -> 0 bytes .../Stone Island.app/MainViewController.nib | Bin 943 -> 0 bytes .../Products/Applications/Stone Island.app/PkgInfo | 1 - .../Applications/Stone Island.app/Stone Island | Bin 2712176 -> 0 bytes .../Stone Island.app/_CodeSignature/CodeResources | 2750 ----------- .../archived-expanded-entitlements.xcent | 5 - .../Applications/Stone Island.app/config.xml | 89 - .../Stone Island.app/embedded.mobileprovision | Bin 11560 -> 0 bytes .../Stone Island.app/www/cordova-js-src/exec.js | 262 - .../www/cordova-js-src/platform.js | 28 - .../Applications/Stone Island.app/www/cordova.js | 1938 -------- .../Stone Island.app/www/cordova_plugins.js | 153 - .../Stone Island.app/www/css/account.css | 533 -- .../Stone Island.app/www/css/blogs.css | 352 -- .../Applications/Stone Island.app/www/css/cart.css | 362 -- .../Stone Island.app/www/css/fonts/andale_mono.ttf | Bin 109700 -> 0 bytes .../www/css/fonts/andale_mono.woff | Bin 53751 -> 0 bytes .../Stone Island.app/www/css/fonts/fonts.css | 37 - .../Stone Island.app/www/css/fonts/ionicons.css | 1480 ------ .../Stone Island.app/www/css/fonts/ionicons.eot | Bin 120724 -> 0 bytes .../Stone Island.app/www/css/fonts/ionicons.svg | 2230 --------- .../Stone Island.app/www/css/fonts/ionicons.ttf | Bin 188508 -> 0 bytes .../Stone Island.app/www/css/fonts/ionicons.woff | Bin 67904 -> 0 bytes .../www/css/fonts/pfdintextpro-bold-webfont.woff | Bin 25068 -> 0 bytes .../www/css/fonts/pfdintextpro-italic-webfont.woff | Bin 30160 -> 0 bytes .../www/css/fonts/pfdintextpro-light-webfont.woff | Bin 28824 -> 0 bytes .../www/css/fonts/pfdintextpro-medium-webfont.woff | Bin 26668 -> 0 bytes .../css/fonts/pfdintextpro-regular-webfont.woff | Bin 25352 -> 0 bytes .../Stone Island.app/www/css/index.css | 61 - .../Applications/Stone Island.app/www/css/nav.css | 443 -- .../Stone Island.app/www/css/products.css | 236 - .../Stone Island.app/www/css/vendor/flickity.css | 141 - .../img/Resources/CDVNotification.bundle/beep.wav | Bin 8114 -> 0 bytes .../Resources/splash/Default-568h@2x~iphone.png | Bin 101919 -> 0 bytes .../www/img/Resources/splash/Default-667h.png | Bin 104550 -> 0 bytes .../www/img/Resources/splash/Default-736h.png | Bin 192301 -> 0 bytes .../Resources/splash/Default-Landscape-736h.png | Bin 195426 -> 0 bytes .../Resources/splash/Default-Landscape@2x~ipad.png | Bin 246786 -> 0 bytes .../Resources/splash/Default-Landscape~ipad.png | Bin 107960 -> 0 bytes .../Resources/splash/Default-Portrait@2x~ipad.png | Bin 244661 -> 0 bytes .../img/Resources/splash/Default-Portrait~ipad.png | Bin 107123 -> 0 bytes .../www/img/Resources/splash/Default@2x~iphone.png | Bin 100977 -> 0 bytes .../www/img/Resources/splash/Default~iphone.png | Bin 46074 -> 0 bytes .../Stone Island.app/www/img/angle-down.png | Bin 5562 -> 0 bytes .../Stone Island.app/www/img/bottom-fade.png | Bin 2936 -> 0 bytes .../Stone Island.app/www/img/cart-box.png | Bin 173 -> 0 bytes .../Stone Island.app/www/img/cart-handle.png | Bin 42648 -> 0 bytes .../Stone Island.app/www/img/compass-logo.png | Bin 75721 -> 0 bytes .../Stone Island.app/www/img/compass-logo.png.old | Bin 137677 -> 0 bytes .../www/img/fade-to-bottom-threshold.gif | Bin 80012 -> 0 bytes .../Stone Island.app/www/img/fade-to-bottom.png | Bin 2936 -> 0 bytes .../Stone Island.app/www/img/left-arrow.png | Bin 5147 -> 0 bytes .../Stone Island.app/www/img/right-arrow.png | Bin 5264 -> 0 bytes .../Stone Island.app/www/img/small-cart-box.png | Bin 130 -> 0 bytes .../Stone Island.app/www/img/small-cart-handle.png | Bin 4017 -> 0 bytes .../Stone Island.app/www/img/small-logo.png | Bin 8140 -> 0 bytes .../Stone Island.app/www/img/spinner.gif | Bin 5694 -> 0 bytes .../Stone Island.app/www/img/wide-logo.png | Bin 18354 -> 0 bytes .../Applications/Stone Island.app/www/index.html | 1154 ----- .../Applications/Stone Island.app/www/js/index.js | 135 - .../Stone Island.app/www/js/lib/_router.js | 107 - .../www/js/lib/account/AccountView.js | 161 - .../www/js/lib/account/OrdersView.js | 194 - .../www/js/lib/account/PaymentView.js | 126 - .../www/js/lib/account/ProfileView.js | 103 - .../www/js/lib/account/SettingsView.js | 45 - .../www/js/lib/account/ShippingView.js | 87 - .../Stone Island.app/www/js/lib/auth/LoginView.js | 60 - .../Stone Island.app/www/js/lib/auth/LogoutView.js | 16 - .../Stone Island.app/www/js/lib/auth/SignupView.js | 121 - .../www/js/lib/blogs/ArchiveView.js | 235 - .../Stone Island.app/www/js/lib/blogs/BlogView.js | 87 - .../Stone Island.app/www/js/lib/blogs/HubView.js | 174 - .../Stone Island.app/www/js/lib/blogs/PageView.js | 41 - .../Stone Island.app/www/js/lib/blogs/StoryView.js | 76 - .../www/js/lib/cart/CartConfirm.js | 178 - .../Stone Island.app/www/js/lib/cart/CartError.js | 28 - .../www/js/lib/cart/CartPayment.js | 188 - .../www/js/lib/cart/CartShipping.js | 137 - .../www/js/lib/cart/CartSummary.js | 212 - .../Stone Island.app/www/js/lib/cart/CartThanks.js | 28 - .../Stone Island.app/www/js/lib/cart/CartView.js | 72 - .../Stone Island.app/www/js/lib/etc/backup_db.js | 551 --- .../Stone Island.app/www/js/lib/etc/deeplink.js | 5 - .../Stone Island.app/www/js/lib/etc/geo.js | 71 - .../Stone Island.app/www/js/lib/etc/push.js | 77 - .../Stone Island.app/www/js/lib/nav/AddressView.js | 272 -- .../www/js/lib/nav/CreditCardView.js | 61 - .../Stone Island.app/www/js/lib/nav/CurtainView.js | 39 - .../Stone Island.app/www/js/lib/nav/FooterView.js | 41 - .../Stone Island.app/www/js/lib/nav/HeaderView.js | 57 - .../Stone Island.app/www/js/lib/nav/IntroView.js | 64 - .../Stone Island.app/www/js/lib/nav/NavView.js | 162 - .../Stone Island.app/www/js/lib/nav/SearchView.js | 16 - .../www/js/lib/products/ClosedStoreView.js | 75 - .../www/js/lib/products/CollectionView.js | 171 - .../www/js/lib/products/GalleryView.js | 65 - .../www/js/lib/products/ProductView.js | 480 -- .../www/js/lib/products/Selector.js | 70 - .../www/js/lib/products/filters/CategoryFilter.js | 40 - .../js/lib/products/filters/DepartmentFilter.js | 31 - .../Stone Island.app/www/js/lib/view/Router.js | 75 - .../Stone Island.app/www/js/lib/view/Scrollable.js | 27 - .../www/js/lib/view/Serializable.js | 168 - .../Stone Island.app/www/js/lib/view/View.js | 147 - .../Stone Island.app/www/js/sdk/_sdk.js | 38 - .../Stone Island.app/www/js/sdk/account.js | 133 - .../Stone Island.app/www/js/sdk/address.js | 78 - .../Stone Island.app/www/js/sdk/auth.js | 148 - .../Stone Island.app/www/js/sdk/cart.js | 248 - .../Stone Island.app/www/js/sdk/payment.js | 72 - .../Stone Island.app/www/js/sdk/product.js | 68 - .../Stone Island.app/www/js/sdk/shipping.js | 85 - .../Stone Island.app/www/js/vendor/fastclick.js | 790 --- .../www/js/vendor/flickity.pkgd.js | 5090 -------------------- .../Stone Island.app/www/js/vendor/iscroll.js | 2011 -------- .../www/js/vendor/jquery-2.1.4.min.js | 4 - .../www/js/vendor/jquery.creditCardValidator.js | 208 - .../Stone Island.app/www/js/vendor/loader.js | 97 - .../Stone Island.app/www/js/vendor/lodash.min.js | 98 - .../Stone Island.app/www/js/vendor/moment.js | 3195 ------------ .../Stone Island.app/www/js/vendor/oktween.js | 125 - .../Stone Island.app/www/js/vendor/prefixfree.js | 497 -- .../Stone Island.app/www/js/vendor/promise.js | 34 - .../Stone Island.app/www/js/vendor/util.js | 200 - .../www/cdv-plugin-parse.js | 98 - .../www/console-via-logger.js | 189 - .../plugins/cordova-plugin-console/www/logger.js | 357 -- .../www/ios/LaunchMyApp.js | 12 - .../plugins/cordova-plugin-device/www/device.js | 86 - .../cordova-plugin-dialogs/www/notification.js | 133 - .../cordova-plugin-geolocation/www/Coordinates.js | 72 - .../cordova-plugin-geolocation/www/Position.js | 36 - .../www/PositionError.js | 41 - .../cordova-plugin-geolocation/www/geolocation.js | 214 - .../www/inappbrowser.js | 114 - .../www/Connection.js | 37 - .../www/network.js | 94 - .../www/splashscreen.js | 36 - .../www/SocialSharing.js | 124 - .../ionic-plugin-keyboard/www/ios/keyboard.js | 43 - .../ios/Stone Island.xcodeproj/project.pbxproj | 402 +- .../project.xcworkspace/contents.xcworkspacedata | 7 - .../UserInterfaceState.xcuserstate | Bin 11463 -> 0 bytes .../xcschemes/Stone Island.xcscheme | 91 - .../xcschemes/xcschememanagement.plist | 22 - .../contents.xcworkspacedata | 3 + .../ios/Stone Island/Entitlements-Debug.plist | 28 +- .../ios/Stone Island/Entitlements-Release.plist | 28 +- .../Images.xcassets/AppIcon.appiconset/icon-40.png | Bin 3590 -> 4082 bytes .../AppIcon.appiconset/icon-40@2x.png | Bin 8896 -> 7411 bytes .../Images.xcassets/AppIcon.appiconset/icon-50.png | Bin 4646 -> 4874 bytes .../AppIcon.appiconset/icon-50@2x.png | Bin 11969 -> 9611 bytes .../Images.xcassets/AppIcon.appiconset/icon-60.png | Bin 6097 -> 0 bytes .../AppIcon.appiconset/icon-60@2x.png | Bin 15559 -> 11924 bytes .../AppIcon.appiconset/icon-60@3x.png | Bin 29194 -> 30083 bytes .../Images.xcassets/AppIcon.appiconset/icon-72.png | Bin 7763 -> 4944 bytes .../AppIcon.appiconset/icon-72@2x.png | Bin 20517 -> 11706 bytes .../Images.xcassets/AppIcon.appiconset/icon-76.png | Bin 8279 -> 7025 bytes .../AppIcon.appiconset/icon-76@2x.png | Bin 22387 -> 15262 bytes .../AppIcon.appiconset/icon-83.5@2x.png | Bin 26132 -> 20563 bytes .../AppIcon.appiconset/icon-small.png | Bin 2191 -> 3294 bytes .../AppIcon.appiconset/icon-small@2x.png | Bin 5799 -> 5608 bytes .../AppIcon.appiconset/icon-small@3x.png | Bin 10067 -> 7040 bytes .../Images.xcassets/AppIcon.appiconset/icon.png | Bin 5679 -> 3902 bytes .../Images.xcassets/AppIcon.appiconset/icon@2x.png | Bin 14395 -> 7869 bytes .../Default-568h@2x~iphone.png | Bin 108884 -> 34225 bytes .../LaunchImage.launchimage/Default-667h.png | Bin 136116 -> 57532 bytes .../LaunchImage.launchimage/Default-736h.png | Bin 259566 -> 80929 bytes .../Default-Landscape-736h.png | Bin 264012 -> 79491 bytes .../Default-Landscape@2x~ipad.png | Bin 259502 -> 212234 bytes .../Default-Landscape~ipad.png | Bin 100012 -> 91810 bytes .../Default-Portrait@2x~ipad.png | Bin 257446 -> 212860 bytes .../Default-Portrait~ipad.png | Bin 99013 -> 91713 bytes .../LaunchImage.launchimage/Default@2x~iphone.png | Bin 90183 -> 29475 bytes .../LaunchImage.launchimage/Default~iphone.png | Bin 38256 -> 10394 bytes .../AppDelegate+notification.h | 22 + .../AppDelegate+notification.m | 278 ++ .../Plugins/phonegap-plugin-push/PushPlugin.h | 80 + .../Plugins/phonegap-plugin-push/PushPlugin.m | 677 +++ .../ios/Stone Island/Stone Island-Info.plist | 8 + .../ios/Stone Island/Stone Island.entitlements | 8 - StoneIsland/platforms/ios/Stone Island/config.xml | 67 +- .../platforms/ios/cordova/build-extras.xcconfig | 22 + StoneIsland/platforms/ios/exportOptions.plist | 10 - StoneIsland/platforms/ios/frameworks.json | 5 +- StoneIsland/platforms/ios/ios.json | 57 +- .../platforms/ios/platform_www/cordova_plugins.js | 11 +- .../plugins/phonegap-plugin-push/www/push.js | 329 ++ StoneIsland/platforms/ios/pods-debug.xcconfig | 20 +- StoneIsland/platforms/ios/pods-release.xcconfig | 22 +- StoneIsland/platforms/ios/pods.json | 14 + StoneIsland/platforms/ios/www/cordova_plugins.js | 11 +- StoneIsland/platforms/ios/www/index.html | 2 +- .../platforms/ios/www/js/lib/auth/SignupView.js | 2 +- .../www/plugins/phonegap-plugin-push/www/push.js | 329 ++ StoneIsland/platforms/platforms.json | 3 +- StoneIsland/plugins/android.json | 4 + StoneIsland/plugins/fetch.json | 18 +- StoneIsland/plugins/ios.json | 4 + .../plugins/phonegap-plugin-push/CHANGELOG.md | 597 +++ .../plugins/phonegap-plugin-push/MIT-LICENSE | 20 + StoneIsland/plugins/phonegap-plugin-push/README.md | 26 + .../plugins/phonegap-plugin-push/bower.json | 26 + .../plugins/phonegap-plugin-push/docs/API.md | 425 ++ .../plugins/phonegap-plugin-push/docs/EXAMPLES.md | 43 + .../phonegap-plugin-push/docs/INSTALLATION.md | 313 ++ .../plugins/phonegap-plugin-push/docs/ISSUES.md | 80 + .../plugins/phonegap-plugin-push/docs/PAYLOAD.md | 1400 ++++++ .../phonegap-plugin-push/docs/PHONEGAP_BUILD.md | 93 + .../phonegap-plugin-push/docs/PLATFORM_SUPPORT.md | 17 + .../phonegap-plugin-push/docs/TYPESCRIPT.md | 72 + .../hooks/windows/setToastCapable.js | 12 + .../plugins/phonegap-plugin-push/package.json | 58 + .../plugins/phonegap-plugin-push/plugin.xml | 123 + .../plugins/phonegap-plugin-push/push.gradle | 21 + .../phonegap-plugin-push/spec/helper/cordova.js | 83 + .../phonegap-plugin-push/spec/index.spec.js | 405 ++ .../push/BackgroundActionButtonHandler.java | 41 + .../com/adobe/phonegap/push/GCMIntentService.java | 802 +++ .../com/adobe/phonegap/push/PermissionUtils.java | 55 + .../com/adobe/phonegap/push/PushConstants.java | 72 + .../adobe/phonegap/push/PushHandlerActivity.java | 120 + .../push/PushInstanceIDListenerService.java | 27 + .../com/adobe/phonegap/push/PushPlugin.java | 458 ++ .../phonegap/push/RegistrationIntentService.java | 38 + .../src/browser/ServiceWorker.js | 51 + .../phonegap-plugin-push/src/browser/manifest.json | 4 + .../src/ios/AppDelegate+notification.h | 22 + .../src/ios/AppDelegate+notification.m | 278 ++ .../phonegap-plugin-push/src/ios/PushPlugin.h | 80 + .../phonegap-plugin-push/src/ios/PushPlugin.m | 677 +++ .../src/windows/PushPluginProxy.js | 93 + .../phonegap-plugin-push/www/browser/push.js | 357 ++ .../plugins/phonegap-plugin-push/www/push.js | 326 ++ StoneIsland/www/js/lib/etc/push.js | 86 +- 452 files changed, 17933 insertions(+), 34441 deletions(-) create mode 100644 StoneIsland/google-services.json mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/build.gradle mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/cordova.gradle mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/project.properties mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/AuthenticationToken.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java create mode 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackMap.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Config.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ConfigXmlParser.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaArgs.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaClientCertRequest.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaDialogsHelper.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaHttpAuthHandler.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterfaceImpl.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPlugin.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPreferences.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaResourceApi.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebView.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewEngine.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewImpl.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ExposedJsApi.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaClientCertRequest.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaCookieManager.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaHttpAuthHandler.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginResult.java create mode 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ResumeCallback.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Whitelist.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemCookieManager.java mode change 100755 => 100644 StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebView.java mode change 100755 => 100644 StoneIsland/platforms/android/assets/www/cordova-js-src/android/nativeapiprovider.js mode change 100755 => 100644 StoneIsland/platforms/android/assets/www/cordova-js-src/android/promptbasednativeapi.js mode change 100755 => 100644 StoneIsland/platforms/android/assets/www/cordova-js-src/exec.js mode change 100755 => 100644 StoneIsland/platforms/android/assets/www/cordova-js-src/platform.js mode change 100755 => 100644 StoneIsland/platforms/android/assets/www/cordova-js-src/plugin/android/app.js mode change 100755 => 100644 StoneIsland/platforms/android/assets/www/cordova.js create mode 100644 StoneIsland/platforms/android/assets/www/img/angle-down.png create mode 100644 StoneIsland/platforms/android/assets/www/js/lib/products/filters/DepartmentFilter.js create mode 100644 StoneIsland/platforms/android/assets/www/plugins/phonegap-plugin-push/www/push.js mode change 100755 => 100644 StoneIsland/platforms/android/build.gradle create mode 100644 StoneIsland/platforms/android/cordova/.jshintrc create mode 100644 StoneIsland/platforms/android/cordova/Api.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/build.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/check_reqs.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/clean.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/defaults.xml create mode 100644 StoneIsland/platforms/android/cordova/lib/Adb.js create mode 100644 StoneIsland/platforms/android/cordova/lib/AndroidManifest.js create mode 100644 StoneIsland/platforms/android/cordova/lib/AndroidProject.js create mode 100644 StoneIsland/platforms/android/cordova/lib/AndroidStudio.js delete mode 100755 StoneIsland/platforms/android/cordova/lib/appinfo.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/build.js create mode 100644 StoneIsland/platforms/android/cordova/lib/builders/AntBuilder.js create mode 100644 StoneIsland/platforms/android/cordova/lib/builders/GenericBuilder.js create mode 100644 StoneIsland/platforms/android/cordova/lib/builders/GradleBuilder.js create mode 100644 StoneIsland/platforms/android/cordova/lib/builders/builders.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/check_reqs.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/device.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/emulator.js delete mode 100755 StoneIsland/platforms/android/cordova/lib/exec.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/install-device.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/install-emulator.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/list-devices.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/list-emulator-images.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/list-started-emulators.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/log.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/plugin-build.gradle create mode 100644 StoneIsland/platforms/android/cordova/lib/pluginHandlers.js create mode 100644 StoneIsland/platforms/android/cordova/lib/prepare.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/retry.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/run.js delete mode 100755 StoneIsland/platforms/android/cordova/lib/spawn.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/lib/start-emulator.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/log.bat create mode 100644 StoneIsland/platforms/android/cordova/loggingHelper.js mode change 100755 => 100644 StoneIsland/platforms/android/cordova/run.bat mode change 100755 => 100644 StoneIsland/platforms/android/cordova/version.bat create mode 100644 StoneIsland/platforms/android/google-services.json create mode 100644 StoneIsland/platforms/android/phonegap-plugin-push/stoneisland-push.gradle mode change 100755 => 100644 StoneIsland/platforms/android/platform_www/cordova-js-src/android/nativeapiprovider.js mode change 100755 => 100644 StoneIsland/platforms/android/platform_www/cordova-js-src/android/promptbasednativeapi.js mode change 100755 => 100644 StoneIsland/platforms/android/platform_www/cordova-js-src/exec.js mode change 100755 => 100644 StoneIsland/platforms/android/platform_www/cordova-js-src/platform.js mode change 100755 => 100644 StoneIsland/platforms/android/platform_www/cordova-js-src/plugin/android/app.js mode change 100755 => 100644 StoneIsland/platforms/android/platform_www/cordova.js create mode 100644 StoneIsland/platforms/android/platform_www/plugins/phonegap-plugin-push/www/push.js mode change 100755 => 100644 StoneIsland/platforms/android/res/xml/config.xml create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/BackgroundActionButtonHandler.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/GCMIntentService.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/PermissionUtils.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushConstants.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushHandlerActivity.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushInstanceIDListenerService.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushPlugin.java create mode 100644 StoneIsland/platforms/android/src/com/adobe/phonegap/push/RegistrationIntentService.java delete mode 100644 StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/CordovaLib.xcscheme delete mode 100644 StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 StoneIsland/platforms/ios/Podfile create mode 100644 StoneIsland/platforms/ios/Podfile.lock create mode 100644 StoneIsland/platforms/ios/Pods/GGLInstanceID/CHANGELOG.md create mode 100644 StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceID.h create mode 100644 StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDConfig.h create mode 100644 StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDDelegate.h create mode 100644 StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDHeaders.h create mode 100755 StoneIsland/platforms/ios/Pods/GGLInstanceID/Libraries/libGGLInstanceIDLib.a create mode 100644 StoneIsland/platforms/ios/Pods/GGLInstanceID/README.md create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/CHANGELOG.md create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMConfig.h create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMPubSub.h create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMReceiverDelegate.h create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMService.h create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GoogleCloudMessaging.h create mode 100755 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Libraries/libGcmLib.a create mode 100644 StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/README.md create mode 100644 StoneIsland/platforms/ios/Pods/GoogleIPhoneUtilities/Frameworks/GoogleIPhoneUtilities.framework/GoogleIPhoneUtilities create mode 100755 StoneIsland/platforms/ios/Pods/GoogleInterchangeUtilities/Frameworks/frameworks/GoogleInterchangeUtilities.framework/GoogleInterchangeUtilities create mode 100755 StoneIsland/platforms/ios/Pods/GoogleSymbolUtilities/Frameworks/frameworks/GoogleSymbolUtilities.framework/GoogleSymbolUtilities create mode 100755 StoneIsland/platforms/ios/Pods/GoogleUtilities/Frameworks/frameworks/GoogleUtilities.framework/GoogleUtilities create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceID.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDConfig.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDDelegate.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDHeaders.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMConfig.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMPubSub.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMReceiverDelegate.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMService.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GoogleCloudMessaging.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceID.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDConfig.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDDelegate.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDHeaders.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMConfig.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMPubSub.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMReceiverDelegate.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMService.h create mode 120000 StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GoogleCloudMessaging.h create mode 100644 StoneIsland/platforms/ios/Pods/Manifest.lock create mode 100644 StoneIsland/platforms/ios/Pods/Pods.xcodeproj/project.pbxproj create mode 100644 StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/Pods-Stone Island.xcscheme create mode 100644 StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.markdown create mode 100644 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.plist create mode 100644 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-dummy.m create mode 100755 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-frameworks.sh create mode 100755 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-resources.sh create mode 100644 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.debug.xcconfig create mode 100644 StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.release.xcconfig delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Info.plist delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@3x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@3x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@3x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon83.5x83.5@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/Info.plist delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVNotification.bundle/beep.wav delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Info.plist delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-568h@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-568h@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-667h@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Landscape-736h@3x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Portrait-736h@3x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait@2x~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait~ipad.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage@2x.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/MainViewController.nib delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/PkgInfo delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Stone Island delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/_CodeSignature/CodeResources delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/archived-expanded-entitlements.xcent delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/config.xml delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/embedded.mobileprovision delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/exec.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/platform.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova_plugins.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/account.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/blogs.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/cart.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/andale_mono.ttf delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/andale_mono.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/fonts.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/ionicons.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/ionicons.eot delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/ionicons.svg delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/ionicons.ttf delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/ionicons.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/pfdintextpro-bold-webfont.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/pfdintextpro-italic-webfont.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/pfdintextpro-light-webfont.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/pfdintextpro-medium-webfont.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/fonts/pfdintextpro-regular-webfont.woff delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/index.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/nav.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/products.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/css/vendor/flickity.css delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/CDVNotification.bundle/beep.wav delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-568h@2x~iphone.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-667h.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-736h.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-Landscape-736h.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-Landscape@2x~ipad.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-Landscape~ipad.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-Portrait@2x~ipad.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default-Portrait~ipad.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default@2x~iphone.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/Resources/splash/Default~iphone.png delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/angle-down.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/bottom-fade.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/cart-box.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/cart-handle.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/compass-logo.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/compass-logo.png.old delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/fade-to-bottom-threshold.gif delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/fade-to-bottom.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/left-arrow.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/right-arrow.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/small-cart-box.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/small-cart-handle.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/small-logo.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/spinner.gif delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/img/wide-logo.png delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/index.html delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/index.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/_router.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/AccountView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/OrdersView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/PaymentView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ProfileView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/SettingsView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ShippingView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LoginView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LogoutView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/SignupView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/ArchiveView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/BlogView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/HubView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/PageView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/StoryView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartConfirm.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartError.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartPayment.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartShipping.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartSummary.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartThanks.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/backup_db.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/deeplink.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/geo.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/push.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/AddressView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CreditCardView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CurtainView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/FooterView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/HeaderView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/IntroView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/NavView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/SearchView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ClosedStoreView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/CollectionView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/GalleryView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ProductView.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/Selector.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/CategoryFilter.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/DepartmentFilter.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Router.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Scrollable.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Serializable.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/View.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/_sdk.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/account.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/address.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/auth.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/cart.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/payment.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/product.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/shipping.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/fastclick.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/flickity.pkgd.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/iscroll.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/jquery-2.1.4.min.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/jquery.creditCardValidator.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/loader.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/lodash.min.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/moment.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/oktween.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/prefixfree.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/promise.js delete mode 100755 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/util.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/com.parse.cordova.core.pushplugin/www/cdv-plugin-parse.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-console/www/console-via-logger.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-console/www/logger.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-customurlscheme/www/ios/LaunchMyApp.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-device/www/device.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-dialogs/www/notification.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-geolocation/www/Coordinates.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-geolocation/www/Position.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-geolocation/www/PositionError.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-geolocation/www/geolocation.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-inappbrowser/www/inappbrowser.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-network-information/www/Connection.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-network-information/www/network.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-splashscreen/www/splashscreen.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/cordova-plugin-x-socialsharing/www/SocialSharing.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/plugins/ionic-plugin-keyboard/www/ios/keyboard.js delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcodeproj/project.xcworkspace/xcuserdata/julie.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/Stone Island.xcscheme delete mode 100644 StoneIsland/platforms/ios/Stone Island.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 StoneIsland/platforms/ios/Stone Island/Images.xcassets/AppIcon.appiconset/icon-60.png create mode 100644 StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.h create mode 100644 StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.m create mode 100644 StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.h create mode 100644 StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.m delete mode 100644 StoneIsland/platforms/ios/Stone Island/Stone Island.entitlements delete mode 100644 StoneIsland/platforms/ios/exportOptions.plist create mode 100644 StoneIsland/platforms/ios/platform_www/plugins/phonegap-plugin-push/www/push.js create mode 100644 StoneIsland/platforms/ios/pods.json create mode 100644 StoneIsland/platforms/ios/www/plugins/phonegap-plugin-push/www/push.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/CHANGELOG.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/MIT-LICENSE create mode 100644 StoneIsland/plugins/phonegap-plugin-push/README.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/bower.json create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/API.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/EXAMPLES.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/INSTALLATION.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/ISSUES.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/PAYLOAD.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/PHONEGAP_BUILD.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/PLATFORM_SUPPORT.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/docs/TYPESCRIPT.md create mode 100644 StoneIsland/plugins/phonegap-plugin-push/hooks/windows/setToastCapable.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/package.json create mode 100755 StoneIsland/plugins/phonegap-plugin-push/plugin.xml create mode 100644 StoneIsland/plugins/phonegap-plugin-push/push.gradle create mode 100644 StoneIsland/plugins/phonegap-plugin-push/spec/helper/cordova.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/spec/index.spec.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/BackgroundActionButtonHandler.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/GCMIntentService.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PermissionUtils.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushInstanceIDListenerService.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/RegistrationIntentService.java create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/browser/ServiceWorker.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/browser/manifest.json create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.h create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.m create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.h create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/ios/PushPlugin.m create mode 100644 StoneIsland/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/www/browser/push.js create mode 100644 StoneIsland/plugins/phonegap-plugin-push/www/push.js diff --git a/StoneIsland/google-services.json b/StoneIsland/google-services.json new file mode 100644 index 00000000..57497bf5 --- /dev/null +++ b/StoneIsland/google-services.json @@ -0,0 +1,4 @@ +{ + "project_info": {}, + "client": [] +} diff --git a/StoneIsland/platforms/android/AndroidManifest.xml b/StoneIsland/platforms/android/AndroidManifest.xml index da0336cf..b8feb984 100755 --- a/StoneIsland/platforms/android/AndroidManifest.xml +++ b/StoneIsland/platforms/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + @@ -43,6 +43,25 @@ + + + + + + + + + + + + + + + + + + + @@ -57,4 +76,8 @@ + + + + diff --git a/StoneIsland/platforms/android/CordovaLib/build.gradle b/StoneIsland/platforms/android/CordovaLib/build.gradle old mode 100755 new mode 100644 index 2565633f..b580e13f --- a/StoneIsland/platforms/android/CordovaLib/build.gradle +++ b/StoneIsland/platforms/android/CordovaLib/build.gradle @@ -21,28 +21,22 @@ buildscript { repositories { mavenCentral() + jcenter(); } - // Switch the Android Gradle plugin version requirement depending on the - // installed version of Gradle. This dependency is documented at - // http://tools.android.com/tech-docs/new-build-system/version-compatibility - // and https://issues.apache.org/jira/browse/CB-8143 - if (gradle.gradleVersion >= "2.2") { - dependencies { - classpath 'com.android.tools.build:gradle:1.0.0+' - } - } else if (gradle.gradleVersion >= "2.1") { - dependencies { - classpath 'com.android.tools.build:gradle:0.14.0+' - } - } else { - dependencies { - classpath 'com.android.tools.build:gradle:0.12.0+' - } + dependencies { + classpath 'com.android.tools.build:gradle:2.2.1' } + } -apply plugin: 'android-library' +apply plugin: 'com.android.library' + +ext { + apply from: 'cordova.gradle' + cdvCompileSdkVersion = privateHelpers.getProjectTarget() + cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools() +} android { compileSdkVersion cdvCompileSdkVersion diff --git a/StoneIsland/platforms/android/CordovaLib/cordova.gradle b/StoneIsland/platforms/android/CordovaLib/cordova.gradle old mode 100755 new mode 100644 index 6e89c4c2..21a01bb5 --- a/StoneIsland/platforms/android/CordovaLib/cordova.gradle +++ b/StoneIsland/platforms/android/CordovaLib/cordova.gradle @@ -61,7 +61,7 @@ String doFindLatestInstalledBuildTools(String minBuildToolsVersion) { highestBuildToolsVersion } else { throw new RuntimeException( - "No installed build tools found. Please install the Android build tools version " + + "No installed build tools found. Install the Android build tools version " + minBuildToolsVersion + " or higher.") } } @@ -125,7 +125,15 @@ def doExtractIntFromManifest(name) { def pattern = Pattern.compile(name + "=\"(\\d+)\"") def matcher = pattern.matcher(manifestFile.getText()) matcher.find() - return Integer.parseInt(matcher.group(1)) + return new BigInteger(matcher.group(1)) +} + +def doExtractStringFromManifest(name) { + def manifestFile = file(android.sourceSets.main.manifest.srcFile) + def pattern = Pattern.compile(name + "=\"(\\S+)\"") + def matcher = pattern.matcher(manifestFile.getText()) + matcher.find() + return matcher.group(1) } def doPromptForPassword(msg) { @@ -179,6 +187,7 @@ ext { privateHelpers.getProjectTarget = { doGetProjectTarget() } privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') } privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) } + privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) } privateHelpers.promptForPassword = { msg -> doPromptForPassword(msg) } privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) } diff --git a/StoneIsland/platforms/android/CordovaLib/project.properties b/StoneIsland/platforms/android/CordovaLib/project.properties old mode 100755 new mode 100644 index 40ae82c1..df3c73c4 --- a/StoneIsland/platforms/android/CordovaLib/project.properties +++ b/StoneIsland/platforms/android/CordovaLib/project.properties @@ -10,7 +10,7 @@ # Indicates whether an apk should be generated for each density. split.density=false # Project target. -target=android-22 +target=android-25 apk-configurations= renderscript.opt.level=O0 android.library=true diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/AuthenticationToken.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/AuthenticationToken.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java old mode 100755 new mode 100644 index 446c37d9..43363869 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackContext.java @@ -20,8 +20,6 @@ package org.apache.cordova; import org.json.JSONArray; -import android.util.Log; - import org.apache.cordova.CordovaWebView; import org.apache.cordova.PluginResult; import org.json.JSONObject; @@ -31,22 +29,22 @@ public class CallbackContext { private String callbackId; private CordovaWebView webView; - private boolean finished; + protected boolean finished; private int changingThreads; public CallbackContext(String callbackId, CordovaWebView webView) { this.callbackId = callbackId; this.webView = webView; } - + public boolean isFinished() { return finished; } - + public boolean isChangingThreads() { return changingThreads > 0; } - + public String getCallbackId() { return callbackId; } @@ -54,7 +52,7 @@ public class CallbackContext { public void sendPluginResult(PluginResult pluginResult) { synchronized (this) { if (finished) { - Log.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage()); + LOG.w(LOG_TAG, "Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage()); return; } else { finished = !pluginResult.getKeepCallback(); @@ -98,7 +96,7 @@ public class CallbackContext { public void success(byte[] message) { sendPluginResult(new PluginResult(PluginResult.Status.OK, message)); } - + /** * Helper for success callbacks that just returns the Status.OK by default * diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackMap.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackMap.java new file mode 100644 index 00000000..050daa01 --- /dev/null +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CallbackMap.java @@ -0,0 +1,65 @@ +/* + 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. +*/ +package org.apache.cordova; + +import android.util.Pair; +import android.util.SparseArray; + +/** + * Provides a collection that maps unique request codes to CordovaPlugins and Integers. + * Used to ensure that when plugins make requests for runtime permissions, those requests do not + * collide with requests from other plugins that use the same request code value. + */ +public class CallbackMap { + private int currentCallbackId = 0; + private SparseArray> callbacks; + + public CallbackMap() { + this.callbacks = new SparseArray>(); + } + + /** + * Stores a CordovaPlugin and request code and returns a new unique request code to use + * in a permission request. + * + * @param receiver The plugin that is making the request + * @param requestCode The original request code used by the plugin + * @return A unique request code that can be used to retrieve this callback + * with getAndRemoveCallback() + */ + public synchronized int registerCallback(CordovaPlugin receiver, int requestCode) { + int mappedId = this.currentCallbackId++; + callbacks.put(mappedId, new Pair(receiver, requestCode)); + return mappedId; + } + + /** + * Retrieves and removes a callback stored in the map using the mapped request code + * obtained from registerCallback() + * + * @param mappedId The request code obtained from registerCallback() + * @return The CordovaPlugin and orignal request code that correspond to the + * given mappedCode + */ + public synchronized Pair getAndRemoveCallback(int mappedId) { + Pair callback = callbacks.get(mappedId); + callbacks.remove(mappedId); + return callback; + } +} diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Config.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Config.java old mode 100755 new mode 100644 index 048960bf..07397959 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Config.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Config.java @@ -22,7 +22,6 @@ package org.apache.cordova; import java.util.List; import android.app.Activity; -import android.util.Log; @Deprecated // Use Whitelist, CordovaPrefences, etc. directly. public class Config { @@ -61,7 +60,7 @@ public class Config { public static List getPluginEntries() { return parser.getPluginEntries(); } - + public static CordovaPreferences getPreferences() { return parser.getPreferences(); } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ConfigXmlParser.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ConfigXmlParser.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaActivity.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaActivity.java index 5c3bc508..85eeb53a 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaActivity.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaActivity.java @@ -26,6 +26,7 @@ import org.json.JSONObject; import android.app.Activity; import android.app.AlertDialog; +import android.annotation.SuppressLint; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; @@ -33,7 +34,6 @@ import android.graphics.Color; import android.media.AudioManager; import android.os.Build; import android.os.Bundle; -import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -49,7 +49,7 @@ import android.widget.FrameLayout; * html file that contains the application. * * As an example: - * + * *
  *     package org.apache.cordova.examples;
  *
@@ -66,8 +66,8 @@ import android.widget.FrameLayout;
  *       }
  *     }
  * 
- * - * Cordova xml configuration: Cordova uses a configuration file at + * + * Cordova xml configuration: Cordova uses a configuration file at * res/xml/config.xml to specify its settings. See "The config.xml File" * guide in cordova-docs at http://cordova.apache.org/docs for the documentation * for the configuration. The use of the set*Property() methods is @@ -103,31 +103,31 @@ public class CordovaActivity extends Activity { */ @Override public void onCreate(Bundle savedInstanceState) { + // need to activate preferences before super.onCreate to avoid "requestFeature() must be called before adding content" exception + loadConfig(); + + String logLevel = preferences.getString("loglevel", "ERROR"); + LOG.setLogLevel(logLevel); + LOG.i(TAG, "Apache Cordova native platform version " + CordovaWebView.CORDOVA_VERSION + " is starting"); LOG.d(TAG, "CordovaActivity.onCreate()"); - // need to activate preferences before super.onCreate to avoid "requestFeature() must be called before adding content" exception - loadConfig(); - if(!preferences.getBoolean("ShowTitle", false)) - { + if (!preferences.getBoolean("ShowTitle", false)) { getWindow().requestFeature(Window.FEATURE_NO_TITLE); } - if(preferences.getBoolean("SetFullscreen", false)) - { - Log.d(TAG, "The SetFullscreen configuration is deprecated in favor of Fullscreen, and will be removed in a future version."); + if (preferences.getBoolean("SetFullscreen", false)) { + LOG.d(TAG, "The SetFullscreen configuration is deprecated in favor of Fullscreen, and will be removed in a future version."); preferences.set("Fullscreen", true); } - if(preferences.getBoolean("Fullscreen", false)) - { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) - { + if (preferences.getBoolean("Fullscreen", false)) { + // NOTE: use the FullscreenNotImmersive configuration key to set the activity in a REAL full screen + // (as was the case in previous cordova versions) + if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) && !preferences.getBoolean("FullscreenNotImmersive", false)) { immersiveMode = true; - } - else - { + } else { getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); + WindowManager.LayoutParams.FLAG_FULLSCREEN); } } else { getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, @@ -137,12 +137,11 @@ public class CordovaActivity extends Activity { super.onCreate(savedInstanceState); cordovaInterface = makeCordovaInterface(); - if(savedInstanceState != null) - { + if (savedInstanceState != null) { cordovaInterface.restoreInstanceState(savedInstanceState); } } - + protected void init() { appView = makeWebView(); createViews(); @@ -181,9 +180,14 @@ public class CordovaActivity extends Activity { setContentView(appView.getView()); if (preferences.contains("BackgroundColor")) { - int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK); - // Background of activity: - appView.getView().setBackgroundColor(backgroundColor); + try { + int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK); + // Background of activity: + appView.getView().setBackgroundColor(backgroundColor); + } + catch (NumberFormatException e){ + e.printStackTrace(); + } } appView.getView().requestFocusFromTouch(); @@ -191,7 +195,7 @@ public class CordovaActivity extends Activity { /** * Construct the default web view object. - * + *

* Override this to customize the webview that is used. */ protected CordovaWebView makeWebView() { @@ -244,13 +248,13 @@ public class CordovaActivity extends Activity { /** * Called when the activity receives a new intent - **/ + */ @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); //Forward to plugins if (this.appView != null) - this.appView.onNewIntent(intent); + this.appView.onNewIntent(intent); } /** @@ -260,7 +264,7 @@ public class CordovaActivity extends Activity { protected void onResume() { super.onResume(); LOG.d(TAG, "Resumed the activity."); - + if (this.appView == null) { return; } @@ -320,16 +324,17 @@ public class CordovaActivity extends Activity { super.onWindowFocusChanged(hasFocus); if (hasFocus && immersiveMode) { final int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; getWindow().getDecorView().setSystemUiVisibility(uiOptions); } } + @SuppressLint("NewApi") @Override public void startActivityForResult(Intent intent, int requestCode, Bundle options) { // Capture requestCode here so that it is captured in the setActivityResultCallback() case. @@ -341,10 +346,10 @@ public class CordovaActivity extends Activity { * Called when an activity you launched exits, giving you the requestCode you started it with, * the resultCode it returned, and any additional data from it. * - * @param requestCode The request code originally supplied to startActivityForResult(), - * allowing you to identify who this result came from. - * @param resultCode The integer result code returned by the child activity through its setResult(). - * @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). + * @param requestCode The request code originally supplied to startActivityForResult(), + * allowing you to identify who this result came from. + * @param resultCode The integer result code returned by the child activity through its setResult(). + * @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { @@ -357,9 +362,9 @@ public class CordovaActivity extends Activity { * Report an error to the host application. These errors are unrecoverable (i.e. the main resource is unavailable). * The errorCode parameter corresponds to one of the ERROR_* constants. * - * @param errorCode The error code corresponding to an ERROR_* value. - * @param description A String describing the error. - * @param failingUrl The url that failed to load. + * @param errorCode The error code corresponding to an ERROR_* value. + * @param description A String describing the error. + * @param failingUrl The url that failed to load. */ public void onReceivedError(final int errorCode, final String description, final String failingUrl) { final CordovaActivity me = this; @@ -448,9 +453,9 @@ public class CordovaActivity extends Activity { /** * Called when a message is sent to plugin. * - * @param id The message id - * @param data The message data - * @return Object or null + * @param id The message id + * @param data The message data + * @return Object or null */ public Object onMessage(String id, Object data) { if ("onReceivedError".equals(id)) { @@ -466,8 +471,7 @@ public class CordovaActivity extends Activity { return null; } - protected void onSaveInstanceState(Bundle outState) - { + protected void onSaveInstanceState(Bundle outState) { cordovaInterface.onSaveInstanceState(outState); super.onSaveInstanceState(outState); } @@ -475,7 +479,7 @@ public class CordovaActivity extends Activity { /** * Called by the system when the device configuration changes while your activity is running. * - * @param newConfig The new device configuration + * @param newConfig The new device configuration */ @Override public void onConfigurationChanged(Configuration newConfig) { @@ -488,4 +492,27 @@ public class CordovaActivity extends Activity { pm.onConfigurationChanged(newConfig); } } + + /** + * Called by the system when the user grants permissions + * + * @param requestCode + * @param permissions + * @param grantResults + */ + @Override + public void onRequestPermissionsResult(int requestCode, String permissions[], + int[] grantResults) { + try + { + cordovaInterface.onRequestPermissionResult(requestCode, permissions, grantResults); + } + catch (JSONException e) + { + LOG.d(TAG, "JSONException: Parameters fed into the method are not valid"); + e.printStackTrace(); + } + + } + } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaArgs.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaArgs.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java old mode 100755 new mode 100644 index 7bc4a552..9459a113 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaBridge.java @@ -23,8 +23,6 @@ import java.security.SecureRandom; import org.json.JSONArray; import org.json.JSONException; -import android.util.Log; - /** * Contains APIs that the JS can call. All functions in here should also have * an equivalent entry in CordovaChromeClient.java, and be added to @@ -87,15 +85,15 @@ public class CordovaBridge { private boolean verifySecret(String action, int bridgeSecret) throws IllegalAccessException { if (!jsMessageQueue.isBridgeEnabled()) { if (bridgeSecret == -1) { - Log.d(LOG_TAG, action + " call made before bridge was enabled."); + LOG.d(LOG_TAG, action + " call made before bridge was enabled."); } else { - Log.d(LOG_TAG, "Ignoring " + action + " from previous page load."); + LOG.d(LOG_TAG, "Ignoring " + action + " from previous page load."); } return false; } // Bridge secret wrong and bridge not due to it being from the previous page. if (expectedBridgeSecret < 0 || bridgeSecret != expectedBridgeSecret) { - Log.e(LOG_TAG, "Bridge access attempt with wrong secret token, possibly from malicious code. Disabling exec() bridge!"); + LOG.e(LOG_TAG, "Bridge access attempt with wrong secret token, possibly from malicious code. Disabling exec() bridge!"); clearBridgeSecret(); throw new IllegalAccessException(); } @@ -120,7 +118,7 @@ public class CordovaBridge { public void reset() { jsMessageQueue.reset(); - clearBridgeSecret(); + clearBridgeSecret(); } public String promptOnJsPrompt(String origin, String message, String defaultValue) { @@ -141,7 +139,7 @@ public class CordovaBridge { } return ""; } - // Sets the native->JS bridge mode. + // Sets the native->JS bridge mode. else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) { try { int bridgeSecret = Integer.parseInt(defaultValue.substring(16)); @@ -153,7 +151,7 @@ public class CordovaBridge { } return ""; } - // Polling for JavaScript messages + // Polling for JavaScript messages else if (defaultValue != null && defaultValue.startsWith("gap_poll:")) { int bridgeSecret = Integer.parseInt(defaultValue.substring(9)); try { @@ -175,7 +173,7 @@ public class CordovaBridge { int secret = generateBridgeSecret(); return ""+secret; } else { - Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin); + LOG.e(LOG_TAG, "gap_init called from restricted origin: " + origin); } return ""; } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaClientCertRequest.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaClientCertRequest.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaDialogsHelper.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaDialogsHelper.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaHttpAuthHandler.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaHttpAuthHandler.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterface.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterface.java index 59ed4864..3b8468f3 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterface.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterface.java @@ -69,4 +69,20 @@ public interface CordovaInterface { * Returns a shared thread pool that can be used for background tasks. */ public ExecutorService getThreadPool(); + + /** + * Sends a permission request to the activity for one permission. + */ + public void requestPermission(CordovaPlugin plugin, int requestCode, String permission); + + /** + * Sends a permission request to the activity for a group of permissions + */ + public void requestPermissions(CordovaPlugin plugin, int requestCode, String [] permissions); + + /** + * Check for a permission. Returns true if the permission is granted, false otherwise. + */ + public boolean hasPermission(String permission); + } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterfaceImpl.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterfaceImpl.java old mode 100755 new mode 100644 index e35a181d..71dcb782 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterfaceImpl.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaInterfaceImpl.java @@ -21,8 +21,13 @@ package org.apache.cordova; import android.app.Activity; import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; -import android.util.Log; +import android.util.Pair; + +import org.json.JSONException; +import org.json.JSONObject; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -37,9 +42,12 @@ public class CordovaInterfaceImpl implements CordovaInterface { protected PluginManager pluginManager; protected ActivityResultHolder savedResult; + protected CallbackMap permissionResultCallbacks; protected CordovaPlugin activityResultCallback; protected String initCallbackService; protected int activityResultRequestCode; + protected boolean activityWasDestroyed = false; + protected Bundle savedPluginState; public CordovaInterfaceImpl(Activity activity) { this(activity, Executors.newCachedThreadPool()); @@ -48,6 +56,7 @@ public class CordovaInterfaceImpl implements CordovaInterface { public CordovaInterfaceImpl(Activity activity, ExecutorService threadPool) { this.activity = activity; this.threadPool = threadPool; + this.permissionResultCallbacks = new CallbackMap(); } @Override @@ -89,12 +98,31 @@ public class CordovaInterfaceImpl implements CordovaInterface { } /** - * Dispatches any pending onActivityResult callbacks. + * Dispatches any pending onActivityResult callbacks and sends the resume event if the + * Activity was destroyed by the OS. */ public void onCordovaInit(PluginManager pluginManager) { this.pluginManager = pluginManager; if (savedResult != null) { onActivityResult(savedResult.requestCode, savedResult.resultCode, savedResult.intent); + } else if(activityWasDestroyed) { + // If there was no Activity result, we still need to send out the resume event if the + // Activity was destroyed by the OS + activityWasDestroyed = false; + if(pluginManager != null) + { + CoreAndroid appPlugin = (CoreAndroid) pluginManager.getPlugin(CoreAndroid.PLUGIN_NAME); + if(appPlugin != null) { + JSONObject obj = new JSONObject(); + try { + obj.put("action", "resume"); + } catch (JSONException e) { + LOG.e(TAG, "Failed to create event message", e); + } + appPlugin.sendResumeEvent(new PluginResult(PluginResult.Status.OK, obj)); + } + } + } } @@ -109,18 +137,22 @@ public class CordovaInterfaceImpl implements CordovaInterface { savedResult = new ActivityResultHolder(requestCode, resultCode, intent); if (pluginManager != null) { callback = pluginManager.getPlugin(initCallbackService); + if(callback != null) { + callback.onRestoreStateForActivityResult(savedPluginState.getBundle(callback.getServiceName()), + new ResumeCallback(callback.getServiceName(), pluginManager)); + } } } activityResultCallback = null; if (callback != null) { - Log.d(TAG, "Sending activity result to plugin"); + LOG.d(TAG, "Sending activity result to plugin"); initCallbackService = null; savedResult = null; callback.onActivityResult(requestCode, resultCode, intent); return true; } - Log.w(TAG, "Got an activity result, but no plugin was registered to receive it" + (savedResult != null ? " yet!": ".")); + LOG.w(TAG, "Got an activity result, but no plugin was registered to receive it" + (savedResult != null ? " yet!" : ".")); return false; } @@ -141,6 +173,10 @@ public class CordovaInterfaceImpl implements CordovaInterface { String serviceName = activityResultCallback.getServiceName(); outState.putString("callbackService", serviceName); } + if(pluginManager != null){ + outState.putBundle("plugin", pluginManager.onSaveInstanceState()); + } + } /** @@ -148,6 +184,8 @@ public class CordovaInterfaceImpl implements CordovaInterface { */ public void restoreInstanceState(Bundle savedInstanceState) { initCallbackService = savedInstanceState.getString("callbackService"); + savedPluginState = savedInstanceState.getBundle("plugin"); + activityWasDestroyed = true; } private static class ActivityResultHolder { @@ -161,4 +199,43 @@ public class CordovaInterfaceImpl implements CordovaInterface { this.intent = intent; } } + + /** + * Called by the system when the user grants permissions + * + * @param requestCode + * @param permissions + * @param grantResults + */ + public void onRequestPermissionResult(int requestCode, String[] permissions, + int[] grantResults) throws JSONException { + Pair callback = permissionResultCallbacks.getAndRemoveCallback(requestCode); + if(callback != null) { + callback.first.onRequestPermissionResult(callback.second, permissions, grantResults); + } + } + + public void requestPermission(CordovaPlugin plugin, int requestCode, String permission) { + String[] permissions = new String [1]; + permissions[0] = permission; + requestPermissions(plugin, requestCode, permissions); + } + + public void requestPermissions(CordovaPlugin plugin, int requestCode, String [] permissions) { + int mappedRequestCode = permissionResultCallbacks.registerCallback(plugin, requestCode); + getActivity().requestPermissions(permissions, mappedRequestCode); + } + + public boolean hasPermission(String permission) + { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + { + int result = activity.checkSelfPermission(permission); + return PackageManager.PERMISSION_GRANTED == result; + } + else + { + return true; + } + } } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPlugin.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPlugin.java old mode 100755 new mode 100644 index 7cf8528f..41af1db7 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPlugin.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPlugin.java @@ -26,8 +26,11 @@ import org.json.JSONArray; import org.json.JSONException; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.net.Uri; +import android.os.Build; +import android.os.Bundle; import java.io.FileNotFoundException; import java.io.IOException; @@ -75,7 +78,7 @@ public class CordovaPlugin { public String getServiceName() { return serviceName; } - + /** * Executes the request. * @@ -172,6 +175,29 @@ public class CordovaPlugin { public void onDestroy() { } + /** + * Called when the Activity is being destroyed (e.g. if a plugin calls out to an external + * Activity and the OS kills the CordovaActivity in the background). The plugin should save its + * state in this method only if it is awaiting the result of an external Activity and needs + * to preserve some information so as to handle that result; onRestoreStateForActivityResult() + * will only be called if the plugin is the recipient of an Activity result + * + * @return Bundle containing the state of the plugin or null if state does not need to be saved + */ + public Bundle onSaveInstanceState() { + return null; + } + + /** + * Called when a plugin is the recipient of an Activity result after the CordovaActivity has + * been destroyed. The Bundle will be the same as the one the plugin returned in + * onSaveInstanceState() + * + * @param state Bundle containing the state of the plugin + * @param callbackContext Replacement Context to return the plugin result to + */ + public void onRestoreStateForActivityResult(Bundle state, CallbackContext callbackContext) {} + /** * Called when a message is sent to plugin. * @@ -321,7 +347,7 @@ public class CordovaPlugin { */ public void onReset() { } - + /** * Called when the system received an HTTP authentication request. Plugin can use * the supplied HttpAuthHandler to process this auth challenge. @@ -330,14 +356,14 @@ public class CordovaPlugin { * @param handler The HttpAuthHandler used to set the WebView's response * @param host The host requiring authentication * @param realm The realm for which authentication is required - * + * * @return Returns True if plugin will resolve this auth challenge, otherwise False - * + * */ public boolean onReceivedHttpAuthRequest(CordovaWebView view, ICordovaHttpAuthHandler handler, String host, String realm) { return false; } - + /** * Called when he system received an SSL client certificate request. Plugin can use * the supplied ClientCertRequest to process this certificate challenge. @@ -359,4 +385,38 @@ public class CordovaPlugin { */ public void onConfigurationChanged(Configuration newConfig) { } + + /** + * Called by the Plugin Manager when we need to actually request permissions + * + * @param requestCode Passed to the activity to track the request + * + * @return Returns the permission that was stored in the plugin + */ + + public void requestPermissions(int requestCode) { + } + + /* + * Called by the WebView implementation to check for geolocation permissions, can be used + * by other Java methods in the event that a plugin is using this as a dependency. + * + * @return Returns true if the plugin has all the permissions it needs to operate. + */ + + public boolean hasPermisssion() { + return true; + } + + /** + * Called by the system when the user grants permissions + * + * @param requestCode + * @param permissions + * @param grantResults + */ + public void onRequestPermissionResult(int requestCode, String[] permissions, + int[] grantResults) throws JSONException { + + } } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPreferences.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaPreferences.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaResourceApi.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaResourceApi.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebView.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebView.java old mode 100755 new mode 100644 index ba58f9a0..2eebd0d3 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebView.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebView.java @@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback; * are not expected to implement it. */ public interface CordovaWebView { - public static final String CORDOVA_VERSION = "4.1.1"; + public static final String CORDOVA_VERSION = "6.1.2"; void init(CordovaInterface cordova, List pluginEntries, CordovaPreferences preferences); diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewEngine.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewEngine.java old mode 100755 new mode 100644 index dd84ab11..c8e5a55d --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewEngine.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewEngine.java @@ -20,9 +20,10 @@ package org.apache.cordova; import android.view.KeyEvent; import android.view.View; +import android.webkit.ValueCallback; /** - * Interfcae for all Cordova engines. + * Interface for all Cordova engines. * No methods will be added to this class (in order to be compatible with existing engines). * Instead, we will create a new interface: e.g. CordovaWebViewEngineV2 */ @@ -58,6 +59,9 @@ public interface CordovaWebViewEngine { /** Clean up all resources associated with the WebView. */ void destroy(); + /** Add the evaulate Javascript method **/ + void evaluateJavascript(String js, ValueCallback callback); + /** * Used to retrieve the associated CordovaWebView given a View without knowing the type of Engine. * E.g. ((CordovaWebView.EngineView)activity.findViewById(android.R.id.webView)).getCordovaWebView(); diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewImpl.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewImpl.java old mode 100755 new mode 100644 index 06da55e1..85a0b5f5 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewImpl.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewImpl.java @@ -21,7 +21,6 @@ package org.apache.cordova; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.View; @@ -135,6 +134,7 @@ public class CordovaWebViewImpl implements CordovaWebView { if (recreatePlugins) { // Don't re-initialize on first load. if (loadedUrl != null) { + appPlugin = null; pluginManager.init(); } loadedUrl = url; @@ -244,7 +244,7 @@ public class CordovaWebViewImpl implements CordovaWebView { @Deprecated public void showCustomView(View view, WebChromeClient.CustomViewCallback callback) { // This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0 - Log.d(TAG, "showing Custom View"); + LOG.d(TAG, "showing Custom View"); // if a view already exists then immediately terminate the new one if (mCustomView != null) { callback.onCustomViewHidden(); @@ -275,7 +275,7 @@ public class CordovaWebViewImpl implements CordovaWebView { public void hideCustomView() { // This code is adapted from the original Android Browser code, licensed under the Apache License, Version 2.0 if (mCustomView == null) return; - Log.d(TAG, "Hiding Custom View"); + LOG.d(TAG, "Hiding Custom View"); // Hide the custom view. mCustomView.setVisibility(View.GONE); @@ -354,6 +354,7 @@ public class CordovaWebViewImpl implements CordovaWebView { case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_BACK: + case KeyEvent.KEYCODE_MENU: // TODO: Why are search and menu buttons handled separately? if (override) { boundKeyCodes.add(keyCode); @@ -445,7 +446,10 @@ public class CordovaWebViewImpl implements CordovaWebView { // Resume JavaScript timers. This affects all webviews within the app! engine.setPaused(false); this.pluginManager.onResume(keepRunning); - // To be the same as other platforms, fire this event only when resumed after a "pause". + + // In order to match the behavior of the other platforms, we only send onResume after an + // onPause has occurred. The resume event might still be sent if the Activity was killed + // while waiting for the result of an external Activity once the result is obtained if (hasPausedEver) { sendJavascriptEvent("resume"); } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CoreAndroid.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CoreAndroid.java index 000717a2..e384f8d7 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CoreAndroid.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/CoreAndroid.java @@ -19,10 +19,6 @@ package org.apache.cordova; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.LOG; -import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -34,17 +30,20 @@ import android.content.IntentFilter; import android.telephony.TelephonyManager; import android.view.KeyEvent; +import java.lang.reflect.Field; import java.util.HashMap; /** * This class exposes methods in Cordova that can be called from JavaScript. */ -class CoreAndroid extends CordovaPlugin { +public class CoreAndroid extends CordovaPlugin { public static final String PLUGIN_NAME = "CoreAndroid"; protected static final String TAG = "CordovaApp"; private BroadcastReceiver telephonyReceiver; private CallbackContext messageChannel; + private PluginResult pendingResume; + private final Object messageChannelLock = new Object(); /** * Send an event to be fired on the Javascript side. @@ -112,7 +111,13 @@ class CoreAndroid extends CordovaPlugin { this.exitApp(); } else if (action.equals("messageChannel")) { - messageChannel = callbackContext; + synchronized(messageChannelLock) { + messageChannel = callbackContext; + if (pendingResume != null) { + sendEventMessage(pendingResume); + pendingResume = null; + } + } return true; } @@ -248,6 +253,9 @@ class CoreAndroid extends CordovaPlugin { else if (button.equals("volumedown")) { webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_DOWN, override); } + else if (button.equals("menubutton")) { + webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_MENU, override); + } } /** @@ -313,10 +321,13 @@ class CoreAndroid extends CordovaPlugin { } catch (JSONException e) { LOG.e(TAG, "Failed to create event message", e); } - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, obj); - pluginResult.setKeepCallback(true); + sendEventMessage(new PluginResult(PluginResult.Status.OK, obj)); + } + + private void sendEventMessage(PluginResult payload) { + payload.setKeepCallback(true); if (messageChannel != null) { - messageChannel.sendPluginResult(pluginResult); + messageChannel.sendPluginResult(payload); } } @@ -328,4 +339,52 @@ class CoreAndroid extends CordovaPlugin { { webView.getContext().unregisterReceiver(this.telephonyReceiver); } + + /** + * Used to send the resume event in the case that the Activity is destroyed by the OS + * + * @param resumeEvent PluginResult containing the payload for the resume event to be fired + */ + public void sendResumeEvent(PluginResult resumeEvent) { + // This operation must be synchronized because plugin results that trigger resume + // events can be processed asynchronously + synchronized(messageChannelLock) { + if (messageChannel != null) { + sendEventMessage(resumeEvent); + } else { + // Might get called before the page loads, so we need to store it until the + // messageChannel gets created + this.pendingResume = resumeEvent; + } + } + } + + /* + * This needs to be implemented if you wish to use the Camera Plugin or other plugins + * that read the Build Configuration. + * + * Thanks to Phil@Medtronic and Graham Borland for finding the answer and posting it to + * StackOverflow. This is annoying as hell! + * + */ + + public static Object getBuildConfigValue(Context ctx, String key) + { + try + { + Class clazz = Class.forName(ctx.getPackageName() + ".BuildConfig"); + Field field = clazz.getField(key); + return field.get(null); + } catch (ClassNotFoundException e) { + LOG.d(TAG, "Unable to get the BuildConfig, is this built with ANT?"); + e.printStackTrace(); + } catch (NoSuchFieldException e) { + LOG.d(TAG, key + " is not a valid field. Check your build.gradle"); + } catch (IllegalAccessException e) { + LOG.d(TAG, "Illegal Access Exception: Let's print a stack trace."); + e.printStackTrace(); + } + + return null; + } } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ExposedJsApi.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ExposedJsApi.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaClientCertRequest.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaClientCertRequest.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaCookieManager.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaCookieManager.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaHttpAuthHandler.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ICordovaHttpAuthHandler.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/LOG.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/LOG.java index 3dd1a754..9fe7a7df 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/LOG.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/LOG.java @@ -154,6 +154,16 @@ public class LOG { if (LOG.INFO >= LOGLEVEL) Log.i(tag, s, e); } + /** + * Warning log message. + * + * @param tag + * @param e + */ + public static void w(String tag, Throwable e) { + if (LOG.WARN >= LOGLEVEL) Log.w(tag, e); + } + /** * Warning log message. * diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/NativeToJsMessageQueue.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/NativeToJsMessageQueue.java index a05e8b81..61d04f17 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/NativeToJsMessageQueue.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/NativeToJsMessageQueue.java @@ -21,8 +21,6 @@ package org.apache.cordova; import java.util.ArrayList; import java.util.LinkedList; -import android.util.Log; - /** * Holds the list of messages to be sent to the WebView. */ @@ -42,13 +40,13 @@ public class NativeToJsMessageQueue { // This currently only chops up on message boundaries. It may be useful // to allow it to break up messages. private static int MAX_PAYLOAD_SIZE = 50 * 1024 * 10240; - + /** * When true, the active listener is not fired upon enqueue. When set to false, - * the active listener will be fired if the queue is non-empty. + * the active listener will be fired if the queue is non-empty. */ private boolean paused; - + /** * The list of JavaScript statements to be sent to JavaScript. */ @@ -58,7 +56,7 @@ public class NativeToJsMessageQueue { * The array of listeners that can be used to send messages to JS. */ private ArrayList bridgeModes = new ArrayList(); - + /** * When null, the bridge is disabled. This occurs during page transitions. * When disabled, all callbacks are dropped since they are assumed to be @@ -83,11 +81,11 @@ public class NativeToJsMessageQueue { */ public void setBridgeMode(int value) { if (value < -1 || value >= bridgeModes.size()) { - Log.d(LOG_TAG, "Invalid NativeToJsBridgeMode: " + value); + LOG.d(LOG_TAG, "Invalid NativeToJsBridgeMode: " + value); } else { BridgeMode newMode = value < 0 ? null : bridgeModes.get(value); if (newMode != activeBridgeMode) { - Log.d(LOG_TAG, "Set native->JS mode to " + (newMode == null ? "null" : newMode.getClass().getSimpleName())); + LOG.d(LOG_TAG, "Set native->JS mode to " + (newMode == null ? "null" : newMode.getClass().getSimpleName())); synchronized (this) { activeBridgeMode = newMode; if (newMode != null) { @@ -100,7 +98,7 @@ public class NativeToJsMessageQueue { } } } - + /** * Clears all messages and resets to the default bridge mode. */ @@ -114,16 +112,16 @@ public class NativeToJsMessageQueue { private int calculatePackedMessageLength(JsMessage message) { int messageLen = message.calculateEncodedLength(); String messageLenStr = String.valueOf(messageLen); - return messageLenStr.length() + messageLen + 1; + return messageLenStr.length() + messageLen + 1; } - + private void packMessage(JsMessage message, StringBuilder sb) { int len = message.calculateEncodedLength(); sb.append(len) .append(' '); message.encodeAsMessage(sb); } - + /** * Combines and returns queued messages combined into a single string. * Combines as many messages as possible, while staying under MAX_PAYLOAD_SIZE. @@ -154,7 +152,7 @@ public class NativeToJsMessageQueue { JsMessage message = queue.removeFirst(); packMessage(message, sb); } - + if (!queue.isEmpty()) { // Attach a char to indicate that there are more messages pending. sb.append('*'); @@ -163,7 +161,7 @@ public class NativeToJsMessageQueue { return ret; } } - + /** * Same as popAndEncode(), except encodes in a form that can be executed as JS. */ @@ -185,7 +183,7 @@ public class NativeToJsMessageQueue { } boolean willSendAllMessages = numMessagesToSend == queue.size(); StringBuilder sb = new StringBuilder(totalPayloadLen + (willSendAllMessages ? 0 : 100)); - // Wrap each statement in a try/finally so that if one throws it does + // Wrap each statement in a try/finally so that if one throws it does // not affect the next. for (int i = 0; i < numMessagesToSend; ++i) { JsMessage message = queue.removeFirst(); @@ -206,7 +204,7 @@ public class NativeToJsMessageQueue { String ret = sb.toString(); return ret; } - } + } /** * Add a JavaScript statement to the list. @@ -220,7 +218,7 @@ public class NativeToJsMessageQueue { */ public void addPluginResult(PluginResult result, String callbackId) { if (callbackId == null) { - Log.e(LOG_TAG, "Got plugin result with no callbackId", new Throwable()); + LOG.e(LOG_TAG, "Got plugin result with no callbackId", new Throwable()); return; } // Don't send anything if there is no result and there is no need to @@ -243,7 +241,7 @@ public class NativeToJsMessageQueue { private void enqueueMessage(JsMessage message) { synchronized (this) { if (activeBridgeMode == null) { - Log.d(LOG_TAG, "Dropping Native->JS message due to disabled bridge"); + LOG.d(LOG_TAG, "Dropping Native->JS message due to disabled bridge"); return; } queue.add(message); @@ -257,7 +255,7 @@ public class NativeToJsMessageQueue { if (paused && value) { // This should never happen. If a use-case for it comes up, we should // change pause to be a counter. - Log.e(LOG_TAG, "nested call to setPaused detected.", new Throwable()); + LOG.e(LOG_TAG, "nested call to setPaused detected.", new Throwable()); } paused = value; if (!value) { @@ -265,7 +263,7 @@ public class NativeToJsMessageQueue { if (!queue.isEmpty() && activeBridgeMode != null) { activeBridgeMode.onNativeToJsMessageAvailable(this); } - } + } } } @@ -351,6 +349,31 @@ public class NativeToJsMessageQueue { } } + /** Uses webView.evaluateJavascript to execute messages. */ + public static class EvalBridgeMode extends BridgeMode { + private final CordovaWebViewEngine engine; + private final CordovaInterface cordova; + + public EvalBridgeMode(CordovaWebViewEngine engine, CordovaInterface cordova) { + this.engine = engine; + this.cordova = cordova; + } + + @Override + public void onNativeToJsMessageAvailable(final NativeToJsMessageQueue queue) { + cordova.getActivity().runOnUiThread(new Runnable() { + public void run() { + String js = queue.popAndEncodeAsJs(); + if (js != null) { + engine.evaluateJavascript(js, null); + } + } + }); + } + } + + + private static class JsMessage { final String jsPayloadOrCallbackId; final PluginResult pluginResult; @@ -368,7 +391,7 @@ public class NativeToJsMessageQueue { jsPayloadOrCallbackId = callbackId; this.pluginResult = pluginResult; } - + static int calculateEncodedLengthHelper(PluginResult pluginResult) { switch (pluginResult.getMessageType()) { case PluginResult.MESSAGE_TYPE_BOOLEAN: // f or t @@ -395,7 +418,7 @@ public class NativeToJsMessageQueue { return pluginResult.getMessage().length(); } } - + int calculateEncodedLength() { if (pluginResult == null) { return jsPayloadOrCallbackId.length() + 1; @@ -424,7 +447,7 @@ public class NativeToJsMessageQueue { case PluginResult.MESSAGE_TYPE_BINARYSTRING: // S sb.append('S'); sb.append(pluginResult.getMessage()); - break; + break; case PluginResult.MESSAGE_TYPE_ARRAYBUFFER: // A sb.append('A'); sb.append(pluginResult.getMessage()); @@ -443,7 +466,7 @@ public class NativeToJsMessageQueue { sb.append(pluginResult.getMessage()); // [ or { } } - + void encodeAsMessage(StringBuilder sb) { if (pluginResult == null) { sb.append('J') diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginManager.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginManager.java index a541e770..c9576a6c 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginManager.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginManager.java @@ -26,8 +26,8 @@ import org.json.JSONException; import android.content.Intent; import android.content.res.Configuration; import android.net.Uri; +import android.os.Bundle; import android.os.Debug; -import android.util.Log; /** * PluginManager is exposed to JavaScript in the Cordova WebView. @@ -47,6 +47,8 @@ public class PluginManager { private final CordovaWebView app; private boolean isInitialized; + private CordovaPlugin permissionRequester; + public PluginManager(CordovaWebView cordovaWebView, CordovaInterface cordova, Collection pluginEntries) { this.ctx = cordova; this.app = cordovaWebView; @@ -119,7 +121,7 @@ public class PluginManager { public void exec(final String service, final String action, final String callbackId, final String rawArgs) { CordovaPlugin plugin = getPlugin(service); if (plugin == null) { - Log.d(TAG, "exec() call to unknown plugin: " + service); + LOG.d(TAG, "exec() call to unknown plugin: " + service); PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION); app.sendPluginResult(cr, callbackId); return; @@ -131,7 +133,7 @@ public class PluginManager { long duration = System.currentTimeMillis() - pluginStartTime; if (duration > SLOW_EXEC_WARNING_THRESHOLD) { - Log.w(TAG, "THREAD WARNING: exec() call to " + service + "." + action + " blocked the main thread for " + duration + "ms. Plugin should use CordovaInterface.getThreadPool()."); + LOG.w(TAG, "THREAD WARNING: exec() call to " + service + "." + action + " blocked the main thread for " + duration + "ms. Plugin should use CordovaInterface.getThreadPool()."); } if (!wasValidAction) { PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION); @@ -141,7 +143,7 @@ public class PluginManager { PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION); callbackContext.sendPluginResult(cr); } catch (Exception e) { - Log.e(TAG, "Uncaught exception from plugin", e); + LOG.e(TAG, "Uncaught exception from plugin", e); callbackContext.error(e.getMessage()); } } @@ -219,9 +221,9 @@ public class PluginManager { * @param handler The HttpAuthHandler used to set the WebView's response * @param host The host requiring authentication * @param realm The realm for which authentication is required - * + * * @return Returns True if there is a plugin which will resolve this auth challenge, otherwise False - * + * */ public boolean onReceivedHttpAuthRequest(CordovaWebView view, ICordovaHttpAuthHandler handler, String host, String realm) { for (CordovaPlugin plugin : this.pluginMap.values()) { @@ -231,7 +233,7 @@ public class PluginManager { } return false; } - + /** * Called when he system received an SSL client certificate request. Plugin can use * the supplied ClientCertRequest to process this certificate challenge. @@ -508,4 +510,17 @@ public class PluginManager { } } } + + public Bundle onSaveInstanceState() { + Bundle state = new Bundle(); + for (CordovaPlugin plugin : this.pluginMap.values()) { + if (plugin != null) { + Bundle pluginState = plugin.onSaveInstanceState(); + if(pluginState != null) { + state.putBundle(plugin.getServiceName(), pluginState); + } + } + } + return state; + } } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginResult.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/PluginResult.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ResumeCallback.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ResumeCallback.java new file mode 100644 index 00000000..49a43b5d --- /dev/null +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/ResumeCallback.java @@ -0,0 +1,76 @@ +/* + 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. +*/ +package org.apache.cordova; + + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class ResumeCallback extends CallbackContext { + private final String TAG = "CordovaResumeCallback"; + private String serviceName; + private PluginManager pluginManager; + + public ResumeCallback(String serviceName, PluginManager pluginManager) { + super("resumecallback", null); + this.serviceName = serviceName; + this.pluginManager = pluginManager; + } + + @Override + public void sendPluginResult(PluginResult pluginResult) { + synchronized (this) { + if (finished) { + LOG.w(TAG, serviceName + " attempted to send a second callback to ResumeCallback\nResult was: " + pluginResult.getMessage()); + return; + } else { + finished = true; + } + } + + JSONObject event = new JSONObject(); + JSONObject pluginResultObject = new JSONObject(); + + try { + pluginResultObject.put("pluginServiceName", this.serviceName); + pluginResultObject.put("pluginStatus", PluginResult.StatusMessages[pluginResult.getStatus()]); + + event.put("action", "resume"); + event.put("pendingResult", pluginResultObject); + } catch (JSONException e) { + LOG.e(TAG, "Unable to create resume object for Activity Result"); + } + + PluginResult eventResult = new PluginResult(PluginResult.Status.OK, event); + + // We send a list of results to the js so that we don't have to decode + // the PluginResult passed to this CallbackContext into JSON twice. + // The results are combined into an event payload before the event is + // fired on the js side of things (see platform.js) + List result = new ArrayList(); + result.add(eventResult); + result.add(pluginResult); + + CoreAndroid appPlugin = (CoreAndroid) pluginManager.getPlugin(CoreAndroid.PLUGIN_NAME); + appPlugin.sendResumeEvent(new PluginResult(PluginResult.Status.OK, result)); + } +} diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Whitelist.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/Whitelist.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemCookieManager.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemCookieManager.java old mode 100755 new mode 100644 index ae55dfee..acf795fa --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemCookieManager.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemCookieManager.java @@ -19,6 +19,7 @@ package org.apache.cordova.engine; +import android.annotation.TargetApi; import android.os.Build; import android.webkit.CookieManager; import android.webkit.WebView; @@ -30,10 +31,15 @@ class SystemCookieManager implements ICordovaCookieManager { protected final WebView webView; private final CookieManager cookieManager; + //Added because lint can't see the conditional RIGHT ABOVE this + @TargetApi(Build.VERSION_CODES.LOLLIPOP) public SystemCookieManager(WebView webview) { webView = webview; cookieManager = CookieManager.getInstance(); + //REALLY? Nobody has seen this UNTIL NOW? + cookieManager.setAcceptFileSchemeCookies(true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.setAcceptThirdPartyCookies(webView, true); } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebChromeClient.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebChromeClient.java index 3b5866c3..3ea5e576 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebChromeClient.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebChromeClient.java @@ -21,11 +21,11 @@ package org.apache.cordova.engine; import java.util.Arrays; import android.annotation.TargetApi; import android.app.Activity; +import android.content.Context; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.os.Build; -import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup.LayoutParams; @@ -61,15 +61,17 @@ public class SystemWebChromeClient extends WebChromeClient { // the video progress view private View mVideoProgressView; - + private CordovaDialogsHelper dialogsHelper; + private Context appContext; private WebChromeClient.CustomViewCallback mCustomViewCallback; private View mCustomView; public SystemWebChromeClient(SystemWebViewEngine parentEngine) { this.parentEngine = parentEngine; - dialogsHelper = new CordovaDialogsHelper(parentEngine.webView.getContext()); + appContext = parentEngine.webView.getContext(); + dialogsHelper = new CordovaDialogsHelper(appContext); } /** @@ -174,14 +176,23 @@ public class SystemWebChromeClient extends WebChromeClient { /** * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin. * + * This also checks for the Geolocation Plugin and requests permission from the application to use Geolocation. + * * @param origin * @param callback */ public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { super.onGeolocationPermissionsShowPrompt(origin, callback); callback.invoke(origin, true, false); + //Get the plugin, it should be loaded + CordovaPlugin geolocation = parentEngine.pluginManager.getPlugin("Geolocation"); + if(geolocation != null && !geolocation.hasPermisssion()) + { + geolocation.requestPermissions(0); + } + } - + // API level 7 is required for this, see if we could lower this using something else @Override public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) { @@ -201,9 +212,9 @@ public class SystemWebChromeClient extends WebChromeClient { */ public View getVideoLoadingProgressView() { - if (mVideoProgressView == null) { + if (mVideoProgressView == null) { // Create a new Loading view programmatically. - + // create the linear layout LinearLayout layout = new LinearLayout(parentEngine.getView().getContext()); layout.setOrientation(LinearLayout.VERTICAL); @@ -214,12 +225,12 @@ public class SystemWebChromeClient extends WebChromeClient { ProgressBar bar = new ProgressBar(parentEngine.getView().getContext()); LinearLayout.LayoutParams barLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); barLayoutParams.gravity = Gravity.CENTER; - bar.setLayoutParams(barLayoutParams); + bar.setLayoutParams(barLayoutParams); layout.addView(bar); - + mVideoProgressView = layout; } - return mVideoProgressView; + return mVideoProgressView; } // support: @@ -228,11 +239,11 @@ public class SystemWebChromeClient extends WebChromeClient { public void openFileChooser(ValueCallback uploadMsg) { this.openFileChooser(uploadMsg, "*/*"); } - + public void openFileChooser( ValueCallback uploadMsg, String acceptType ) { this.openFileChooser(uploadMsg, acceptType, null); } - + public void openFileChooser(final ValueCallback uploadMsg, String acceptType, String capture) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); @@ -242,7 +253,7 @@ public class SystemWebChromeClient extends WebChromeClient { @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData(); - Log.d(LOG_TAG, "Receive file chooser URL: " + result); + LOG.d(LOG_TAG, "Receive file chooser URL: " + result); uploadMsg.onReceiveValue(result); } }, intent, FILECHOOSER_RESULTCODE); @@ -257,12 +268,12 @@ public class SystemWebChromeClient extends WebChromeClient { @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { Uri[] result = WebChromeClient.FileChooserParams.parseResult(resultCode, intent); - Log.d(LOG_TAG, "Receive file chooser URL: " + result); + LOG.d(LOG_TAG, "Receive file chooser URL: " + result); filePathsCallback.onReceiveValue(result); } }, intent, FILECHOOSER_RESULTCODE); } catch (ActivityNotFoundException e) { - Log.w("No activity found to handle file chooser intent.", e); + LOG.w("No activity found to handle file chooser intent.", e); filePathsCallback.onReceiveValue(null); } return true; @@ -271,7 +282,7 @@ public class SystemWebChromeClient extends WebChromeClient { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onPermissionRequest(final PermissionRequest request) { - Log.d(LOG_TAG, "onPermissionRequest: " + Arrays.toString(request.getResources())); + LOG.d(LOG_TAG, "onPermissionRequest: " + Arrays.toString(request.getResources())); request.grant(request.getResources()); } diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebView.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebView.java old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewEngine.java b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewEngine.java index 221a884c..0fa02767 100755 --- a/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewEngine.java +++ b/StoneIsland/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewEngine.java @@ -27,8 +27,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.os.Build; -import android.util.Log; import android.view.View; +import android.webkit.ValueCallback; import android.webkit.WebSettings; import android.webkit.WebSettings.LayoutAlgorithm; import android.webkit.WebView; @@ -40,6 +40,7 @@ import org.apache.cordova.CordovaResourceApi; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaWebViewEngine; import org.apache.cordova.ICordovaCookieManager; +import org.apache.cordova.LOG; import org.apache.cordova.NativeToJsMessageQueue; import org.apache.cordova.PluginManager; @@ -116,7 +117,9 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { SystemWebViewEngine.this.cordova.getActivity().runOnUiThread(r); } })); - bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue); + if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) + nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.EvalBridgeMode(this, cordova)); + bridge = new CordovaBridge(pluginManager, nativeToJsMessageQueue); exposeJsInterface(webView, bridge); } @@ -135,7 +138,7 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { return webView; } - @SuppressLint("SetJavaScriptEnabled") + @SuppressLint({"NewApi", "SetJavaScriptEnabled"}) @SuppressWarnings("deprecation") private void initWebViewSettings() { webView.setInitialScale(0); @@ -145,32 +148,32 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { settings.setJavaScriptEnabled(true); settings.setJavaScriptCanOpenWindowsAutomatically(true); settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL); - + // Set the nav dump for HTC 2.x devices (disabling for ICS, deprecated entirely for Jellybean 4.2) try { Method gingerbread_getMethod = WebSettings.class.getMethod("setNavDump", new Class[] { boolean.class }); - + String manufacturer = android.os.Build.MANUFACTURER; - Log.d(TAG, "CordovaWebView is running on device made by: " + manufacturer); + LOG.d(TAG, "CordovaWebView is running on device made by: " + manufacturer); if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB && android.os.Build.MANUFACTURER.contains("HTC")) { gingerbread_getMethod.invoke(settings, true); } } catch (NoSuchMethodException e) { - Log.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8"); + LOG.d(TAG, "We are on a modern version of Android, we will deprecate HTC 2.3 devices in 2.8"); } catch (IllegalArgumentException e) { - Log.d(TAG, "Doing the NavDump failed with bad arguments"); + LOG.d(TAG, "Doing the NavDump failed with bad arguments"); } catch (IllegalAccessException e) { - Log.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore"); + LOG.d(TAG, "This should never happen: IllegalAccessException means this isn't Android anymore"); } catch (InvocationTargetException e) { - Log.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore."); + LOG.d(TAG, "This should never happen: InvocationTargetException means this isn't Android anymore."); } //We don't save any form data in the application settings.setSaveFormData(false); settings.setSavePassword(false); - + // Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist // while we do this if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { @@ -184,15 +187,15 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { String databasePath = webView.getContext().getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); settings.setDatabaseEnabled(true); settings.setDatabasePath(databasePath); - - + + //Determine whether we're in debug or release mode, and turn on Debugging! ApplicationInfo appInfo = webView.getContext().getApplicationContext().getApplicationInfo(); if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { enableRemoteDebugging(); } - + settings.setGeolocationDatabasePath(databasePath); // Enable DOM storage @@ -200,13 +203,13 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { // Enable built-in geolocation settings.setGeolocationEnabled(true); - + // Enable AppCache // Fix for CB-2282 settings.setAppCacheMaxSize(5 * 1048576); settings.setAppCachePath(databasePath); settings.setAppCacheEnabled(true); - + // Fix for CB-1405 // Google issue 4641 String defaultUserAgent = settings.getUserAgentString(); @@ -222,7 +225,7 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { } } // End CB-3360 - + IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); if (this.receiver == null) { @@ -242,18 +245,18 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { try { WebView.setWebContentsDebuggingEnabled(true); } catch (IllegalArgumentException e) { - Log.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! "); + LOG.d(TAG, "You have one job! To turn on Remote Web Debugging! YOU HAVE FAILED! "); e.printStackTrace(); } } private static void exposeJsInterface(WebView webView, CordovaBridge bridge) { if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)) { - Log.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old."); + LOG.i(TAG, "Disabled addJavascriptInterface() bridge since Android version is old."); // Bug being that Java Strings do not get converted to JS strings automatically. // This isn't hard to work-around on the JS side, but it's easier to just // use the prompt bridge instead. - return; + return; } SystemExposedJsApi exposedJsApi = new SystemExposedJsApi(bridge); webView.addJavascriptInterface(exposedJsApi, "_cordovaNative"); @@ -312,8 +315,10 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { @Override public void setPaused(boolean value) { if (value) { + webView.onPause(); webView.pauseTimers(); } else { + webView.onResume(); webView.resumeTimers(); } } @@ -327,8 +332,19 @@ public class SystemWebViewEngine implements CordovaWebViewEngine { try { webView.getContext().unregisterReceiver(receiver); } catch (Exception e) { - Log.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e); + LOG.e(TAG, "Error unregistering configuration receiver: " + e.getMessage(), e); } } } + + @Override + public void evaluateJavascript(String js, ValueCallback callback) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + webView.evaluateJavascript(js, callback); + } + else + { + LOG.d(TAG, "This webview is using the old bridge"); + } + } } diff --git a/StoneIsland/platforms/android/android.json b/StoneIsland/platforms/android/android.json index 587c7239..d345c65d 100755 --- a/StoneIsland/platforms/android/android.json +++ b/StoneIsland/platforms/android/android.json @@ -51,6 +51,10 @@ { "xml": "", "count": 1 + }, + { + "xml": "", + "count": 1 } ] } @@ -73,20 +77,44 @@ { "xml": "", "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 } ], "/manifest": [ { "xml": "", - "count": 1 + "count": 2 }, { "xml": "", - "count": 1 + "count": 2 }, { "xml": "", - "count": 1 + "count": 2 }, { "xml": "", @@ -94,7 +122,7 @@ }, { "xml": "", - "count": 1 + "count": 2 }, { "xml": "", @@ -102,7 +130,7 @@ }, { "xml": "", - "count": 1 + "count": 2 }, { "xml": "", @@ -111,6 +139,22 @@ { "xml": "", "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 + }, + { + "xml": "", + "count": 1 } ], "/*/application/activity": [], @@ -161,6 +205,16 @@ } ] } + }, + "res/values/strings.xml": { + "parents": { + "/resources": [ + { + "xml": "XXXXXXX", + "count": 1 + } + ] + } } } }, @@ -209,6 +263,10 @@ }, "ionic-plugin-keyboard": { "PACKAGE_NAME": "us.okfoc.stoneisland" + }, + "phonegap-plugin-push": { + "SENDER_ID": "XXXXXXX", + "PACKAGE_NAME": "us.okfoc.stoneisland" } }, "dependent_plugins": {}, @@ -317,6 +375,14 @@ "cordova.plugins.Keyboard" ], "runs": true + }, + { + "id": "phonegap-plugin-push.PushNotification", + "file": "plugins/phonegap-plugin-push/www/push.js", + "pluginId": "phonegap-plugin-push", + "clobbers": [ + "PushNotification" + ] } ], "plugin_metadata": { @@ -332,6 +398,7 @@ "cordova-plugin-splashscreen": "4.0.0", "cordova-plugin-compat": "1.1.0", "cordova-plugin-geolocation": "2.4.0", - "ionic-plugin-keyboard": "2.2.1" + "ionic-plugin-keyboard": "2.2.1", + "phonegap-plugin-push": "1.9.2" } } \ No newline at end of file diff --git a/StoneIsland/platforms/android/assets/www/cordova-js-src/android/nativeapiprovider.js b/StoneIsland/platforms/android/assets/www/cordova-js-src/android/nativeapiprovider.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/assets/www/cordova-js-src/android/promptbasednativeapi.js b/StoneIsland/platforms/android/assets/www/cordova-js-src/android/promptbasednativeapi.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/assets/www/cordova-js-src/exec.js b/StoneIsland/platforms/android/assets/www/cordova-js-src/exec.js old mode 100755 new mode 100644 index fa8b41be..f73d87a1 --- a/StoneIsland/platforms/android/assets/www/cordova-js-src/exec.js +++ b/StoneIsland/platforms/android/assets/www/cordova-js-src/exec.js @@ -51,10 +51,11 @@ var cordova = require('cordova'), // For the ONLINE_EVENT to be viable, it would need to intercept all event // listeners (both through addEventListener and window.ononline) as well // as set the navigator property itself. - ONLINE_EVENT: 2 + ONLINE_EVENT: 2, + EVAL_BRIDGE: 3 }, jsToNativeBridgeMode, // Set lazily. - nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, + nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE, pollEnabled = false, bridgeSecret = -1; @@ -77,6 +78,9 @@ function androidExec(success, fail, service, action, args) { androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } + // If args is not provided, default to an empty array + args = args || []; + // Process any ArrayBuffers in the args into a string. for (var i = 0; i < args.length; i++) { if (utils.typeName(args[i]) == 'ArrayBuffer') { @@ -86,7 +90,6 @@ function androidExec(success, fail, service, action, args) { var callbackId = service + cordova.callbackId++, argsJson = JSON.stringify(args); - if (success || fail) { cordova.callbacks[callbackId] = {success:success, fail:fail}; } @@ -106,6 +109,17 @@ function androidExec(success, fail, service, action, args) { } androidExec.init = function() { + //CB-11828 + //This failsafe checks the version of Android and if it's Jellybean, it switches it to + //using the Online Event bridge for communicating from Native to JS + // + //It's ugly, but it's necessary. + var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/); + var version_code = check && check[0].match(/4.[0-3].*/); + if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) { + nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT; + } + bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode); channel.onNativeReady.fire(); }; diff --git a/StoneIsland/platforms/android/assets/www/cordova-js-src/platform.js b/StoneIsland/platforms/android/assets/www/cordova-js-src/platform.js old mode 100755 new mode 100644 index bffc6751..2bfd0247 --- a/StoneIsland/platforms/android/assets/www/cordova-js-src/platform.js +++ b/StoneIsland/platforms/android/assets/www/cordova-js-src/platform.js @@ -19,6 +19,9 @@ * */ +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -58,6 +61,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -79,12 +95,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } diff --git a/StoneIsland/platforms/android/assets/www/cordova-js-src/plugin/android/app.js b/StoneIsland/platforms/android/assets/www/cordova-js-src/plugin/android/app.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/assets/www/cordova.js b/StoneIsland/platforms/android/assets/www/cordova.js old mode 100755 new mode 100644 index 23f6e475..18c020e7 --- a/StoneIsland/platforms/android/assets/www/cordova.js +++ b/StoneIsland/platforms/android/assets/www/cordova.js @@ -1,5 +1,5 @@ // Platform: android -// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c +// 7c5fcc5a5adfbf3fb8ceaf36fbdd4bd970bd9c20 /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file @@ -19,7 +19,7 @@ under the License. */ ;(function() { -var PLATFORM_VERSION_BUILD_LABEL = '4.1.1'; +var PLATFORM_VERSION_BUILD_LABEL = '6.1.2'; // file: src/scripts/require.js /*jshint -W079 */ @@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { // file: src/cordova.js define("cordova", function(require, exports, module) { -if(window.cordova){ +// 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)) { throw new Error("cordova already defined"); } @@ -740,8 +742,13 @@ var Channel = function(type, sticky) { } }; -function forceFunction(f) { - if (typeof f != 'function') throw "Function required as first argument!"; +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." + ); + } } /** @@ -751,28 +758,39 @@ function forceFunction(f) { * and a guid that can be used to stop subscribing to the channel. * Returns the guid. */ -Channel.prototype.subscribe = function(f, c) { - // need a function to call - forceFunction(f); +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) { - f.apply(c || this, this.fireArgs); + handleEvent.apply(eventListener || this, this.fireArgs); return; } - var func = f, - guid = f.observer_guid; - if (typeof c == "object") { func = utils.close(c, f); } + guid = eventListenerOrFunction.observer_guid; + if (typeof eventListener === "object") { + handleEvent = utils.close(eventListener, handleEvent); + } if (!guid) { - // first time any channel has seen this subscriber + // First time any channel has seen this subscriber guid = '' + nextGuid++; } - func.observer_guid = guid; - f.observer_guid = guid; + handleEvent.observer_guid = guid; + eventListenerOrFunction.observer_guid = guid; // Don't add the same handler more than once. if (!this.handlers[guid]) { - this.handlers[guid] = func; + this.handlers[guid] = handleEvent; this.numHandlers++; if (this.numHandlers == 1) { this.onHasSubscribersChange && this.onHasSubscribersChange(); @@ -783,12 +801,20 @@ Channel.prototype.subscribe = function(f, c) { /** * Unsubscribes the function with the given guid from the channel. */ -Channel.prototype.unsubscribe = function(f) { - // need a function to unsubscribe - forceFunction(f); +Channel.prototype.unsubscribe = function(eventListenerOrFunction) { + checkSubscriptionArgument(eventListenerOrFunction); + var handleEvent, guid, handler; - var guid = f.observer_guid, - handler = this.handlers[guid]; + 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--; @@ -895,10 +921,11 @@ var cordova = require('cordova'), // For the ONLINE_EVENT to be viable, it would need to intercept all event // listeners (both through addEventListener and window.ononline) as well // as set the navigator property itself. - ONLINE_EVENT: 2 + ONLINE_EVENT: 2, + EVAL_BRIDGE: 3 }, jsToNativeBridgeMode, // Set lazily. - nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, + nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE, pollEnabled = false, bridgeSecret = -1; @@ -921,6 +948,9 @@ function androidExec(success, fail, service, action, args) { androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } + // If args is not provided, default to an empty array + args = args || []; + // Process any ArrayBuffers in the args into a string. for (var i = 0; i < args.length; i++) { if (utils.typeName(args[i]) == 'ArrayBuffer') { @@ -930,7 +960,6 @@ function androidExec(success, fail, service, action, args) { var callbackId = service + cordova.callbackId++, argsJson = JSON.stringify(args); - if (success || fail) { cordova.callbacks[callbackId] = {success:success, fail:fail}; } @@ -950,6 +979,17 @@ function androidExec(success, fail, service, action, args) { } androidExec.init = function() { + //CB-11828 + //This failsafe checks the version of Android and if it's Jellybean, it switches it to + //using the Online Event bridge for communicating from Native to JS + // + //It's ugly, but it's necessary. + var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/); + var version_code = check && check[0].match(/4.[0-3].*/); + if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) { + nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT; + } + bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode); channel.onNativeReady.fire(); }; @@ -1291,10 +1331,12 @@ 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]; +var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady]; // setting exec cordova.exec = require('cordova/exec'); @@ -1379,10 +1421,19 @@ if (window._nativeReady) { // 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(); @@ -1499,11 +1550,111 @@ exports.getOriginalSymbol = function(context, symbolPath) { exports.reset(); +}); + +// file: src/common/modulemapper_b.js +define("cordova/modulemapper_b", function(require, exports, module) { + +var builder = require('cordova/builder'), + symbolList = [], + 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) { + 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); + // + 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/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js define("cordova/platform", function(require, exports, module) { +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -1543,6 +1694,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -1564,12 +1728,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } @@ -1673,10 +1855,6 @@ module.exports = { // file: src/common/pluginloader.js define("cordova/pluginloader", function(require, exports, module) { -/* - NOTE: this file is NOT used when we use the browserify workflow -*/ - var modulemapper = require('cordova/modulemapper'); var urlutil = require('cordova/urlutil'); @@ -1784,6 +1962,54 @@ exports.load = function(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++) { + 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 @@ -1895,7 +2121,10 @@ utils.clone = function(obj) { retVal = {}; for(i in obj){ - if(!(i in retVal) || retVal[i] != obj[i]) { + // 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') { retVal[i] = utils.clone(obj[i]); } } diff --git a/StoneIsland/platforms/android/assets/www/cordova_plugins.js b/StoneIsland/platforms/android/assets/www/cordova_plugins.js index a2734881..722b1683 100755 --- a/StoneIsland/platforms/android/assets/www/cordova_plugins.js +++ b/StoneIsland/platforms/android/assets/www/cordova_plugins.js @@ -104,6 +104,14 @@ module.exports = [ "cordova.plugins.Keyboard" ], "runs": true + }, + { + "id": "phonegap-plugin-push.PushNotification", + "file": "plugins/phonegap-plugin-push/www/push.js", + "pluginId": "phonegap-plugin-push", + "clobbers": [ + "PushNotification" + ] } ]; module.exports.metadata = @@ -121,7 +129,8 @@ module.exports.metadata = "cordova-plugin-splashscreen": "4.0.0", "cordova-plugin-compat": "1.1.0", "cordova-plugin-geolocation": "2.4.0", - "ionic-plugin-keyboard": "2.2.1" -} + "ionic-plugin-keyboard": "2.2.1", + "phonegap-plugin-push": "1.9.2" +}; // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/StoneIsland/platforms/android/assets/www/css/products.css b/StoneIsland/platforms/android/assets/www/css/products.css index e067e05a..bdfed42a 100755 --- a/StoneIsland/platforms/android/assets/www/css/products.css +++ b/StoneIsland/platforms/android/assets/www/css/products.css @@ -24,7 +24,6 @@ height: 126vw; } - .product #product { display: block } #product { display: none; @@ -224,7 +223,11 @@ padding-bottom:45px; } #collection h1 { -background:white + background-color: white; + background-image: url(../img/angle-down.png); + background-size: contain; + background-position: top right; + background-repeat: no-repeat; } #selector { diff --git a/StoneIsland/platforms/android/assets/www/img/angle-down.png b/StoneIsland/platforms/android/assets/www/img/angle-down.png new file mode 100644 index 00000000..e0b3b00f Binary files /dev/null and b/StoneIsland/platforms/android/assets/www/img/angle-down.png differ diff --git a/StoneIsland/platforms/android/assets/www/index.html b/StoneIsland/platforms/android/assets/www/index.html index 768e3140..9c86e559 100755 --- a/StoneIsland/platforms/android/assets/www/index.html +++ b/StoneIsland/platforms/android/assets/www/index.html @@ -355,7 +355,7 @@

- BIRTHDAY (MM/DD/YYYY) + BIRTHDAY (OPTIONAL)
@@ -1136,6 +1136,7 @@ + diff --git a/StoneIsland/platforms/android/assets/www/js/index.js b/StoneIsland/platforms/android/assets/www/js/index.js index 6bea75d0..76a8af05 100755 --- a/StoneIsland/platforms/android/assets/www/js/index.js +++ b/StoneIsland/platforms/android/assets/www/js/index.js @@ -8,7 +8,7 @@ var app = (function(){ app.bind() app.build() - + app.iscroll_options = { mouseWheel: true, scrollbars: true, diff --git a/StoneIsland/platforms/android/assets/www/js/lib/auth/SignupView.js b/StoneIsland/platforms/android/assets/www/js/lib/auth/SignupView.js index 8d9cf52d..fd0c1887 100755 --- a/StoneIsland/platforms/android/assets/www/js/lib/auth/SignupView.js +++ b/StoneIsland/platforms/android/assets/www/js/lib/auth/SignupView.js @@ -49,7 +49,7 @@ var SignupView = FormView.extend({ "Surname": "Please enter your last name.", "Email": "Please enter a valid email address.", "ConfirmEmail": "Please enter a valid email address.", - "BirthDay": "Please enter your birthday.", + // "BirthDay": "Please enter your birthday.", "Password": "Please enter your password.", "Password2": "Please enter your password again.", "DataProfiling": "You must agree to data profiling.", diff --git a/StoneIsland/platforms/android/assets/www/js/lib/blogs/BlogView.js b/StoneIsland/platforms/android/assets/www/js/lib/blogs/BlogView.js index b7c80520..5ee7f641 100755 --- a/StoneIsland/platforms/android/assets/www/js/lib/blogs/BlogView.js +++ b/StoneIsland/platforms/android/assets/www/js/lib/blogs/BlogView.js @@ -31,7 +31,7 @@ var BlogView = View.extend({ this.loaded = true this.data = data = typeof data == "string" ? JSON.parse(data) : data - switch (data.store[0].StoreStatus) { + switch (data.store[0].DepartmentStoreStatus) { case "open": app.closed.storeIsClosed = false break @@ -46,9 +46,9 @@ var BlogView = View.extend({ app.closed.populate(data.store[0].ClosedStoreImages) } else { - app.gallery_id = data.store[0].CollectionId - app.department_id = data.store[0].DepartmentId - app.collection.setCollectionName( data.store[0].collection ) + app.departments = data.store[0].Departments + app.department_id = data.store[0].Departments[0].uri + app.collection.setCollectionName( data.store[0].Departments[0].text ) app.collection.loaded = false app.collection.fetch() } diff --git a/StoneIsland/platforms/android/assets/www/js/lib/blogs/HubView.js b/StoneIsland/platforms/android/assets/www/js/lib/blogs/HubView.js index 1657d295..013c2b45 100755 --- a/StoneIsland/platforms/android/assets/www/js/lib/blogs/HubView.js +++ b/StoneIsland/platforms/android/assets/www/js/lib/blogs/HubView.js @@ -167,6 +167,7 @@ var HubLoader = (function(){ } HubLoader.build = function(){ view.append(item) + view.scroller.refresh() setTimeout(HubLoader.load, 20) } return HubLoader diff --git a/StoneIsland/platforms/android/assets/www/js/lib/products/CollectionView.js b/StoneIsland/platforms/android/assets/www/js/lib/products/CollectionView.js index b9a7755f..671d36b3 100755 --- a/StoneIsland/platforms/android/assets/www/js/lib/products/CollectionView.js +++ b/StoneIsland/platforms/android/assets/www/js/lib/products/CollectionView.js @@ -14,6 +14,7 @@ var CollectionView = ScrollableView.extend({ "mousedown .item": "touchstart", "mousemove .item": "touchmove", "mouseup .item": "touchend", + "touchstart h1": "showDepartmentSelector", }, initialize: function(){ @@ -21,7 +22,7 @@ var CollectionView = ScrollableView.extend({ this.$content = this.$(".content") this.$loader = this.$(".loader") this.scroller = new IScroll('#collection', app.iscroll_options) - this.filterView = new CategoryFilter ({ parent: this }) + this.filterView = new DepartmentFilter ({ parent: this }) }, show: function(){ @@ -85,7 +86,7 @@ var CollectionView = ScrollableView.extend({ } console.log(">>>>>>>> YES ") if (! this.loaded) { - console.log("populate 3") + console.log("populate 3", data.SearchResponseFull.Results.Items.length) this.loaded = true this.$loader.hide() this.$content.empty() @@ -140,6 +141,10 @@ var CollectionView = ScrollableView.extend({ this.$title.html(this.collectionName) }, + showDepartmentSelector: function(){ + this.filterView.filter() + }, + firstTouch: { x: 0, y: 0, id: "" }, lastTouch: { x: 0, y: 0, id: "" }, touchstart: function(e){ diff --git a/StoneIsland/platforms/android/assets/www/js/lib/products/ProductView.js b/StoneIsland/platforms/android/assets/www/js/lib/products/ProductView.js index cfb39f20..81ad536d 100755 --- a/StoneIsland/platforms/android/assets/www/js/lib/products/ProductView.js +++ b/StoneIsland/platforms/android/assets/www/js/lib/products/ProductView.js @@ -118,8 +118,8 @@ var ProductView = ScrollableView.extend({ var title = name_partz.join(' ') var type = title_case( data['MicroCategory'] ) var price = "$" + data['DiscountedPrice'] + ".00" - var body = descriptions['Details'] + "
" + descriptions['EditorialDescription'] - body = body.replace(/
/g, "

").replace(/(
)+$/, "") + var body = descriptions['Details'] + " " + descriptions['EditorialDescription'] + // body = body.replace(/
/g, "

").replace(/(
)+$/, "") var default_color_id = this.populate_selectors(data, details) diff --git a/StoneIsland/platforms/android/assets/www/js/lib/products/Selector.js b/StoneIsland/platforms/android/assets/www/js/lib/products/Selector.js index 6db33b68..9c1109f6 100755 --- a/StoneIsland/platforms/android/assets/www/js/lib/products/Selector.js +++ b/StoneIsland/platforms/android/assets/www/js/lib/products/Selector.js @@ -5,7 +5,7 @@ var Selector = View.extend({ events: { "click .close": "hide", - "click .options div": "pick", + "touchstart .options div": "pick", }, initialize: function(){ @@ -67,4 +67,4 @@ var Selector = View.extend({ this.hide() }, -}) \ No newline at end of file +}) diff --git a/StoneIsland/platforms/android/assets/www/js/lib/products/filters/DepartmentFilter.js b/StoneIsland/platforms/android/assets/www/js/lib/products/filters/DepartmentFilter.js new file mode 100644 index 00000000..cc0d925e --- /dev/null +++ b/StoneIsland/platforms/android/assets/www/js/lib/products/filters/DepartmentFilter.js @@ -0,0 +1,31 @@ +var DepartmentFilter = View.extend({ + + initialize: function(opt){ + this.parent = opt.parent + }, + + filter: function(){ + var deps = app.departments.map(function(dep){ + console.log(dep) + return { + id: dep.uri, + label: dep.text, + } + }) + app.selector.select("wide", deps, this.pick.bind(this)) + }, + + last_choice: null, + + pick: function(choice){ + this.parent.$content.empty() + this.last_choice = choice + app.department_id = choice.id + app.collection.loaded = false + app.collection.fetch() + app.footer.hide() + app.collection.setCollectionName(choice.label) + this.parent.deferScrollToTop() + }, + +}) diff --git a/StoneIsland/platforms/android/assets/www/plugins/phonegap-plugin-push/www/push.js b/StoneIsland/platforms/android/assets/www/plugins/phonegap-plugin-push/www/push.js new file mode 100644 index 00000000..a5315486 --- /dev/null +++ b/StoneIsland/platforms/android/assets/www/plugins/phonegap-plugin-push/www/push.js @@ -0,0 +1,329 @@ +cordova.define("phonegap-plugin-push.PushNotification", function(require, exports, module) { +/* global cordova:false */ +/* globals window */ + +/*! + * Module dependencies. + */ + +var exec = cordova.require('cordova/exec'); + +/** + * PushNotification constructor. + * + * @param {Object} options to initiate Push Notifications. + * @return {PushNotification} instance that can be monitored and cancelled. + */ + +var PushNotification = function(options) { + this._handlers = { + 'registration': [], + 'notification': [], + 'error': [] + }; + + // require options parameter + if (typeof options === 'undefined') { + throw new Error('The options argument is required.'); + } + + // store the options to this object instance + this.options = options; + + // triggered on registration and notification + var that = this; + var success = function(result) { + if (result && typeof result.registrationId !== 'undefined') { + that.emit('registration', result); + } else if (result && result.additionalData && typeof result.additionalData.actionCallback !== 'undefined') { + var executeFuctionOrEmitEventByName = function(callbackName, context, arg) { + var namespaces = callbackName.split('.'); + var func = namespaces.pop(); + for (var i = 0; i < namespaces.length; i++) { + context = context[namespaces[i]]; + } + + if (typeof context[func] === 'function') { + context[func].call(context, arg); + } else { + that.emit(callbackName, arg); + } + }; + + executeFuctionOrEmitEventByName(result.additionalData.actionCallback, window, result); + } else if (result) { + that.emit('notification', result); + } + }; + + // triggered on error + var fail = function(msg) { + var e = (typeof msg === 'string') ? new Error(msg) : msg; + that.emit('error', e); + }; + + // wait at least one process tick to allow event subscriptions + setTimeout(function() { + exec(success, fail, 'PushNotification', 'init', [options]); + }, 10); +}; + +/** + * Unregister from push notifications + */ + +PushNotification.prototype.unregister = function(successCallback, errorCallback, options) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.unregister failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.unregister failure: success callback parameter must be a function'); + return; + } + + var that = this; + var cleanHandlersAndPassThrough = function() { + if (!options) { + that._handlers = { + 'registration': [], + 'notification': [], + 'error': [] + }; + } + successCallback(); + }; + + exec(cleanHandlersAndPassThrough, errorCallback, 'PushNotification', 'unregister', [options]); +}; + +/** + * subscribe to a topic + * @param {String} topic topic to subscribe + * @param {Function} successCallback success callback + * @param {Function} errorCallback error callback + * @return {void} + */ +PushNotification.prototype.subscribe = function(topic, successCallback, errorCallback) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.subscribe failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.subscribe failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'subscribe', [topic]); +}; + +/** + * unsubscribe to a topic + * @param {String} topic topic to unsubscribe + * @param {Function} successCallback success callback + * @param {Function} errorCallback error callback + * @return {void} + */ +PushNotification.prototype.unsubscribe = function(topic, successCallback, errorCallback) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.unsubscribe failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.unsubscribe failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'unsubscribe', [topic]); +}; + +/** + * Call this to set the application icon badge + */ + +PushNotification.prototype.setApplicationIconBadgeNumber = function(successCallback, errorCallback, badge) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.setApplicationIconBadgeNumber failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.setApplicationIconBadgeNumber failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'setApplicationIconBadgeNumber', [{badge: badge}]); +}; + +/** + * Get the application icon badge + */ + +PushNotification.prototype.getApplicationIconBadgeNumber = function(successCallback, errorCallback) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.getApplicationIconBadgeNumber failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.getApplicationIconBadgeNumber failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'getApplicationIconBadgeNumber', []); +}; + +/** + * Get the application icon badge + */ + +PushNotification.prototype.clearAllNotifications = function(successCallback, errorCallback) { + if (!successCallback) { successCallback = function() {}; } + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.clearAllNotifications failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.clearAllNotifications failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'clearAllNotifications', []); +}; + +/** + * Listen for an event. + * + * Any event is supported, but the following are built-in: + * + * - registration + * - notification + * - error + * + * @param {String} eventName to subscribe to. + * @param {Function} callback triggered on the event. + */ + +PushNotification.prototype.on = function(eventName, callback) { + if (!this._handlers.hasOwnProperty(eventName)) { + this._handlers[eventName] = []; + } + this._handlers[eventName].push(callback); +}; + +/** + * Remove event listener. + * + * @param {String} eventName to match subscription. + * @param {Function} handle function associated with event. + */ + +PushNotification.prototype.off = function (eventName, handle) { + if (this._handlers.hasOwnProperty(eventName)) { + var handleIndex = this._handlers[eventName].indexOf(handle); + if (handleIndex >= 0) { + this._handlers[eventName].splice(handleIndex, 1); + } + } +}; + +/** + * Emit an event. + * + * This is intended for internal use only. + * + * @param {String} eventName is the event to trigger. + * @param {*} all arguments are passed to the event listeners. + * + * @return {Boolean} is true when the event is triggered otherwise false. + */ + +PushNotification.prototype.emit = function() { + var args = Array.prototype.slice.call(arguments); + var eventName = args.shift(); + + if (!this._handlers.hasOwnProperty(eventName)) { + return false; + } + + for (var i = 0, length = this._handlers[eventName].length; i < length; i++) { + var callback = this._handlers[eventName][i]; + if (typeof callback === 'function') { + callback.apply(undefined,args); + } else { + console.log('event handler: ' + eventName + ' must be a function'); + } + } + + return true; +}; + +PushNotification.prototype.finish = function(successCallback, errorCallback, id) { + if (!successCallback) { successCallback = function() {}; } + if (!errorCallback) { errorCallback = function() {}; } + if (!id) { id = 'handler'; } + + if (typeof successCallback !== 'function') { + console.log('finish failure: success callback parameter must be a function'); + return; + } + + if (typeof errorCallback !== 'function') { + console.log('finish failure: failure parameter not a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'finish', [id]); +}; + +/*! + * Push Notification Plugin. + */ + +module.exports = { + /** + * Register for Push Notifications. + * + * This method will instantiate a new copy of the PushNotification object + * and start the registration process. + * + * @param {Object} options + * @return {PushNotification} instance + */ + + init: function(options) { + return new PushNotification(options); + }, + + hasPermission: function(successCallback, errorCallback) { + exec(successCallback, errorCallback, 'PushNotification', 'hasPermission', []); + }, + + /** + * PushNotification Object. + * + * Expose the PushNotification object for direct use + * and testing. Typically, you should use the + * .init helper method. + */ + + PushNotification: PushNotification +}; + +}); diff --git a/StoneIsland/platforms/android/build.gradle b/StoneIsland/platforms/android/build.gradle old mode 100755 new mode 100644 index b9c43320..5eef5255 --- a/StoneIsland/platforms/android/build.gradle +++ b/StoneIsland/platforms/android/build.gradle @@ -17,41 +17,35 @@ under the License. */ -// GENERATED FILE! DO NOT EDIT! - -apply plugin: 'android' +apply plugin: 'com.android.application' buildscript { repositories { mavenCentral() + jcenter() } // Switch the Android Gradle plugin version requirement depending on the // installed version of Gradle. This dependency is documented at // http://tools.android.com/tech-docs/new-build-system/version-compatibility // and https://issues.apache.org/jira/browse/CB-8143 - if (gradle.gradleVersion >= "2.2") { - dependencies { - classpath 'com.android.tools.build:gradle:1.0.0+' - } - } else if (gradle.gradleVersion >= "2.1") { - dependencies { - classpath 'com.android.tools.build:gradle:0.14.0+' - } - } else { - dependencies { - classpath 'com.android.tools.build:gradle:0.12.0+' - } + dependencies { + classpath "com.google.gms:google-services:3.0.0" + classpath "com.google.gms:google-services:3.0.0" + classpath 'com.android.tools.build:gradle:2.2.1' } } // Allow plugins to declare Maven dependencies via build-extras.gradle. -repositories { - mavenCentral() +allprojects { + repositories { + mavenCentral(); + jcenter() + } } task wrapper(type: Wrapper) { - gradleVersion = '2.2.1' + gradleVersion = '2.14.1' } // Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties. @@ -173,25 +167,31 @@ android { } defaultConfig { - versionCode cdvVersionCode ?: Integer.parseInt("" + privateHelpers.extractIntFromManifest("versionCode") + "0") + versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode")) + applicationId privateHelpers.extractStringFromManifest("package") + if (cdvMinSdkVersion != null) { minSdkVersion cdvMinSdkVersion } } + lintOptions { + abortOnError false; + } + compileSdkVersion cdvCompileSdkVersion buildToolsVersion cdvBuildToolsVersion if (Boolean.valueOf(cdvBuildMultipleApks)) { productFlavors { armv7 { - versionCode cdvVersionCode ?: defaultConfig.versionCode + 2 + versionCode defaultConfig.versionCode*10 + 2 ndk { abiFilters "armeabi-v7a", "" } } x86 { - versionCode cdvVersionCode ?: defaultConfig.versionCode + 4 + versionCode defaultConfig.versionCode*10 + 4 ndk { abiFilters "x86", "" } @@ -202,7 +202,12 @@ android { } } } - } else if (!cdvVersionCode) { + } + /* + + ELSE NOTHING! DON'T MESS WITH THE VERSION CODE IF YOU DON'T HAVE TO! + + else if (!cdvVersionCode) { def minSdkVersion = cdvMinSdkVersion ?: privateHelpers.extractIntFromManifest("minSdkVersion") // Vary versionCode by the two most common API levels: // 14 is ICS, which is the lowest API level for many apps. @@ -213,6 +218,7 @@ android { defaultConfig.versionCode += 8 } } + */ compileOptions { sourceCompatibility JavaVersion.VERSION_1_6 @@ -244,10 +250,11 @@ android { dependencies { compile fileTree(dir: 'libs', include: '*.jar') // SUB-PROJECT DEPENDENCIES START - debugCompile project(path: "CordovaLib", configuration: "debug") - releaseCompile project(path: "CordovaLib", configuration: "release") + debugCompile(project(path: "CordovaLib", configuration: "debug")) + releaseCompile(project(path: "CordovaLib", configuration: "release")) compile "com.android.support:support-v13:23+" - compile "com.google.android.gms:play-services-gcm:+" + compile "com.google.android.gms:play-services-gcm:9.8+" + compile "me.leolin:ShortcutBadger:1.1.11@aar" // SUB-PROJECT DEPENDENCIES END } @@ -265,7 +272,7 @@ def promptForReleaseKeyPassword() { gradle.taskGraph.whenReady { taskGraph -> taskGraph.getAllTasks().each() { task -> - if (task.name == 'validateReleaseSigning') { + if (task.name == 'validateReleaseSigning' || task.name == 'validateSigningRelease') { promptForReleaseKeyPassword() } } diff --git a/StoneIsland/platforms/android/cordova/.jshintrc b/StoneIsland/platforms/android/cordova/.jshintrc new file mode 100644 index 00000000..89a121cf --- /dev/null +++ b/StoneIsland/platforms/android/cordova/.jshintrc @@ -0,0 +1,10 @@ +{ + "node": true + , "bitwise": true + , "undef": true + , "trailing": true + , "quotmark": true + , "indent": 4 + , "unused": "vars" + , "latedef": "nofunc" +} diff --git a/StoneIsland/platforms/android/cordova/Api.js b/StoneIsland/platforms/android/cordova/Api.js new file mode 100644 index 00000000..8e4711cb --- /dev/null +++ b/StoneIsland/platforms/android/cordova/Api.js @@ -0,0 +1,415 @@ +/** + 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 path = require('path'); +var Q = require('q'); + +var AndroidProject = require('./lib/AndroidProject'); +var AndroidStudio = require('./lib/AndroidStudio'); +var PluginManager = require('cordova-common').PluginManager; + +var CordovaLogger = require('cordova-common').CordovaLogger; +var selfEvents = require('cordova-common').events; + +var PLATFORM = 'android'; + + +function setupEvents(externalEventEmitter) { + if (externalEventEmitter) { + // This will make the platform internal events visible outside + selfEvents.forwardEventsTo(externalEventEmitter); + return externalEventEmitter; + } + + // There is no logger if external emitter is not present, + // so attach a console logger + CordovaLogger.get().subscribe(selfEvents); + return selfEvents; +} + + +/** + * Class, that acts as abstraction over particular platform. Encapsulates the + * platform's properties and methods. + * + * Platform that implements own PlatformApi instance _should implement all + * prototype methods_ of this class to be fully compatible with cordova-lib. + * + * The PlatformApi instance also should define the following field: + * + * * platform: String that defines a platform name. + */ +function Api(platform, platformRootDir, events) { + this.platform = PLATFORM; + this.root = path.resolve(__dirname, '..'); + + setupEvents(events); + + var self = this; + + this.locations = { + root: self.root, + www: path.join(self.root, 'assets/www'), + res: path.join(self.root, 'res'), + platformWww: path.join(self.root, 'platform_www'), + configXml: path.join(self.root, 'res/xml/config.xml'), + defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'), + strings: path.join(self.root, 'res/values/strings.xml'), + manifest: path.join(self.root, 'AndroidManifest.xml'), + build: path.join(self.root, 'build'), + // NOTE: Due to platformApi spec we need to return relative paths here + cordovaJs: 'bin/templates/project/assets/www/cordova.js', + cordovaJsSrc: 'cordova-js-src' + }; + + // XXX Override some locations for Android Studio projects + if(AndroidStudio.isAndroidStudioProject(self.root) === true) { + selfEvents.emit('log', 'Android Studio project detected'); + this.android_studio = true; + this.locations.configXml = path.join(self.root, 'app/src/main/res/xml/config.xml'); + this.locations.strings = path.join(self.root, 'app/src/main/res/xml/strings.xml'); + this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml'); + this.locations.www = path.join(self.root, 'app/src/main/assets/www'); + this.locations.res = path.join(self.root, 'app/src/main/res'); + } +} + +/** + * Installs platform to specified directory and creates a platform project. + * + * @param {String} destination Destination directory, where insatll platform to + * @param {ConfigParser} [config] ConfgiParser instance, used to retrieve + * project creation options, such as package id and project name. + * @param {Object} [options] An options object. The most common options are: + * @param {String} [options.customTemplate] A path to custom template, that + * should override the default one from platform. + * @param {Boolean} [options.link] Flag that indicates that platform's + * sources will be linked to installed platform instead of copying. + * @param {EventEmitter} [events] An EventEmitter instance that will be used for + * logging purposes. If no EventEmitter provided, all events will be logged to + * console + * + * @return {Promise} Promise either fulfilled with PlatformApi + * instance or rejected with CordovaError. + */ +Api.createPlatform = function (destination, config, options, events) { + events = setupEvents(events); + var result; + try { + result = require('../../lib/create') + .create(destination, config, options, events) + .then(function (destination) { + var PlatformApi = require(path.resolve(destination, 'cordova/Api')); + return new PlatformApi(PLATFORM, destination, events); + }); + } + catch (e) { + events.emit('error','createPlatform is not callable from the android project API.'); + throw(e); + } + return result; +}; + +/** + * Updates already installed platform. + * + * @param {String} destination Destination directory, where platform installed + * @param {Object} [options] An options object. The most common options are: + * @param {String} [options.customTemplate] A path to custom template, that + * should override the default one from platform. + * @param {Boolean} [options.link] Flag that indicates that platform's + * sources will be linked to installed platform instead of copying. + * @param {EventEmitter} [events] An EventEmitter instance that will be used for + * logging purposes. If no EventEmitter provided, all events will be logged to + * console + * + * @return {Promise} Promise either fulfilled with PlatformApi + * instance or rejected with CordovaError. + */ +Api.updatePlatform = function (destination, options, events) { + events = setupEvents(events); + var result; + try { + result = require('../../lib/create') + .update(destination, options, events) + .then(function (destination) { + var PlatformApi = require(path.resolve(destination, 'cordova/Api')); + return new PlatformApi('android', destination, events); + }); + } + catch (e) { + events.emit('error','updatePlatform is not callable from the android project API, you will need to do this manually.'); + throw(e); + } + return result; +}; + +/** + * Gets a CordovaPlatform object, that represents the platform structure. + * + * @return {CordovaPlatform} A structure that contains the description of + * platform's file structure and other properties of platform. + */ +Api.prototype.getPlatformInfo = function () { + var result = {}; + result.locations = this.locations; + result.root = this.root; + result.name = this.platform; + result.version = require('./version'); + result.projectConfig = this._config; + + return result; +}; + +/** + * Updates installed platform with provided www assets and new app + * configuration. This method is required for CLI workflow and will be called + * each time before build, so the changes, made to app configuration and www + * code, will be applied to platform. + * + * @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a + * project structure and configuration, that should be applied to platform + * (contains project's www location and ConfigParser instance for project's + * config). + * + * @return {Promise} Return a promise either fulfilled, or rejected with + * CordovaError instance. + */ +Api.prototype.prepare = function (cordovaProject, prepareOptions) { + return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions); +}; + +/** + * Installs a new plugin into platform. This method only copies non-www files + * (sources, libs, etc.) to platform. It also doesn't resolves the + * dependencies of plugin. Both of handling of www files, such as assets and + * js-files and resolving dependencies are the responsibility of caller. + * + * @param {PluginInfo} plugin A PluginInfo instance that represents plugin + * that will be installed. + * @param {Object} installOptions An options object. Possible options below: + * @param {Boolean} installOptions.link: Flag that specifies that plugin + * sources will be symlinked to app's directory instead of copying (if + * possible). + * @param {Object} installOptions.variables An object that represents + * variables that will be used to install plugin. See more details on plugin + * variables in documentation: + * https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html + * + * @return {Promise} Return a promise either fulfilled, or rejected with + * CordovaError instance. + */ +Api.prototype.addPlugin = function (plugin, installOptions) { + var project = AndroidProject.getProjectFile(this.root); + var self = this; + + installOptions = installOptions || {}; + installOptions.variables = installOptions.variables || {}; + // Add PACKAGE_NAME variable into vars + if (!installOptions.variables.PACKAGE_NAME) { + installOptions.variables.PACKAGE_NAME = project.getPackageName(); + } + + if(this.android_studio === true) { + installOptions.android_studio = true; + } + + return Q() + .then(function () { + //CB-11964: Do a clean when installing the plugin code to get around + //the Gradle bug introduced by the Android Gradle Plugin Version 2.2 + //TODO: Delete when the next version of Android Gradle plugin comes out + + // Since clean doesn't just clean the build, it also wipes out www, we need + // to pass additional options. + + // Do some basic argument parsing + var opts = {}; + + // Skip cleaning prepared files when not invoking via cordova CLI. + opts.noPrepare = true; + + if(!AndroidStudio.isAndroidStudioProject(self.root) && !project.isClean()) { + return self.clean(opts); + } + }) + .then(function () { + return PluginManager.get(self.platform, self.locations, project) + .addPlugin(plugin, installOptions); + }) + .then(function () { + if (plugin.getFrameworks(this.platform).length === 0) return; + + selfEvents.emit('verbose', 'Updating build files since android plugin contained '); + require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles(); + }.bind(this)) + // CB-11022 Return truthy value to prevent running prepare after + .thenResolve(true); +}; + +/** + * Removes an installed plugin from platform. + * + * Since method accepts PluginInfo instance as input parameter instead of plugin + * id, caller shoud take care of managing/storing PluginInfo instances for + * future uninstalls. + * + * @param {PluginInfo} plugin A PluginInfo instance that represents plugin + * that will be installed. + * + * @return {Promise} Return a promise either fulfilled, or rejected with + * CordovaError instance. + */ +Api.prototype.removePlugin = function (plugin, uninstallOptions) { + var project = AndroidProject.getProjectFile(this.root); + + if(uninstallOptions && uninstallOptions.usePlatformWww === true && this.android_studio === true) { + uninstallOptions.usePlatformWww = false; + uninstallOptions.android_studio = true; + } + + return PluginManager.get(this.platform, this.locations, project) + .removePlugin(plugin, uninstallOptions) + .then(function () { + if (plugin.getFrameworks(this.platform).length === 0) return; + + selfEvents.emit('verbose', 'Updating build files since android plugin contained '); + require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles(); + }.bind(this)) + // CB-11022 Return truthy value to prevent running prepare after + .thenResolve(true); +}; + +/** + * Builds an application package for current platform. + * + * @param {Object} buildOptions A build options. This object's structure is + * highly depends on platform's specific. The most common options are: + * @param {Boolean} buildOptions.debug Indicates that packages should be + * built with debug configuration. This is set to true by default unless the + * 'release' option is not specified. + * @param {Boolean} buildOptions.release Indicates that packages should be + * built with release configuration. If not set to true, debug configuration + * will be used. + * @param {Boolean} buildOptions.device Specifies that built app is intended + * to run on device + * @param {Boolean} buildOptions.emulator: Specifies that built app is + * intended to run on emulator + * @param {String} buildOptions.target Specifies the device id that will be + * used to run built application. + * @param {Boolean} buildOptions.nobuild Indicates that this should be a + * dry-run call, so no build artifacts will be produced. + * @param {String[]} buildOptions.archs Specifies chip architectures which + * app packages should be built for. List of valid architectures is depends on + * platform. + * @param {String} buildOptions.buildConfig The path to build configuration + * file. The format of this file is depends on platform. + * @param {String[]} buildOptions.argv Raw array of command-line arguments, + * passed to `build` command. The purpose of this property is to pass a + * platform-specific arguments, and eventually let platform define own + * arguments processing logic. + * + * @return {Promise} A promise either fulfilled with an array of build + * artifacts (application packages) if package was built successfully, + * or rejected with CordovaError. The resultant build artifact objects is not + * strictly typed and may conatin arbitrary set of fields as in sample below. + * + * { + * architecture: 'x86', + * buildType: 'debug', + * path: '/path/to/build', + * type: 'app' + * } + * + * The return value in most cases will contain only one item but in some cases + * there could be multiple items in output array, e.g. when multiple + * arhcitectures is specified. + */ +Api.prototype.build = function (buildOptions) { + var self = this; + return require('./lib/check_reqs').run() + .then(function () { + return require('./lib/build').run.call(self, buildOptions); + }) + .then(function (buildResults) { + // Cast build result to array of build artifacts + return buildResults.apkPaths.map(function (apkPath) { + return { + buildType: buildResults.buildType, + buildMethod: buildResults.buildMethod, + path: apkPath, + type: 'apk' + }; + }); + }); +}; + +/** + * Builds an application package for current platform and runs it on + * specified/default device. If no 'device'/'emulator'/'target' options are + * specified, then tries to run app on default device if connected, otherwise + * runs the app on emulator. + * + * @param {Object} runOptions An options object. The structure is the same + * as for build options. + * + * @return {Promise} A promise either fulfilled if package was built and ran + * successfully, or rejected with CordovaError. + */ +Api.prototype.run = function(runOptions) { + var self = this; + return require('./lib/check_reqs').run() + .then(function () { + return require('./lib/run').run.call(self, runOptions); + }); +}; + +/** + * Cleans out the build artifacts from platform's directory, and also + * cleans out the platform www directory if called without options specified. + * + * @return {Promise} Return a promise either fulfilled, or rejected with + * CordovaError. + */ +Api.prototype.clean = function(cleanOptions) { + var self = this; + return require('./lib/check_reqs').run() + .then(function () { + return require('./lib/build').runClean.call(self, cleanOptions); + }) + .then(function () { + return require('./lib/prepare').clean.call(self, cleanOptions); + }); +}; + + + +/** + * Performs a requirements check for current platform. Each platform defines its + * own set of requirements, which should be resolved before platform can be + * built successfully. + * + * @return {Promise} Promise, resolved with set of Requirement + * objects for current platform. + */ +Api.prototype.requirements = function() { + return require('./lib/check_reqs').check_all(); +}; + +module.exports = Api; diff --git a/StoneIsland/platforms/android/cordova/build b/StoneIsland/platforms/android/cordova/build index 3c3aee4e..222e84a0 100755 --- a/StoneIsland/platforms/android/cordova/build +++ b/StoneIsland/platforms/android/cordova/build @@ -19,23 +19,32 @@ under the License. */ -var build = require('./lib/build'), - reqs = require('./lib/check_reqs'), - args = process.argv; +var args = process.argv; +var Api = require('./Api'); +var nopt = require('nopt'); +var path = require('path'); // Support basic help commands -if(args[2] == '--help' || - args[2] == '/?' || - args[2] == '-h' || - args[2] == 'help' || - args[2] == '-help' || - args[2] == '/help') { - build.help(); -} else { - reqs.run().done(function() { - return build.run(args.slice(2)); - }, function(err) { - console.error(err); - process.exit(2); - }); -} +if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) + require('./lib/build').help(); + +// Do some basic argument parsing +var buildOpts = nopt({ + 'verbose' : Boolean, + 'silent' : Boolean, + 'debug' : Boolean, + 'release' : Boolean, + 'nobuild': Boolean, + 'buildConfig' : path +}, { 'd' : '--verbose' }); + +// Make buildOptions compatible with PlatformApi build method spec +buildOpts.argv = buildOpts.argv.original; + +require('./loggingHelper').adjustLoggerLevel(buildOpts); + +new Api().build(buildOpts) +.catch(function(err) { + console.error(err.stack); + process.exit(2); +}); diff --git a/StoneIsland/platforms/android/cordova/build.bat b/StoneIsland/platforms/android/cordova/build.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/check_reqs.bat b/StoneIsland/platforms/android/cordova/check_reqs.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/clean b/StoneIsland/platforms/android/cordova/clean index d9a7d490..22065cc5 100755 --- a/StoneIsland/platforms/android/cordova/clean +++ b/StoneIsland/platforms/android/cordova/clean @@ -19,26 +19,33 @@ under the License. */ -var build = require('./lib/build'), - reqs = require('./lib/check_reqs'), - args = process.argv; +var Api = require('./Api'); var path = require('path'); +var nopt = require('nopt'); // Support basic help commands -if(args[2] == '--help' || - args[2] == '/?' || - args[2] == '-h' || - args[2] == 'help' || - args[2] == '-help' || - args[2] == '/help') { +if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) { console.log('Usage: ' + path.relative(process.cwd(), process.argv[1])); console.log('Cleans the project directory.'); process.exit(0); -} else { - reqs.run().done(function() { - return build.runClean(args.slice(2)); - }, function(err) { - console.error(err); - process.exit(2); - }); } + +// Do some basic argument parsing +var opts = nopt({ + 'verbose' : Boolean, + 'silent' : Boolean +}, { 'd' : '--verbose' }); + +// Make buildOptions compatible with PlatformApi clean method spec +opts.argv = opts.argv.original; + +// Skip cleaning prepared files when not invoking via cordova CLI. +opts.noPrepare = true; + +require('./loggingHelper').adjustLoggerLevel(opts); + +new Api().clean(opts) +.catch(function(err) { + console.error(err.stack); + process.exit(2); +}); diff --git a/StoneIsland/platforms/android/cordova/clean.bat b/StoneIsland/platforms/android/cordova/clean.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/defaults.xml b/StoneIsland/platforms/android/cordova/defaults.xml old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/Adb.js b/StoneIsland/platforms/android/cordova/lib/Adb.js new file mode 100644 index 00000000..84ae707e --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/Adb.js @@ -0,0 +1,105 @@ +/** + 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 Q = require('q'); +var os = require('os'); +var events = require('cordova-common').events; +var spawn = require('cordova-common').superspawn.spawn; +var CordovaError = require('cordova-common').CordovaError; + +var Adb = {}; + +function isDevice(line) { + return line.match(/\w+\tdevice/) && !line.match(/emulator/); +} + +function isEmulator(line) { + return line.match(/device/) && line.match(/emulator/); +} + +/** + * Lists available/connected devices and emulators + * + * @param {Object} opts Various options + * @param {Boolean} opts.emulators Specifies whether this method returns + * emulators only + * + * @return {Promise} list of available/connected + * devices/emulators + */ +Adb.devices = function (opts) { + return spawn('adb', ['devices'], {cwd: os.tmpdir()}) + .then(function(output) { + return output.split('\n').filter(function (line) { + // Filter out either real devices or emulators, depending on options + return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line); + }).map(function (line) { + return line.replace(/\tdevice/, '').replace('\r', ''); + }); + }); +}; + +Adb.install = function (target, packagePath, opts) { + events.emit('verbose', 'Installing apk ' + packagePath + ' on target ' + target + '...'); + var args = ['-s', target, 'install']; + if (opts && opts.replace) args.push('-r'); + return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()}) + .then(function(output) { + // 'adb install' seems to always returns no error, even if installation fails + // so we catching output to detect installation failure + if (output.match(/Failure/)) { + if (output.match(/INSTALL_PARSE_FAILED_NO_CERTIFICATES/)) { + output += '\n\n' + 'Sign the build using \'-- --keystore\' or \'--buildConfig\'' + + ' or sign and deploy the unsigned apk manually using Android tools.'; + } else if (output.match(/INSTALL_FAILED_VERSION_DOWNGRADE/)) { + output += '\n\n' + 'You\'re trying to install apk with a lower versionCode that is already installed.' + + '\nEither uninstall an app or increment the versionCode.'; + } + + return Q.reject(new CordovaError('Failed to install apk to device: ' + output)); + } + }); +}; + +Adb.uninstall = function (target, packageId) { + events.emit('verbose', 'Uninstalling package ' + packageId + ' from target ' + target + '...'); + return spawn('adb', ['-s', target, 'uninstall', packageId], {cwd: os.tmpdir()}); +}; + +Adb.shell = function (target, shellCommand) { + events.emit('verbose', 'Running adb shell command "' + shellCommand + '" on target ' + target + '...'); + var args = ['-s', target, 'shell']; + shellCommand = shellCommand.split(/\s+/); + return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()}) + .catch(function (output) { + return Q.reject(new CordovaError('Failed to execute shell command "' + + shellCommand + '"" on device: ' + output)); + }); +}; + +Adb.start = function (target, activityName) { + events.emit('verbose', 'Starting application "' + activityName + '" on target ' + target + '...'); + return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName) + .catch(function (output) { + return Q.reject(new CordovaError('Failed to start application "' + + activityName + '"" on device: ' + output)); + }); +}; + +module.exports = Adb; diff --git a/StoneIsland/platforms/android/cordova/lib/AndroidManifest.js b/StoneIsland/platforms/android/cordova/lib/AndroidManifest.js new file mode 100644 index 00000000..8248f593 --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/AndroidManifest.js @@ -0,0 +1,161 @@ +/** + 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 fs = require('fs'); +var et = require('elementtree'); +var xml= require('cordova-common').xmlHelpers; + +var DEFAULT_ORIENTATION = 'default'; + +/** Wraps an AndroidManifest file */ +function AndroidManifest(path) { + this.path = path; + this.doc = xml.parseElementtreeSync(path); + if (this.doc.getroot().tag !== 'manifest') { + throw new Error('AndroidManifest at ' + path + ' has incorrect root node name (expected "manifest")'); + } +} + +AndroidManifest.prototype.getVersionName = function() { + return this.doc.getroot().attrib['android:versionName']; +}; + +AndroidManifest.prototype.setVersionName = function(versionName) { + this.doc.getroot().attrib['android:versionName'] = versionName; + return this; +}; + +AndroidManifest.prototype.getVersionCode = function() { + return this.doc.getroot().attrib['android:versionCode']; +}; + +AndroidManifest.prototype.setVersionCode = function(versionCode) { + this.doc.getroot().attrib['android:versionCode'] = versionCode; + return this; +}; + +AndroidManifest.prototype.getPackageId = function() { + /*jshint -W069 */ + return this.doc.getroot().attrib['package']; + /*jshint +W069 */ +}; + +AndroidManifest.prototype.setPackageId = function(pkgId) { + /*jshint -W069 */ + this.doc.getroot().attrib['package'] = pkgId; + /*jshint +W069 */ + return this; +}; + +AndroidManifest.prototype.getActivity = function() { + var activity = this.doc.getroot().find('./application/activity'); + return { + getName: function () { + return activity.attrib['android:name']; + }, + setName: function (name) { + if (!name) { + delete activity.attrib['android:name']; + } else { + activity.attrib['android:name'] = name; + } + return this; + }, + getOrientation: function () { + return activity.attrib['android:screenOrientation']; + }, + setOrientation: function (orientation) { + if (!orientation || orientation.toLowerCase() === DEFAULT_ORIENTATION) { + delete activity.attrib['android:screenOrientation']; + } else { + activity.attrib['android:screenOrientation'] = orientation; + } + return this; + }, + getLaunchMode: function () { + return activity.attrib['android:launchMode']; + }, + setLaunchMode: function (launchMode) { + if (!launchMode) { + delete activity.attrib['android:launchMode']; + } else { + activity.attrib['android:launchMode'] = launchMode; + } + return this; + } + }; +}; + +['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'] +.forEach(function(sdkPrefName) { + // Copy variable reference to avoid closure issues + var prefName = sdkPrefName; + + AndroidManifest.prototype['get' + capitalize(prefName)] = function() { + var usesSdk = this.doc.getroot().find('./uses-sdk'); + return usesSdk && usesSdk.attrib['android:' + prefName]; + }; + + AndroidManifest.prototype['set' + capitalize(prefName)] = function(prefValue) { + var usesSdk = this.doc.getroot().find('./uses-sdk'); + + if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first + usesSdk = new et.Element('uses-sdk'); + this.doc.getroot().append(usesSdk); + } + + if (prefValue) { + usesSdk.attrib['android:' + prefName] = prefValue; + } + + return this; + }; +}); + +AndroidManifest.prototype.getDebuggable = function() { + return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true'; +}; + +AndroidManifest.prototype.setDebuggable = function(value) { + var application = this.doc.getroot().find('./application'); + if (value) { + application.attrib['android:debuggable'] = 'true'; + } else { + // The default value is "false", so we can remove attribute at all. + delete application.attrib['android:debuggable']; + } + return this; +}; + +/** + * Writes manifest to disk syncronously. If filename is specified, then manifest + * will be written to that file + * + * @param {String} [destPath] File to write manifest to. If omitted, + * manifest will be written to file it has been read from. + */ +AndroidManifest.prototype.write = function(destPath) { + fs.writeFileSync(destPath || this.path, this.doc.write({indent: 4}), 'utf-8'); +}; + +module.exports = AndroidManifest; + +function capitalize (str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} diff --git a/StoneIsland/platforms/android/cordova/lib/AndroidProject.js b/StoneIsland/platforms/android/cordova/lib/AndroidProject.js new file mode 100644 index 00000000..fa1c6129 --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/AndroidProject.js @@ -0,0 +1,210 @@ +/** + 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 fs = require('fs'); +var path = require('path'); +var properties_parser = require('properties-parser'); +var AndroidManifest = require('./AndroidManifest'); +var AndroidStudio = require('./AndroidStudio'); +var pluginHandlers = require('./pluginHandlers'); + +var projectFileCache = {}; + +function addToPropertyList(projectProperties, key, value) { + var i = 1; + while (projectProperties.get(key + '.' + i)) + i++; + + projectProperties.set(key + '.' + i, value); + projectProperties.dirty = true; +} + +function removeFromPropertyList(projectProperties, key, value) { + var i = 1; + var currentValue; + while ((currentValue = projectProperties.get(key + '.' + i))) { + if (currentValue === value) { + while ((currentValue = projectProperties.get(key + '.' + (i + 1)))) { + projectProperties.set(key + '.' + i, currentValue); + i++; + } + projectProperties.set(key + '.' + i); + break; + } + i++; + } + projectProperties.dirty = true; +} + +function getRelativeLibraryPath (parentDir, subDir) { + var libraryPath = path.relative(parentDir, subDir); + return (path.sep == '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath; +} + +function AndroidProject(projectDir) { + this._propertiesEditors = {}; + this._subProjectDirs = {}; + this._dirty = false; + this.projectDir = projectDir; + this.platformWww = path.join(this.projectDir, 'platform_www'); + this.www = path.join(this.projectDir, 'assets/www'); + if(AndroidStudio.isAndroidStudioProject(projectDir) === true) { + this.www = path.join(this.projectDir, 'app/src/main/assets/www'); + } +} + +AndroidProject.getProjectFile = function (projectDir) { + if (!projectFileCache[projectDir]) { + projectFileCache[projectDir] = new AndroidProject(projectDir); + } + + return projectFileCache[projectDir]; +}; + +AndroidProject.purgeCache = function (projectDir) { + if (projectDir) { + delete projectFileCache[projectDir]; + } else { + projectFileCache = {}; + } +}; + +/** + * Reads the package name out of the Android Manifest file + * + * @param {String} projectDir The absolute path to the directory containing the project + * + * @return {String} The name of the package + */ +AndroidProject.prototype.getPackageName = function() { + var manifestPath = path.join(this.projectDir, 'AndroidManifest.xml'); + if(AndroidStudio.isAndroidStudioProject(this.projectDir) === true) { + manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml'); + } + return new AndroidManifest(manifestPath).getPackageId(); +}; + +AndroidProject.prototype.getCustomSubprojectRelativeDir = function(plugin_id, src) { + // All custom subprojects are prefixed with the last portion of the package id. + // This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name. + var packageName = this.getPackageName(); + var lastDotIndex = packageName.lastIndexOf('.'); + var prefix = packageName.substring(lastDotIndex + 1); + var subRelativeDir = path.join(plugin_id, prefix + '-' + path.basename(src)); + return subRelativeDir; +}; + +AndroidProject.prototype.addSubProject = function(parentDir, subDir) { + var parentProjectFile = path.resolve(parentDir, 'project.properties'); + var subProjectFile = path.resolve(subDir, 'project.properties'); + var parentProperties = this._getPropertiesFile(parentProjectFile); + // TODO: Setting the target needs to happen only for pre-3.7.0 projects + if (fs.existsSync(subProjectFile)) { + var subProperties = this._getPropertiesFile(subProjectFile); + subProperties.set('target', parentProperties.get('target')); + subProperties.dirty = true; + this._subProjectDirs[subDir] = true; + } + addToPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir)); + + this._dirty = true; +}; + +AndroidProject.prototype.removeSubProject = function(parentDir, subDir) { + var parentProjectFile = path.resolve(parentDir, 'project.properties'); + var parentProperties = this._getPropertiesFile(parentProjectFile); + removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir)); + delete this._subProjectDirs[subDir]; + this._dirty = true; +}; + +AndroidProject.prototype.addGradleReference = function(parentDir, subDir) { + var parentProjectFile = path.resolve(parentDir, 'project.properties'); + var parentProperties = this._getPropertiesFile(parentProjectFile); + addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir)); + this._dirty = true; +}; + +AndroidProject.prototype.removeGradleReference = function(parentDir, subDir) { + var parentProjectFile = path.resolve(parentDir, 'project.properties'); + var parentProperties = this._getPropertiesFile(parentProjectFile); + removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir)); + this._dirty = true; +}; + +AndroidProject.prototype.addSystemLibrary = function(parentDir, value) { + var parentProjectFile = path.resolve(parentDir, 'project.properties'); + var parentProperties = this._getPropertiesFile(parentProjectFile); + addToPropertyList(parentProperties, 'cordova.system.library', value); + this._dirty = true; +}; + +AndroidProject.prototype.removeSystemLibrary = function(parentDir, value) { + var parentProjectFile = path.resolve(parentDir, 'project.properties'); + var parentProperties = this._getPropertiesFile(parentProjectFile); + removeFromPropertyList(parentProperties, 'cordova.system.library', value); + this._dirty = true; +}; + +AndroidProject.prototype.write = function() { + if (!this._dirty) { + return; + } + this._dirty = false; + + for (var filename in this._propertiesEditors) { + var editor = this._propertiesEditors[filename]; + if (editor.dirty) { + fs.writeFileSync(filename, editor.toString()); + editor.dirty = false; + } + } +}; + +AndroidProject.prototype._getPropertiesFile = function (filename) { + if (!this._propertiesEditors[filename]) { + if (fs.existsSync(filename)) { + this._propertiesEditors[filename] = properties_parser.createEditor(filename); + } else { + this._propertiesEditors[filename] = properties_parser.createEditor(); + } + } + + return this._propertiesEditors[filename]; +}; + +AndroidProject.prototype.getInstaller = function (type) { + return pluginHandlers.getInstaller(type); +}; + +AndroidProject.prototype.getUninstaller = function (type) { + return pluginHandlers.getUninstaller(type); +}; + +/* + * This checks if an Android project is clean or has old build artifacts + */ + +AndroidProject.prototype.isClean = function() { + var build_path = path.join(this.projectDir, 'build'); + //If the build directory doesn't exist, it's clean + return !(fs.existsSync(build_path)); +}; + +module.exports = AndroidProject; diff --git a/StoneIsland/platforms/android/cordova/lib/AndroidStudio.js b/StoneIsland/platforms/android/cordova/lib/AndroidStudio.js new file mode 100644 index 00000000..335b334b --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/AndroidStudio.js @@ -0,0 +1,42 @@ +/* + * This is a simple routine that checks if project is an Android Studio Project + * + * @param {String} root Root folder of the project + */ + +/*jshint esnext: false */ + +var path = require('path'); +var fs = require('fs'); +var CordovaError = require('cordova-common').CordovaError; + +module.exports.isAndroidStudioProject = function isAndroidStudioProject(root) { + var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res', 'project.properties', 'platform_www']; + var androidStudioFiles = ['app', 'gradle', 'app/src/main/res']; + + // assume it is an AS project and not an Eclipse project + var isEclipse = false; + var isAS = true; + + if(!fs.existsSync(root)) { + throw new CordovaError('AndroidStudio.js:inAndroidStudioProject root does not exist: ' + root); + } + + // if any of the following exists, then we are not an ASProj + eclipseFiles.forEach(function(file) { + if(fs.existsSync(path.join(root, file))) { + isEclipse = true; + } + }); + + // if it is NOT an eclipse project, check that all required files exist + if(!isEclipse) { + androidStudioFiles.forEach(function(file){ + if(!fs.existsSync(path.join(root, file))) { + console.log('missing file :: ' + file); + isAS = false; + } + }); + } + return (!isEclipse && isAS); +}; diff --git a/StoneIsland/platforms/android/cordova/lib/appinfo.js b/StoneIsland/platforms/android/cordova/lib/appinfo.js deleted file mode 100755 index 080c2ba8..00000000 --- a/StoneIsland/platforms/android/cordova/lib/appinfo.js +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node - -/* - 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 path = require('path'); -var fs = require('fs'); -var cachedAppInfo = null; - -function readAppInfoFromManifest() { - var manifestPath = path.join(__dirname, '..', '..', 'AndroidManifest.xml'); - var manifestData = fs.readFileSync(manifestPath, {encoding:'utf8'}); - var packageName = /\bpackage\s*=\s*"(.+?)"/.exec(manifestData); - if (!packageName) throw new Error('Could not find package name within ' + manifestPath); - var activityTag = //.exec(manifestData); - if (!activityTag) throw new Error('Could not find within ' + manifestPath); - var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag); - if (!activityName) throw new Error('Could not find android:name within ' + manifestPath); - - return packageName[1] + '/.' + activityName[1]; -} - -exports.getActivityName = function() { - return (cachedAppInfo = cachedAppInfo || readAppInfoFromManifest()); -}; diff --git a/StoneIsland/platforms/android/cordova/lib/build.js b/StoneIsland/platforms/android/cordova/lib/build.js old mode 100755 new mode 100644 index aa9f3d01..bd613da2 --- a/StoneIsland/platforms/android/cordova/lib/build.js +++ b/StoneIsland/platforms/android/cordova/lib/build.js @@ -19,477 +19,68 @@ under the License. */ -/* jshint sub:true */ - -var shell = require('shelljs'), - spawn = require('./spawn'), - Q = require('q'), +var Q = require('q'), path = require('path'), fs = require('fs'), - os = require('os'), - ROOT = path.join(__dirname, '..', '..'); -var check_reqs = require('./check_reqs'); -var exec = require('./exec'); - - -var SIGNING_PROPERTIES = '-signing.properties'; -var MARKER = 'YOUR CHANGES WILL BE ERASED!'; -var TEMPLATE = - '# This file is automatically generated.\n' + - '# Do not modify this file -- ' + MARKER + '\n'; - -function findApks(directory) { - var ret = []; - if (fs.existsSync(directory)) { - fs.readdirSync(directory).forEach(function(p) { - if (path.extname(p) == '.apk') { - ret.push(path.join(directory, p)); - } - }); - } - return ret; -} - -function sortFilesByDate(files) { - return files.map(function(p) { - return { p: p, t: fs.statSync(p).mtime }; - }).sort(function(a, b) { - var timeDiff = b.t - a.t; - return timeDiff === 0 ? a.p.length - b.p.length : timeDiff; - }).map(function(p) { return p.p; }); -} - -function isAutoGenerated(file) { - if(fs.existsSync(file)) { - var fileContents = fs.readFileSync(file, 'utf8'); - return fileContents.indexOf(MARKER) > 0; - } - return false; -} - -function findOutputApksHelper(dir, build_type, arch) { - var ret = findApks(dir).filter(function(candidate) { - // Need to choose between release and debug .apk. - if (build_type === 'debug') { - return /-debug/.exec(candidate) && !/-unaligned|-unsigned/.exec(candidate); - } - if (build_type === 'release') { - return /-release/.exec(candidate) && !/-unaligned/.exec(candidate); - } - return true; - }); - ret = sortFilesByDate(ret); - if (ret.length === 0) { - return ret; - } - // Assume arch-specific build if newest apk has -x86 or -arm. - var archSpecific = !!/-x86|-arm/.exec(ret[0]); - // And show only arch-specific ones (or non-arch-specific) - ret = ret.filter(function(p) { - /*jshint -W018 */ - return !!/-x86|-arm/.exec(p) == archSpecific; - /*jshint +W018 */ - }); - if (archSpecific && ret.length > 1) { - ret = ret.filter(function(p) { - return p.indexOf('-' + arch) != -1; - }); - } - - return ret; -} - -function hasCustomRules() { - return fs.existsSync(path.join(ROOT, 'custom_rules.xml')); -} + nopt = require('nopt'); + +var Adb = require('./Adb'); + +var builders = require('./builders/builders'); +var events = require('cordova-common').events; +var spawn = require('cordova-common').superspawn.spawn; +var CordovaError = require('cordova-common').CordovaError; + +function parseOpts(options, resolvedTarget, projectRoot) { + options = options || {}; + options.argv = nopt({ + gradle: Boolean, + ant: Boolean, + prepenv: Boolean, + versionCode: String, + minSdkVersion: String, + gradleArg: [String, Array], + keystore: path, + alias: String, + storePassword: String, + password: String, + keystoreType: String + }, {}, options.argv, 0); -function extractRealProjectNameFromManifest(projectPath) { - var manifestPath = path.join(projectPath, 'AndroidManifest.xml'); - var manifestData = fs.readFileSync(manifestPath, 'utf8'); - var m = / 0) { - throw new Error('Project contains at least one plugin that requires a system library. This is not supported with ANT. Please build using gradle.'); - } - - var propertiesFile = opts.buildType + SIGNING_PROPERTIES; - var propertiesFilePath = path.join(ROOT, propertiesFile); - if (opts.packageInfo) { - fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties()); - } else if(isAutoGenerated(propertiesFilePath)) { - shell.rm('-f', propertiesFilePath); - } - }); - }, - - /* - * Builds the project with ant. - * Returns a promise. - */ - build: function(opts) { - // Without our custom_rules.xml, we need to clean before building. - var ret = Q(); - if (!hasCustomRules()) { - // clean will call check_ant() for us. - ret = this.clean(opts); - } - - var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts); - return check_reqs.check_ant() - .then(function() { - console.log('Executing: ant ' + args.join(' ')); - return spawn('ant', args); - }); - }, - - clean: function(opts) { - var args = this.getArgs('clean', opts); - return check_reqs.check_ant() - .then(function() { - return spawn('ant', args); - }); - }, - - findOutputApks: function(build_type) { - var binDir = path.join(ROOT, hasCustomRules() ? 'ant-build' : 'bin'); - return findOutputApksHelper(binDir, build_type, null); - } - }, - gradle: { - getArgs: function(cmd, opts) { - if (cmd == 'release') { - cmd = 'cdvBuildRelease'; - } else if (cmd == 'debug') { - cmd = 'cdvBuildDebug'; - } - var args = [cmd, '-b', path.join(ROOT, 'build.gradle')]; - if (opts.arch) { - args.push('-PcdvBuildArch=' + opts.arch); - } - // 10 seconds -> 6 seconds - args.push('-Dorg.gradle.daemon=true'); - args.push.apply(args, opts.extraArgs); - // Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet): - // args.push('-Dorg.gradle.parallel=true'); - return args; - }, - - // Makes the project buildable, minus the gradle wrapper. - prepBuildFiles: function() { - var projectPath = ROOT; - // Update the version of build.gradle in each dependent library. - var pluginBuildGradle = path.join(projectPath, 'cordova', 'lib', 'plugin-build.gradle'); - var propertiesObj = readProjectProperties(); - var subProjects = propertiesObj.libs; - for (var i = 0; i < subProjects.length; ++i) { - if (subProjects[i] !== 'CordovaLib') { - shell.cp('-f', pluginBuildGradle, path.join(ROOT, subProjects[i], 'build.gradle')); - } - } - - var name = extractRealProjectNameFromManifest(ROOT); - //Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149 - var settingsGradlePaths = subProjects.map(function(p){ - var realDir=p.replace(/[/\\]/g, ':'); - var libName=realDir.replace(name+'-',''); - var str='include ":'+libName+'"\n'; - if(realDir.indexOf(name+'-')!==-1) - str+='project(":'+libName+'").projectDir = new File("'+p+'")\n'; - return str; - }); + if (options.argv.ant || options.argv.gradle) + ret.buildMethod = options.argv.ant ? 'ant' : 'gradle'; - // Write the settings.gradle file. - fs.writeFileSync(path.join(projectPath, 'settings.gradle'), - '// GENERATED FILE - DO NOT EDIT\n' + - 'include ":"\n' + settingsGradlePaths.join('')); - // Update dependencies within build.gradle. - var buildGradle = fs.readFileSync(path.join(projectPath, 'build.gradle'), 'utf8'); - var depsList = ''; - subProjects.forEach(function(p) { - var libName=p.replace(/[/\\]/g, ':').replace(name+'-',''); - depsList += ' debugCompile project(path: "' + libName + '", configuration: "debug")\n'; - depsList += ' releaseCompile project(path: "' + libName + '", configuration: "release")\n'; - }); - // For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390 - var SYSTEM_LIBRARY_MAPPINGS = [ - [/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'], - [/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+'] - ]; - propertiesObj.systemLibs.forEach(function(p) { - var mavenRef; - // It's already in gradle form if it has two ':'s - if (/:.*:/.exec(p)) { - mavenRef = p; - } else { - for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) { - var pair = SYSTEM_LIBRARY_MAPPINGS[i]; - if (pair[0].exec(p)) { - mavenRef = p.replace(pair[0], pair[1]); - break; - } - } - if (!mavenRef) { - throw new Error('Unsupported system library (does not work with gradle): ' + p); - } - } - depsList += ' compile "' + mavenRef + '"\n'; - }); - buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2'); - var includeList = ''; - propertiesObj.gradleIncludes.forEach(function(includePath) { - includeList += 'apply from: "' + includePath + '"\n'; - }); - buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2'); - fs.writeFileSync(path.join(projectPath, 'build.gradle'), buildGradle); - }, - - prepEnv: function(opts) { - var self = this; - return check_reqs.check_gradle() - .then(function() { - return self.prepBuildFiles(); - }).then(function() { - // Copy the gradle wrapper on each build so that: - // A) we don't require the Android SDK at project creation time, and - // B) we always use the SDK's latest version of it. - var projectPath = ROOT; - // check_reqs ensures that this is set. - var sdkDir = process.env['ANDROID_HOME']; - var wrapperDir = path.join(sdkDir, 'tools', 'templates', 'gradle', 'wrapper'); - if (process.platform == 'win32') { - shell.rm('-f', path.join(projectPath, 'gradlew.bat')); - shell.cp(path.join(wrapperDir, 'gradlew.bat'), projectPath); - } else { - shell.rm('-f', path.join(projectPath, 'gradlew')); - shell.cp(path.join(wrapperDir, 'gradlew'), projectPath); - } - shell.rm('-rf', path.join(projectPath, 'gradle', 'wrapper')); - shell.mkdir('-p', path.join(projectPath, 'gradle')); - shell.cp('-r', path.join(wrapperDir, 'gradle', 'wrapper'), path.join(projectPath, 'gradle')); - - // If the gradle distribution URL is set, make sure it points to version we want. - // If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with. - // For some reason, using ^ and $ don't work. This does the job, though. - var distributionUrlRegex = /distributionUrl.*zip/; - var distributionUrl = 'distributionUrl=http\\://services.gradle.org/distributions/gradle-2.2.1-all.zip'; - var gradleWrapperPropertiesPath = path.join(projectPath, 'gradle', 'wrapper', 'gradle-wrapper.properties'); - shell.chmod('u+w', gradleWrapperPropertiesPath); - shell.sed('-i', distributionUrlRegex, distributionUrl, gradleWrapperPropertiesPath); - - var propertiesFile = opts.buildType + SIGNING_PROPERTIES; - var propertiesFilePath = path.join(ROOT, propertiesFile); - if (opts.packageInfo) { - fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties()); - } else if (isAutoGenerated(propertiesFilePath)) { - shell.rm('-f', propertiesFilePath); - } - }); - }, - - /* - * Builds the project with gradle. - * Returns a promise. - */ - build: function(opts) { - var wrapper = path.join(ROOT, 'gradlew'); - var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts); - return Q().then(function() { - console.log('Running: ' + wrapper + ' ' + args.join(' ')); - return spawn(wrapper, args); - }); - }, + if (options.nobuild) ret.buildMethod = 'none'; - clean: function(opts) { - var builder = this; - var wrapper = path.join(ROOT, 'gradlew'); - var args = builder.getArgs('clean', opts); - return Q().then(function() { - console.log('Running: ' + wrapper + ' ' + args.join(' ')); - return spawn(wrapper, args); - }); - }, + if (options.argv.versionCode) + ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); - findOutputApks: function(build_type, arch) { - var binDir = path.join(ROOT, 'build', 'outputs', 'apk'); - return findOutputApksHelper(binDir, build_type, arch); - } - }, + if (options.argv.minSdkVersion) + ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); - none: { - prepEnv: function() { - return Q(); - }, - build: function() { - console.log('Skipping build...'); - return Q(null); - }, - clean: function() { - return Q(); - }, - findOutputApks: function(build_type, arch) { - return sortFilesByDate(builders.ant.findOutputApks(build_type, arch).concat(builders.gradle.findOutputApks(build_type, arch))); - } + if (options.argv.gradleArg) { + ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg); } -}; -module.exports.isBuildFlag = function(flag) { - return /^--(debug|release|ant|gradle|nobuild|versionCode=|minSdkVersion=|gradleArg=|keystore=|alias=|password=|storePassword=|keystoreType=|buildConfig=)/.exec(flag); -}; + var packageArgs = {}; -function parseOpts(options, resolvedTarget) { - // Backwards-compatibility: Allow a single string argument - if (typeof options == 'string') options = [options]; + if (options.argv.keystore) + packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); - var ret = { - buildType: 'debug', - buildMethod: process.env['ANDROID_BUILD'] || 'gradle', - arch: null, - extraArgs: [] - }; + ['alias','storePassword','password','keystoreType'].forEach(function (flagName) { + if (options.argv[flagName]) + packageArgs[flagName] = options.argv[flagName]; + }); - var multiValueArgs = { - 'versionCode': true, - 'minSdkVersion': true, - 'gradleArg': true, - 'keystore' : true, - 'alias' : true, - 'password' : true, - 'storePassword' : true, - 'keystoreType' : true, - 'buildConfig' : true - }; - var packageArgs = {}; - var buildConfig; - // Iterate through command line options - for (var i=0; options && (i < options.length); ++i) { - if (/^--/.exec(options[i])) { - var keyValue = options[i].substring(2).split('='); - var flagName = keyValue.shift(); - var flagValue = keyValue.join('='); - if (multiValueArgs[flagName] && !flagValue) { - flagValue = options[i + 1]; - ++i; - } - switch(flagName) { - case 'debug': - case 'release': - ret.buildType = flagName; - break; - case 'ant': - case 'gradle': - ret.buildMethod = flagName; - break; - case 'device': - case 'emulator': - // Don't need to do anything special to when building for device vs emulator. - // iOS uses this flag to switch on architecture. - break; - case 'prepenv' : - ret.prepEnv = true; - break; - case 'nobuild' : - ret.buildMethod = 'none'; - break; - case 'versionCode': - ret.extraArgs.push('-PcdvVersionCode=' + flagValue); - break; - case 'minSdkVersion': - ret.extraArgs.push('-PcdvMinSdkVersion=' + flagValue); - break; - case 'gradleArg': - ret.extraArgs.push(flagValue); - break; - case 'keystore': - packageArgs.keystore = path.relative(ROOT, path.resolve(flagValue)); - break; - case 'alias': - case 'storePassword': - case 'password': - case 'keystoreType': - packageArgs[flagName] = flagValue; - break; - case 'buildConfig': - buildConfig = flagValue; - break; - default : - console.warn('Build option --\'' + flagName + '\' not recognized (ignoring).'); - } - } else { - console.warn('Build option \'' + options[i] + '\' not recognized (ignoring).'); - } - } + var buildConfig = options.buildConfig; // If some values are not specified as command line arguments - use build config to supplement them. // Command line arguemnts have precedence over build config. @@ -497,16 +88,17 @@ function parseOpts(options, resolvedTarget) { if (!fs.existsSync(buildConfig)) { throw new Error('Specified build config file does not exist: ' + buildConfig); } - console.log('Reading build config file: '+ path.resolve(buildConfig)); - var config = JSON.parse(fs.readFileSync(buildConfig, 'utf8')); + events.emit('log', 'Reading build config file: '+ path.resolve(buildConfig)); + var buildjson = fs.readFileSync(buildConfig, 'utf8'); + var config = JSON.parse(buildjson.replace(/^\ufeff/, '')); // Remove BOM if (config.android && config.android[ret.buildType]) { var androidInfo = config.android[ret.buildType]; if(androidInfo.keystore && !packageArgs.keystore) { - if(path.isAbsolute(androidInfo.keystore)) { - packageArgs.keystore = androidInfo.keystore; - } else { - packageArgs.keystore = path.relative(ROOT, path.join(path.dirname(buildConfig), androidInfo.keystore)); + if(androidInfo.keystore.substr(0,1) === '~') { + androidInfo.keystore = process.env.HOME + androidInfo.keystore.substr(1); } + packageArgs.keystore = path.resolve(path.dirname(buildConfig), androidInfo.keystore); + events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore); } ['alias', 'storePassword', 'password','keystoreType'].forEach(function (key){ @@ -514,6 +106,7 @@ function parseOpts(options, resolvedTarget) { }); } } + if (packageArgs.keystore && packageArgs.alias) { ret.packageInfo = new PackageInfo(packageArgs.keystore, packageArgs.alias, packageArgs.storePassword, packageArgs.password, packageArgs.keystoreType); @@ -521,10 +114,9 @@ function parseOpts(options, resolvedTarget) { if(!ret.packageInfo) { if(Object.keys(packageArgs).length > 0) { - console.warn('\'keystore\' and \'alias\' need to be specified to generate a signed archive.'); + events.emit('warn', '\'keystore\' and \'alias\' need to be specified to generate a signed archive.'); } } - ret.arch = resolvedTarget && resolvedTarget.arch; return ret; } @@ -534,41 +126,39 @@ function parseOpts(options, resolvedTarget) { * Returns a promise. */ module.exports.runClean = function(options) { - var opts = parseOpts(options); - var builder = builders[opts.buildMethod]; + var opts = parseOpts(options, null, this.root); + var builder = builders.getBuilder(opts.buildMethod); return builder.prepEnv(opts) .then(function() { return builder.clean(opts); - }).then(function() { - shell.rm('-rf', path.join(ROOT, 'out')); - - ['debug', 'release'].forEach(function(config) { - var propertiesFilePath = path.join(ROOT, config + SIGNING_PROPERTIES); - if(isAutoGenerated(propertiesFilePath)){ - shell.rm('-f', propertiesFilePath); - } - }); }); }; -/* - * Builds the project with the specifed options - * Returns a promise. +/** + * Builds the project with the specifed options. + * + * @param {BuildOptions} options A set of options. See PlatformApi.build + * method documentation for reference. + * @param {Object} optResolvedTarget A deployment target. Used to pass + * target architecture from upstream 'run' call. TODO: remove this option in + * favor of setting buildOptions.archs field. + * + * @return {Promise} Promise, resolved with built packages + * information. */ module.exports.run = function(options, optResolvedTarget) { - var opts = parseOpts(options, optResolvedTarget); - var builder = builders[opts.buildMethod]; + var opts = parseOpts(options, optResolvedTarget, this.root); + var builder = builders.getBuilder(opts.buildMethod); return builder.prepEnv(opts) .then(function() { if (opts.prepEnv) { - console.log('Build file successfully prepared.'); + events.emit('verbose', 'Build file successfully prepared.'); return; } return builder.build(opts) .then(function() { var apkPaths = builder.findOutputApks(opts.buildType, opts.arch); - console.log('Built the following apk(s):'); - console.log(' ' + apkPaths.join('\n ')); + events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t')); return { apkPaths: apkPaths, buildType: opts.buildType, @@ -578,46 +168,38 @@ module.exports.run = function(options, optResolvedTarget) { }); }; -// Called by plugman after installing plugins, and by create script after creating project. -module.exports.prepBuildFiles = function() { - var builder = builders['gradle']; - return builder.prepBuildFiles(); -}; - /* * Detects the architecture of a device/emulator * Returns "arm" or "x86". */ module.exports.detectArchitecture = function(target) { function helper() { - return exec('adb -s ' + target + ' shell cat /proc/cpuinfo', os.tmpdir()) + return Adb.shell(target, 'cat /proc/cpuinfo') .then(function(output) { - if (/intel/i.exec(output)) { - return 'x86'; - } - return 'arm'; + return /intel/i.exec(output) ? 'x86' : 'arm'; }); } // It sometimes happens (at least on OS X), that this command will hang forever. // To fix it, either unplug & replug device, or restart adb server. - return helper().timeout(1000, 'Device communication timed out. Try unplugging & replugging the device.') + return helper() + .timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.')) .then(null, function(err) { if (/timed out/.exec('' + err)) { // adb kill-server doesn't seem to do the trick. // Could probably find a x-platform version of killall, but I'm not actually // sure that this scenario even happens on non-OSX machines. - return exec('killall adb') + events.emit('verbose', 'adb timed out while detecting device/emulator architecture. Killing adb and trying again.'); + return spawn('killall', ['adb']) .then(function() { - console.log('adb seems hung. retrying.'); return helper() .then(null, function() { // The double kill is sadly often necessary, at least on mac. - console.log('Now device not found... restarting adb again.'); - return exec('killall adb') + events.emit('warn', 'adb timed out a second time while detecting device/emulator architecture. Killing adb and trying again.'); + return spawn('killall', ['adb']) .then(function() { return helper() .then(null, function() { - return Q.reject('USB is flakey. Try unplugging & replugging the device.'); + return Q.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.')); }); }); }); @@ -632,16 +214,18 @@ module.exports.detectArchitecture = function(target) { module.exports.findBestApkForArchitecture = function(buildResults, arch) { var paths = buildResults.apkPaths.filter(function(p) { + var apkName = path.basename(p); if (buildResults.buildType == 'debug') { - return /-debug/.exec(p); + return /-debug/.exec(apkName); } - return !/-debug/.exec(p); + return !/-debug/.exec(apkName); }); var archPattern = new RegExp('-' + arch); var hasArchPattern = /-x86|-arm/; for (var i = 0; i < paths.length; ++i) { - if (hasArchPattern.exec(paths[i])) { - if (archPattern.exec(paths[i])) { + var apkName = path.basename(paths[i]); + if (hasArchPattern.exec(apkName)) { + if (archPattern.exec(apkName)) { return paths[i]; } } else { @@ -695,7 +279,7 @@ PackageInfo.prototype = { }; module.exports.help = function() { - console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'build')) + ' [flags] [Signed APK flags]'); + console.log('Usage: ' + path.relative(process.cwd(), path.join('../build')) + ' [flags] [Signed APK flags]'); console.log('Flags:'); console.log(' \'--debug\': will build project in debug mode (default)'); console.log(' \'--release\': will build project for release'); diff --git a/StoneIsland/platforms/android/cordova/lib/builders/AntBuilder.js b/StoneIsland/platforms/android/cordova/lib/builders/AntBuilder.js new file mode 100644 index 00000000..4e0f71ab --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/builders/AntBuilder.js @@ -0,0 +1,156 @@ +/* + 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 Q = require('q'); +var fs = require('fs'); +var path = require('path'); +var util = require('util'); +var shell = require('shelljs'); +var spawn = require('cordova-common').superspawn.spawn; +var CordovaError = require('cordova-common').CordovaError; +var check_reqs = require('../check_reqs'); + +var SIGNING_PROPERTIES = '-signing.properties'; +var MARKER = 'YOUR CHANGES WILL BE ERASED!'; +var TEMPLATE = + '# This file is automatically generated.\n' + + '# Do not modify this file -- ' + MARKER + '\n'; + +var GenericBuilder = require('./GenericBuilder'); + +function AntBuilder (projectRoot) { + GenericBuilder.call(this, projectRoot); + + this.binDirs = {ant: this.binDirs.ant}; +} + +util.inherits(AntBuilder, GenericBuilder); + +AntBuilder.prototype.getArgs = function(cmd, opts) { + var args = [cmd, '-f', path.join(this.root, 'build.xml')]; + // custom_rules.xml is required for incremental builds. + if (hasCustomRules(this.root)) { + args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen'); + } + if(opts.packageInfo) { + args.push('-propertyfile=' + path.join(this.root, opts.buildType + SIGNING_PROPERTIES)); + } + return args; +}; + +AntBuilder.prototype.prepEnv = function(opts) { + var self = this; + return check_reqs.check_ant() + .then(function() { + // Copy in build.xml on each build so that: + // A) we don't require the Android SDK at project creation time, and + // B) we always use the SDK's latest version of it. + /*jshint -W069 */ + var sdkDir = process.env['ANDROID_HOME']; + /*jshint +W069 */ + var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8'); + function writeBuildXml(projectPath) { + var newData = buildTemplate.replace('PROJECT_NAME', self.extractRealProjectNameFromManifest()); + fs.writeFileSync(path.join(projectPath, 'build.xml'), newData); + if (!fs.existsSync(path.join(projectPath, 'local.properties'))) { + fs.writeFileSync(path.join(projectPath, 'local.properties'), TEMPLATE); + } + } + writeBuildXml(self.root); + var propertiesObj = self.readProjectProperties(); + var subProjects = propertiesObj.libs; + for (var i = 0; i < subProjects.length; ++i) { + writeBuildXml(path.join(self.root, subProjects[i])); + } + if (propertiesObj.systemLibs.length > 0) { + throw new CordovaError('Project contains at least one plugin that requires a system library. This is not supported with ANT. Use gradle instead.'); + } + + var propertiesFile = opts.buildType + SIGNING_PROPERTIES; + var propertiesFilePath = path.join(self.root, propertiesFile); + if (opts.packageInfo) { + fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties()); + } else if(isAutoGenerated(propertiesFilePath)) { + shell.rm('-f', propertiesFilePath); + } + }); +}; + +/* + * Builds the project with ant. + * Returns a promise. + */ +AntBuilder.prototype.build = function(opts) { + // Without our custom_rules.xml, we need to clean before building. + var ret = Q(); + if (!hasCustomRules(this.root)) { + // clean will call check_ant() for us. + ret = this.clean(opts); + } + + var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts); + return check_reqs.check_ant() + .then(function() { + return spawn('ant', args, {stdio: 'pipe'}); + }).progress(function (stdio){ + if (stdio.stderr) { + process.stderr.write(stdio.stderr); + } else { + process.stdout.write(stdio.stdout); + } + }).catch(function (error) { + if (error.toString().indexOf('Unable to resolve project target') >= 0) { + return check_reqs.check_android_target(error).then(function() { + // If due to some odd reason - check_android_target succeeds + // we should still fail here. + return Q.reject(error); + }); + } + return Q.reject(error); + }); +}; + +AntBuilder.prototype.clean = function(opts) { + var args = this.getArgs('clean', opts); + var self = this; + return check_reqs.check_ant() + .then(function() { + return spawn('ant', args, {stdio: 'inherit'}); + }) + .then(function () { + shell.rm('-rf', path.join(self.root, 'out')); + + ['debug', 'release'].forEach(function(config) { + var propertiesFilePath = path.join(self.root, config + SIGNING_PROPERTIES); + if(isAutoGenerated(propertiesFilePath)){ + shell.rm('-f', propertiesFilePath); + } + }); + }); +}; + +module.exports = AntBuilder; + +function hasCustomRules(projectRoot) { + return fs.existsSync(path.join(projectRoot, 'custom_rules.xml')); +} + +function isAutoGenerated(file) { + return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0; +} diff --git a/StoneIsland/platforms/android/cordova/lib/builders/GenericBuilder.js b/StoneIsland/platforms/android/cordova/lib/builders/GenericBuilder.js new file mode 100644 index 00000000..362da431 --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/builders/GenericBuilder.js @@ -0,0 +1,147 @@ +/* + 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 Q = require('q'); +var fs = require('fs'); +var path = require('path'); +var shell = require('shelljs'); +var events = require('cordova-common').events; +var CordovaError = require('cordova-common').CordovaError; + +function GenericBuilder (projectDir) { + this.root = projectDir || path.resolve(__dirname, '../../..'); + this.binDirs = { + ant: path.join(this.root, hasCustomRules(this.root) ? 'ant-build' : 'bin'), + gradle: path.join(this.root, 'build', 'outputs', 'apk') + }; +} + +function hasCustomRules(projectRoot) { + return fs.existsSync(path.join(projectRoot, 'custom_rules.xml')); +} + +GenericBuilder.prototype.prepEnv = function() { + return Q(); +}; + +GenericBuilder.prototype.build = function() { + events.emit('log', 'Skipping build...'); + return Q(null); +}; + +GenericBuilder.prototype.clean = function() { + return Q(); +}; + +GenericBuilder.prototype.findOutputApks = function(build_type, arch) { + var self = this; + return Object.keys(this.binDirs) + .reduce(function (result, builderName) { + var binDir = self.binDirs[builderName]; + return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch)); + }, []) + .sort(apkSorter); +}; + +GenericBuilder.prototype.readProjectProperties = function () { + function findAllUniq(data, r) { + var s = {}; + var m; + while ((m = r.exec(data))) { + s[m[1]] = 1; + } + return Object.keys(s); + } + + var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8'); + return { + libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg), + gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg), + systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg) + }; +}; + +GenericBuilder.prototype.extractRealProjectNameFromManifest = function () { + var manifestPath = path.join(this.root, 'AndroidManifest.xml'); + var manifestData = fs.readFileSync(manifestPath, 'utf8'); + var m = / 1 && arch) { + ret = ret.filter(function(p) { + return path.basename(p).indexOf('-' + arch) != -1; + }); + } + + return ret; +} diff --git a/StoneIsland/platforms/android/cordova/lib/builders/GradleBuilder.js b/StoneIsland/platforms/android/cordova/lib/builders/GradleBuilder.js new file mode 100644 index 00000000..f415646e --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/builders/GradleBuilder.js @@ -0,0 +1,266 @@ +/* + 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 Q = require('q'); +var fs = require('fs'); +var util = require('util'); +var path = require('path'); +var shell = require('shelljs'); +var spawn = require('cordova-common').superspawn.spawn; +var CordovaError = require('cordova-common').CordovaError; +var check_reqs = require('../check_reqs'); + +var GenericBuilder = require('./GenericBuilder'); + +var MARKER = 'YOUR CHANGES WILL BE ERASED!'; +var SIGNING_PROPERTIES = '-signing.properties'; +var TEMPLATE = + '# This file is automatically generated.\n' + + '# Do not modify this file -- ' + MARKER + '\n'; + +function GradleBuilder (projectRoot) { + GenericBuilder.call(this, projectRoot); + + this.binDirs = {gradle: this.binDirs.gradle}; +} + +util.inherits(GradleBuilder, GenericBuilder); + +GradleBuilder.prototype.getArgs = function(cmd, opts) { + if (cmd == 'release') { + cmd = 'cdvBuildRelease'; + } else if (cmd == 'debug') { + cmd = 'cdvBuildDebug'; + } + var args = [cmd, '-b', path.join(this.root, 'build.gradle')]; + if (opts.arch) { + args.push('-PcdvBuildArch=' + opts.arch); + } + + // 10 seconds -> 6 seconds + args.push('-Dorg.gradle.daemon=true'); + // to allow dex in process + args.push('-Dorg.gradle.jvmargs=-Xmx2048m'); + // allow NDK to be used - required by Gradle 1.5 plugin + args.push('-Pandroid.useDeprecatedNdk=true'); + args.push.apply(args, opts.extraArgs); + // Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet): + // args.push('-Dorg.gradle.parallel=true'); + return args; +}; + +// Makes the project buildable, minus the gradle wrapper. +GradleBuilder.prototype.prepBuildFiles = function() { + // Update the version of build.gradle in each dependent library. + var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle'); + var propertiesObj = this.readProjectProperties(); + var subProjects = propertiesObj.libs; + var checkAndCopy = function(subProject, root) { + var subProjectGradle = path.join(root, subProject, 'build.gradle'); + // This is the future-proof way of checking if a file exists + // This must be synchronous to satisfy a Travis test + try { + fs.accessSync(subProjectGradle, fs.F_OK); + } catch (e) { + shell.cp('-f', pluginBuildGradle, subProjectGradle); + } + }; + for (var i = 0; i < subProjects.length; ++i) { + if (subProjects[i] !== 'CordovaLib') { + checkAndCopy(subProjects[i], this.root); + } + } + var name = this.extractRealProjectNameFromManifest(); + //Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149 + var settingsGradlePaths = subProjects.map(function(p){ + var realDir=p.replace(/[/\\]/g, ':'); + var libName=realDir.replace(name+'-',''); + var str='include ":'+libName+'"\n'; + if(realDir.indexOf(name+'-')!==-1) + str+='project(":'+libName+'").projectDir = new File("'+p+'")\n'; + return str; + }); + + // Write the settings.gradle file. + fs.writeFileSync(path.join(this.root, 'settings.gradle'), + '// GENERATED FILE - DO NOT EDIT\n' + + 'include ":"\n' + settingsGradlePaths.join('')); + // Update dependencies within build.gradle. + var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8'); + var depsList = ''; + var root = this.root; + var insertExclude = function(p) { + var gradlePath = path.join(root, p, 'build.gradle'); + var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8'); + if(projectGradleFile.indexOf('CordovaLib') != -1) { + depsList += '{\n exclude module:("CordovaLib")\n }\n'; + } + else { + depsList +='\n'; + } + }; + subProjects.forEach(function(p) { + console.log('Subproject Path: ' + p); + var libName=p.replace(/[/\\]/g, ':').replace(name+'-',''); + depsList += ' debugCompile(project(path: "' + libName + '", configuration: "debug"))'; + insertExclude(p); + depsList += ' releaseCompile(project(path: "' + libName + '", configuration: "release"))'; + insertExclude(p); + }); + // For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390 + var SYSTEM_LIBRARY_MAPPINGS = [ + [/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'], + [/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+'] + ]; + propertiesObj.systemLibs.forEach(function(p) { + var mavenRef; + // It's already in gradle form if it has two ':'s + if (/:.*:/.exec(p)) { + mavenRef = p; + } else { + for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) { + var pair = SYSTEM_LIBRARY_MAPPINGS[i]; + if (pair[0].exec(p)) { + mavenRef = p.replace(pair[0], pair[1]); + break; + } + } + if (!mavenRef) { + throw new CordovaError('Unsupported system library (does not work with gradle): ' + p); + } + } + depsList += ' compile "' + mavenRef + '"\n'; + }); + buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2'); + var includeList = ''; + propertiesObj.gradleIncludes.forEach(function(includePath) { + includeList += 'apply from: "' + includePath + '"\n'; + }); + buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2'); + fs.writeFileSync(path.join(this.root, 'build.gradle'), buildGradle); +}; + +GradleBuilder.prototype.prepEnv = function(opts) { + var self = this; + return check_reqs.check_gradle() + .then(function() { + return self.prepBuildFiles(); + }).then(function() { + // Copy the gradle wrapper on each build so that: + // A) we don't require the Android SDK at project creation time, and + // B) we always use the SDK's latest version of it. + // check_reqs ensures that this is set. + /*jshint -W069 */ + var sdkDir = process.env['ANDROID_HOME']; + /*jshint +W069 */ + var wrapperDir = path.join(sdkDir, 'tools', 'templates', 'gradle', 'wrapper'); + if (process.platform == 'win32') { + shell.rm('-f', path.join(self.root, 'gradlew.bat')); + shell.cp(path.join(wrapperDir, 'gradlew.bat'), self.root); + } else { + shell.rm('-f', path.join(self.root, 'gradlew')); + shell.cp(path.join(wrapperDir, 'gradlew'), self.root); + } + shell.rm('-rf', path.join(self.root, 'gradle', 'wrapper')); + shell.mkdir('-p', path.join(self.root, 'gradle')); + shell.cp('-r', path.join(wrapperDir, 'gradle', 'wrapper'), path.join(self.root, 'gradle')); + + // If the gradle distribution URL is set, make sure it points to version we want. + // If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with. + // For some reason, using ^ and $ don't work. This does the job, though. + var distributionUrlRegex = /distributionUrl.*zip/; + /*jshint -W069 */ + var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-2.14.1-all.zip'; + /*jshint +W069 */ + var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties'); + shell.chmod('u+w', gradleWrapperPropertiesPath); + shell.sed('-i', distributionUrlRegex, 'distributionUrl='+distributionUrl, gradleWrapperPropertiesPath); + + var propertiesFile = opts.buildType + SIGNING_PROPERTIES; + var propertiesFilePath = path.join(self.root, propertiesFile); + if (opts.packageInfo) { + fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties()); + } else if (isAutoGenerated(propertiesFilePath)) { + shell.rm('-f', propertiesFilePath); + } + }); +}; + +/* + * Builds the project with gradle. + * Returns a promise. + */ +GradleBuilder.prototype.build = function(opts) { + var wrapper = path.join(this.root, 'gradlew'); + var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts); + + return spawn(wrapper, args, {stdio: 'pipe'}) + .progress(function (stdio){ + if (stdio.stderr) { + /* + * Workaround for the issue with Java printing some unwanted information to + * stderr instead of stdout. + * This function suppresses 'Picked up _JAVA_OPTIONS' message from being + * printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for + * explanation. + */ + var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(stdio.stderr.toString()); + if (suppressThisLine) { + return; + } + process.stderr.write(stdio.stderr); + } else { + process.stdout.write(stdio.stdout); + } + }).catch(function (error) { + if (error.toString().indexOf('failed to find target with hash string') >= 0) { + return check_reqs.check_android_target(error).then(function() { + // If due to some odd reason - check_android_target succeeds + // we should still fail here. + return Q.reject(error); + }); + } + return Q.reject(error); + }); +}; + +GradleBuilder.prototype.clean = function(opts) { + var builder = this; + var wrapper = path.join(this.root, 'gradlew'); + var args = builder.getArgs('clean', opts); + return Q().then(function() { + return spawn(wrapper, args, {stdio: 'inherit'}); + }) + .then(function () { + shell.rm('-rf', path.join(builder.root, 'out')); + + ['debug', 'release'].forEach(function(config) { + var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES); + if(isAutoGenerated(propertiesFilePath)){ + shell.rm('-f', propertiesFilePath); + } + }); + }); +}; + +module.exports = GradleBuilder; + +function isAutoGenerated(file) { + return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0; +} diff --git a/StoneIsland/platforms/android/cordova/lib/builders/builders.js b/StoneIsland/platforms/android/cordova/lib/builders/builders.js new file mode 100644 index 00000000..4921c49a --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/builders/builders.js @@ -0,0 +1,47 @@ +/* + 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 CordovaError = require('cordova-common').CordovaError; + +var knownBuilders = { + ant: 'AntBuilder', + gradle: 'GradleBuilder', + none: 'GenericBuilder' +}; + +/** + * Helper method that instantiates and returns a builder for specified build + * type. + * + * @param {String} builderType Builder name to construct and return. Must + * be one of 'ant', 'gradle' or 'none' + * + * @return {Builder} A builder instance for specified build type. + */ +module.exports.getBuilder = function (builderType, projectRoot) { + if (!knownBuilders[builderType]) + throw new CordovaError('Builder ' + builderType + ' is not supported.'); + + try { + var Builder = require('./' + knownBuilders[builderType]); + return new Builder(projectRoot); + } catch (err) { + throw new CordovaError('Failed to instantiate ' + knownBuilders[builderType] + ' builder: ' + err); + } +}; diff --git a/StoneIsland/platforms/android/cordova/lib/check_reqs.js b/StoneIsland/platforms/android/cordova/lib/check_reqs.js old mode 100755 new mode 100644 index 9d251596..ac6fa4c1 --- a/StoneIsland/platforms/android/cordova/lib/check_reqs.js +++ b/StoneIsland/platforms/android/cordova/lib/check_reqs.js @@ -26,15 +26,14 @@ var shelljs = require('shelljs'), Q = require('q'), path = require('path'), fs = require('fs'), - which = require('which'), ROOT = path.join(__dirname, '..', '..'); +var CordovaError = require('cordova-common').CordovaError; var isWindows = process.platform == 'win32'; function forgivingWhichSync(cmd) { try { - // TODO: Should use shelljs.which() here to have one less dependency. - return fs.realpathSync(which.sync(cmd)); + return fs.realpathSync(shelljs.which(cmd)); } catch (e) { return ''; } @@ -43,7 +42,7 @@ function forgivingWhichSync(cmd) { function tryCommand(cmd, errMsg, catchStderr) { var d = Q.defer(); child_process.exec(cmd, function(err, stdout, stderr) { - if (err) d.reject(new Error(errMsg)); + if (err) d.reject(new CordovaError(errMsg)); // Sometimes it is necessary to return an stderr instead of stdout in case of success, since // some commands prints theirs output to stderr instead of stdout. 'javac' is the example else d.resolve((catchStderr ? stderr : stdout).trim()); @@ -83,12 +82,12 @@ module.exports.check_ant = function() { module.exports.check_gradle = function() { var sdkDir = process.env['ANDROID_HOME']; if (!sdkDir) - return Q.reject('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' + - 'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'); + return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' + + 'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.')); var wrapperDir = path.join(sdkDir, 'tools', 'templates', 'gradle', 'wrapper'); if (!fs.existsSync(wrapperDir)) { - return Q.reject(new Error('Could not find gradle wrapper within Android SDK. Might need to update your Android SDK.\n' + + return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Might need to update your Android SDK.\n' + 'Looked here: ' + wrapperDir)); } return Q.when(); @@ -120,7 +119,7 @@ module.exports.check_java = function() { if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) { process.env['JAVA_HOME'] = maybeJavaHome; } else { - throw new Error(msg); + throw new CordovaError(msg); } } } else if (isWindows) { @@ -143,22 +142,21 @@ module.exports.check_java = function() { } } }).then(function() { - var msg = - 'Failed to run "java -version", make sure that you have a JDK installed.\n' + - 'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n'; - if (process.env['JAVA_HOME']) { - msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n'; - } - return tryCommand('java -version', msg) - .then(function() { + var msg = + 'Failed to run "javac -version", make sure that you have a JDK installed.\n' + + 'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n'; + if (process.env['JAVA_HOME']) { + msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n'; + } // We use tryCommand with catchStderr = true, because // javac writes version info to stderr instead of stdout - return tryCommand('javac -version', msg, true); - }).then(function (output) { - var match = /javac ((?:\d+\.)+(?:\d+))/i.exec(output)[1]; - return match && match[1]; + return tryCommand('javac -version', msg, true) + .then(function (output) { + //Let's check for at least Java 8, and keep it future proof so we can support Java 10 + var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output); + return match && match[1]; + }); }); - }); }; // Returns a promise. @@ -212,7 +210,7 @@ module.exports.check_android = function() { process.env['ANDROID_HOME'] = grandParentDir; hasAndroidHome = true; } else { - throw new Error('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' + + throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' + 'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' + 'Try reinstall Android SDK or update your PATH to include path to valid SDK directory.'); } @@ -221,27 +219,32 @@ module.exports.check_android = function() { process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'platform-tools'); } if (!process.env['ANDROID_HOME']) { - throw new Error('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' + + throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' + 'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.'); } if (!fs.existsSync(process.env['ANDROID_HOME'])) { - throw new Error('\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process.env['ANDROID_HOME'] + + throw new CordovaError('\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process.env['ANDROID_HOME'] + '\nTry update it manually to point to valid SDK directory.'); } + return hasAndroidHome; }); }; -module.exports.getAbsoluteAndroidCmd = function() { - return forgivingWhichSync('android').replace(/(\s)/g, '\\$1'); +module.exports.getAbsoluteAndroidCmd = function () { + var cmd = forgivingWhichSync('android'); + if (process.platform === 'win32') { + return '"' + cmd + '"'; + } + return cmd.replace(/(\s)/g, '\\$1'); }; -module.exports.check_android_target = function(valid_target) { +module.exports.check_android_target = function(originalError) { // valid_target can look like: // android-19 // android-L // Google Inc.:Google APIs:20 // Google Inc.:Glass Development Kit Preview:20 - if (!valid_target) valid_target = module.exports.get_target(); + var valid_target = module.exports.get_target(); var msg = 'Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.'; return tryCommand('android list targets --compact', msg) .then(function(output) { @@ -251,24 +254,38 @@ module.exports.check_android_target = function(valid_target) { } var androidCmd = module.exports.getAbsoluteAndroidCmd(); - throw new Error('Please install Android target: "' + valid_target + '".\n\n' + + var msg = 'Please install Android target: "' + valid_target + '".\n\n' + 'Hint: Open the SDK manager by running: ' + androidCmd + '\n' + 'You will require:\n' + '1. "SDK Platform" for ' + valid_target + '\n' + '2. "Android SDK Platform-tools (latest)\n' + - '3. "Android SDK Build-tools" (latest)'); + '3. "Android SDK Build-tools" (latest)'; + if (originalError) { + msg = originalError + '\n' + msg; + } + throw new CordovaError(msg); }); }; // Returns a promise. module.exports.run = function() { - return Q.all([this.check_java(), this.check_android().then(this.check_android_target)]) - .then(function() { - console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']); - console.log('JAVA_HOME=' + process.env['JAVA_HOME']); - }); + return Q.all([this.check_java(), this.check_android()]) + .then(function(values) { + console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']); + console.log('JAVA_HOME=' + process.env['JAVA_HOME']); + + if (!values[0]) { + throw new CordovaError('Requirements check failed for JDK 1.8 or greater'); + } + + + if (!values[1]) { + throw new CordovaError('Requirements check failed for Android SDK'); + } + }); }; + /** * Object thar represents one of requirements for current platform. * @param {String} id The unique identifier for this requirements. diff --git a/StoneIsland/platforms/android/cordova/lib/device.js b/StoneIsland/platforms/android/cordova/lib/device.js old mode 100755 new mode 100644 index c13fdc40..4b171db6 --- a/StoneIsland/platforms/android/cordova/lib/device.js +++ b/StoneIsland/platforms/android/cordova/lib/device.js @@ -19,40 +19,30 @@ under the License. */ -var exec = require('./exec'), - Q = require('q'), - os = require('os'), - build = require('./build'), - appinfo = require('./appinfo'); +var Q = require('q'), + build = require('./build'); +var path = require('path'); +var Adb = require('./Adb'); +var AndroidManifest = require('./AndroidManifest'); +var spawn = require('cordova-common').superspawn.spawn; +var CordovaError = require('cordova-common').CordovaError; +var events = require('cordova-common').events; /** * Returns a promise for the list of the device ID's found * @param lookHarder When true, try restarting adb if no devices are found. */ module.exports.list = function(lookHarder) { - function helper() { - return exec('adb devices', os.tmpdir()) - .then(function(output) { - var response = output.split('\n'); - var device_list = []; - for (var i = 1; i < response.length; i++) { - if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) { - device_list.push(response[i].replace(/\tdevice/, '').replace('\r', '')); - } - } - return device_list; - }); - } - return helper() + return Adb.devices() .then(function(list) { if (list.length === 0 && lookHarder) { // adb kill-server doesn't seem to do the trick. // Could probably find a x-platform version of killall, but I'm not actually // sure that this scenario even happens on non-OSX machines. - return exec('killall adb') + return spawn('killall', ['adb']) .then(function() { - console.log('Restarting adb to see if more devices are detected.'); - return helper(); + events.emit('verbose', 'Restarting adb to see if more devices are detected.'); + return Adb.devices(); }, function() { // For non-killall OS's. return list; @@ -66,7 +56,7 @@ module.exports.resolveTarget = function(target) { return this.list(true) .then(function(device_list) { if (!device_list || !device_list.length) { - return Q.reject('ERROR: Failed to deploy to device, no devices found.'); + return Q.reject(new CordovaError('Failed to deploy to device, no devices found.')); } // default device target = target || device_list[0]; @@ -95,27 +85,36 @@ module.exports.install = function(target, buildResults) { return module.exports.resolveTarget(target); }).then(function(resolvedTarget) { var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch); - var launchName = appinfo.getActivityName(); - console.log('Using apk: ' + apk_path); - console.log('Installing app on device...'); - var cmd = 'adb -s ' + resolvedTarget.target + ' install -r "' + apk_path + '"'; - return exec(cmd, os.tmpdir()) - .then(function(output) { - if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output); + var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml')); + var pkgName = manifest.getPackageId(); + var launchName = pkgName + '/.' + manifest.getActivity().getName(); + events.emit('log', 'Using apk: ' + apk_path); + events.emit('log', 'Package name: ' + pkgName); - //unlock screen - var cmd = 'adb -s ' + resolvedTarget.target + ' shell input keyevent 82'; - return exec(cmd, os.tmpdir()); - }, function(err) { return Q.reject('ERROR: Failed to install apk to device: ' + err); }) + return Adb.install(resolvedTarget.target, apk_path, {replace: true}) + .catch(function (error) { + // CB-9557 CB-10157 only uninstall and reinstall app if the one that + // is already installed on device was signed w/different certificate + if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) + throw error; + + events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' + + 'installed app already signed with different key'); + + // This promise is always resolved, even if 'adb uninstall' fails to uninstall app + // or the app doesn't installed at all, so no error catching needed. + return Adb.uninstall(resolvedTarget.target, pkgName) + .then(function() { + return Adb.install(resolvedTarget.target, apk_path, {replace: true}); + }); + }) .then(function() { - // launch the application - console.log('Launching application...'); - var cmd = 'adb -s ' + resolvedTarget.target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName; - return exec(cmd, os.tmpdir()); + //unlock screen + return Adb.shell(resolvedTarget.target, 'input keyevent 82'); + }).then(function() { + return Adb.start(resolvedTarget.target, launchName); }).then(function() { - console.log('LAUNCH SUCCESS'); - }, function(err) { - return Q.reject('ERROR: Failed to launch application on device: ' + err); + events.emit('log', 'LAUNCH SUCCESS'); }); }); }; diff --git a/StoneIsland/platforms/android/cordova/lib/emulator.js b/StoneIsland/platforms/android/cordova/lib/emulator.js old mode 100755 new mode 100644 index e81dd679..ff1e261c --- a/StoneIsland/platforms/android/cordova/lib/emulator.js +++ b/StoneIsland/platforms/android/cordova/lib/emulator.js @@ -21,11 +21,14 @@ /* jshint sub:true */ -var exec = require('./exec'); -var appinfo = require('./appinfo'); var retry = require('./retry'); var build = require('./build'); -var check_reqs = require('./check_reqs'); +var path = require('path'); +var Adb = require('./Adb'); +var AndroidManifest = require('./AndroidManifest'); +var events = require('cordova-common').events; +var spawn = require('cordova-common').superspawn.spawn; +var CordovaError = require('cordova-common').CordovaError; var Q = require('q'); var os = require('os'); @@ -33,8 +36,10 @@ var child_process = require('child_process'); // constants var ONE_SECOND = 1000; // in milliseconds -var INSTALL_COMMAND_TIMEOUT = 120 * ONE_SECOND; // in milliseconds +var ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds +var INSTALL_COMMAND_TIMEOUT = 5 * ONE_MINUTE; // in milliseconds var NUM_INSTALL_RETRIES = 3; +var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds var EXEC_KILL_SIGNAL = 'SIGKILL'; /** @@ -48,7 +53,7 @@ var EXEC_KILL_SIGNAL = 'SIGKILL'; } */ module.exports.list_images = function() { - return exec('android list avds') + return spawn('android', ['list', 'avds']) .then(function(output) { var response = output.split('\n'); var emulator_list = []; @@ -57,13 +62,18 @@ module.exports.list_images = function() { var img_obj = {}; if (response[i].match(/Name:\s/)) { img_obj['name'] = response[i].split('Name: ')[1].replace('\r', ''); + if (response[i + 1].match(/Device:\s/)) { + i++; + img_obj['device'] = response[i].split('Device: ')[1].replace('\r', ''); + } if (response[i + 1].match(/Path:\s/)) { i++; img_obj['path'] = response[i].split('Path: ')[1].replace('\r', ''); } - if (response[i + 1].match(/\(API\slevel\s/)) { + if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) { i++; - img_obj['target'] = response[i].replace('\r', ''); + var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : ''; + img_obj['target'] = (response[i] + secondLine).split('Target: ')[1].replace('\r', ''); } if (response[i + 1].match(/ABI:\s/)) { i++; @@ -92,11 +102,15 @@ module.exports.list_images = function() { * Returns a promise. */ module.exports.best_image = function() { - var project_target = check_reqs.get_target().replace('android-', ''); return this.list_images() .then(function(images) { + // Just return undefined if there is no images + if (images.length === 0) return; + var closest = 9999; var best = images[0]; + // Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue + var project_target = require('./check_reqs').get_target().replace('android-', ''); for (var i in images) { var target = images[i].target; if(target) { @@ -115,22 +129,12 @@ module.exports.best_image = function() { // Returns a promise. module.exports.list_started = function() { - return exec('adb devices', os.tmpdir()) - .then(function(output) { - var response = output.split('\n'); - var started_emulator_list = []; - for (var i = 1; i < response.length; i++) { - if (response[i].match(/device/) && response[i].match(/emulator/)) { - started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', '')); - } - } - return started_emulator_list; - }); + return Adb.devices({emulators: true}); }; // Returns a promise. module.exports.list_targets = function() { - return exec('android list targets', os.tmpdir()) + return spawn('android', ['list', 'targets'], {cwd: os.tmpdir()}) .then(function(output) { var target_out = output.split('\n'); var targets = []; @@ -143,109 +147,140 @@ module.exports.list_targets = function() { }); }; +/* + * Gets unused port for android emulator, between 5554 and 5584 + * Returns a promise. + */ +module.exports.get_available_port = function () { + var self = this; + + return self.list_started() + .then(function (emulators) { + for (var p = 5584; p >= 5554; p-=2) { + if (emulators.indexOf('emulator-' + p) === -1) { + events.emit('verbose', 'Found available port: ' + p); + return p; + } + } + throw new CordovaError('Could not find an available avd port'); + }); +}; + /* * Starts an emulator with the given ID, * and returns the started ID of that emulator. - * If no ID is given it will used the first image available, + * If no ID is given it will use the first image available, * if no image is available it will error out (maybe create one?). + * If no boot timeout is given or the value is negative it will wait forever for + * the emulator to boot * * Returns a promise. */ -module.exports.start = function(emulator_ID) { +module.exports.start = function(emulator_ID, boot_timeout) { var self = this; - var emulator_id, num_started, started_emulators; - return self.list_started() - .then(function(list) { - started_emulators = list; - num_started = started_emulators.length; - if (!emulator_ID) { - return self.list_images() - .then(function(emulator_list) { - if (emulator_list.length > 0) { - return self.best_image() - .then(function(best) { - emulator_ID = best.name; - console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID); - return emulator_ID; - }); - } else { - var androidCmd = check_reqs.getAbsoluteAndroidCmd(); - return Q.reject('ERROR : No emulator images (avds) found.\n' + - '1. Download desired System Image by running: ' + androidCmd + ' sdk\n' + - '2. Create an AVD by running: ' + androidCmd + ' avd\n' + - 'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'); - } - }); - } else { - return Q(emulator_ID); - } - }).then(function() { - var cmd = 'emulator'; - var args = ['-avd', emulator_ID]; - var proc = child_process.spawn(cmd, args, { stdio: 'inherit', detached: true }); - proc.unref(); // Don't wait for it to finish, since the emulator will probably keep running for a long time. - }).then(function() { - // wait for emulator to start - console.log('Waiting for emulator...'); - return self.wait_for_emulator(num_started); - }).then(function(new_started) { - if (new_started.length > 1) { - for (var i in new_started) { - if (started_emulators.indexOf(new_started[i]) < 0) { - emulator_id = new_started[i]; - } + return Q().then(function() { + if (emulator_ID) return Q(emulator_ID); + + return self.best_image() + .then(function(best) { + if (best && best.name) { + events.emit('warn', 'No emulator specified, defaulting to ' + best.name); + return best.name; } - } else { - emulator_id = new_started[0]; - } - if (!emulator_id) return Q.reject('ERROR : Failed to start emulator, could not find new emulator'); + + // Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue + var androidCmd = require('./check_reqs').getAbsoluteAndroidCmd(); + return Q.reject(new CordovaError('No emulator images (avds) found.\n' + + '1. Download desired System Image by running: ' + androidCmd + ' sdk\n' + + '2. Create an AVD by running: ' + androidCmd + ' avd\n' + + 'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n')); + }); + }).then(function(emulatorId) { + return self.get_available_port() + .then(function (port) { + var args = ['-avd', emulatorId, '-port', port]; + // Don't wait for it to finish, since the emulator will probably keep running for a long time. + child_process + .spawn('emulator', args, { stdio: 'inherit', detached: true }) + .unref(); + + // wait for emulator to start + events.emit('log', 'Waiting for emulator to start...'); + return self.wait_for_emulator(port); + }); + }).then(function(emulatorId) { + if (!emulatorId) + return Q.reject(new CordovaError('Failed to start emulator')); //wait for emulator to boot up - process.stdout.write('Booting up emulator (this may take a while)...'); - return self.wait_for_boot(emulator_id); - }).then(function() { - console.log('BOOT COMPLETE'); - - //unlock screen - return exec('adb -s ' + emulator_id + ' shell input keyevent 82', os.tmpdir()); - }).then(function() { - //return the new emulator id for the started emulators - return emulator_id; + process.stdout.write('Waiting for emulator to boot (this may take a while)...'); + return self.wait_for_boot(emulatorId, boot_timeout) + .then(function(success) { + if (success) { + events.emit('log','BOOT COMPLETE'); + //unlock screen + return Adb.shell(emulatorId, 'input keyevent 82') + .then(function() { + //return the new emulator id for the started emulators + return emulatorId; + }); + } else { + // We timed out waiting for the boot to happen + return null; + } + }); }); }; /* - * Waits for the new emulator to apear on the started-emulator list. - * Returns a promise with a list of newly started emulators' IDs. + * Waits for an emulator to boot on a given port. + * Returns this emulator's ID in a promise. */ -module.exports.wait_for_emulator = function(num_running) { +module.exports.wait_for_emulator = function(port) { var self = this; - return self.list_started() - .then(function(new_started) { - if (new_started.length > num_running) { - return new_started; - } else { - return Q.delay(1000).then(function() { - return self.wait_for_emulator(num_running); - }); - } - }); + return Q().then(function() { + var emulator_id = 'emulator-' + port; + return Adb.shell(emulator_id, 'getprop dev.bootcomplete') + .then(function (output) { + if (output.indexOf('1') >= 0) { + return emulator_id; + } + return self.wait_for_emulator(port); + }, function (error) { + if (error && error.message && + (error.message.indexOf('not found') > -1) || + error.message.indexOf('device offline') > -1) { + // emulator not yet started, continue waiting + return self.wait_for_emulator(port); + } else { + // something unexpected has happened + throw error; + } + }); + }); }; /* - * Waits for the boot animation property of the emulator to switch to 'stopped' + * Waits for the core android process of the emulator to start. Returns a + * promise that resolves to a boolean indicating success. Not specifying a + * time_remaining or passing a negative value will cause it to wait forever */ -module.exports.wait_for_boot = function(emulator_id) { +module.exports.wait_for_boot = function(emulator_id, time_remaining) { var self = this; - return exec('adb -s ' + emulator_id + ' shell getprop init.svc.bootanim', os.tmpdir()) + return Adb.shell(emulator_id, 'ps') .then(function(output) { - if (output.match(/stopped/)) { - return; + if (output.match(/android\.process\.acore/)) { + return true; + } else if (time_remaining === 0) { + return false; } else { process.stdout.write('.'); - return Q.delay(3000).then(function() { - return self.wait_for_boot(emulator_id); + + // Check at regular intervals + return Q.delay(time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL).then(function() { + var updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining; + return self.wait_for_boot(emulator_id, updated_time); }); } }); @@ -257,9 +292,9 @@ module.exports.wait_for_boot = function(emulator_id) { * Returns a promise. */ module.exports.create_image = function(name, target) { - console.log('Creating avd named ' + name); + console.log('Creating new avd named ' + name); if (target) { - return exec('android create avd --name ' + name + ' --target ' + target) + return spawn('android', ['create', 'avd', '--name', name, '--target', target]) .then(null, function(error) { console.error('ERROR : Failed to create emulator image : '); console.error(' Do you have the latest android targets including ' + target + '?'); @@ -267,11 +302,11 @@ module.exports.create_image = function(name, target) { }); } else { console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.'); - return exec('android create avd --name ' + name + ' --target ' + this.list_targets()[0]) + return spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]]) .then(function() { // TODO: This seems like another error case, even though it always happens. console.error('ERROR : Unable to create an avd emulator, no targets found.'); - console.error('Please insure you have targets available by running the "android" command'); + console.error('Ensure you have targets available by running the "android" command'); return Q.reject(); }, function(error) { console.error('ERROR : Failed to create emulator image : '); @@ -284,7 +319,7 @@ module.exports.resolveTarget = function(target) { return this.list_started() .then(function(emulator_list) { if (emulator_list.length < 1) { - return Q.reject('No started emulators found, please start an emultor before deploying your project.'); + return Q.reject('No running Android emulators found, please start an emulator before deploying your project.'); } // default emulator @@ -309,6 +344,8 @@ module.exports.resolveTarget = function(target) { module.exports.install = function(givenTarget, buildResults) { var target; + var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml')); + var pkgName = manifest.getPackageId(); // resolve the target emulator return Q().then(function () { @@ -324,49 +361,83 @@ module.exports.install = function(givenTarget, buildResults) { // install the app }).then(function () { + // This promise is always resolved, even if 'adb uninstall' fails to uninstall app + // or the app doesn't installed at all, so no error catching needed. + return Q.when() + .then(function() { - var apk_path = build.findBestApkForArchitecture(buildResults, target.arch); - var execOptions = { - timeout: INSTALL_COMMAND_TIMEOUT, // in milliseconds - killSignal: EXEC_KILL_SIGNAL - }; - - console.log('Installing app on emulator...'); - console.log('Using apk: ' + apk_path); - - var retriedInstall = retry.retryPromise( - NUM_INSTALL_RETRIES, - exec, 'adb -s ' + target.target + ' install -r -d "' + apk_path + '"', os.tmpdir(), execOptions - ); + var apk_path = build.findBestApkForArchitecture(buildResults, target.arch); + var execOptions = { + cwd: os.tmpdir(), + timeout: INSTALL_COMMAND_TIMEOUT, // in milliseconds + killSignal: EXEC_KILL_SIGNAL + }; + + events.emit('log', 'Using apk: ' + apk_path); + events.emit('log', 'Package name: ' + pkgName); + events.emit('verbose', 'Installing app on emulator...'); + + // A special function to call adb install in specific environment w/ specific options. + // Introduced as a part of fix for http://issues.apache.org/jira/browse/CB-9119 + // to workaround sporadic emulator hangs + function adbInstallWithOptions(target, apk, opts) { + events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...'); + + var command = 'adb -s ' + target + ' install -r "' + apk + '"'; + return Q.promise(function (resolve, reject) { + child_process.exec(command, opts, function(err, stdout, stderr) { + if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr)); + // adb does not return an error code even if installation fails. Instead it puts a specific + // message to stdout, so we have to use RegExp matching to detect installation failure. + else if (/Failure/.test(stdout)) { + if (stdout.match(/INSTALL_PARSE_FAILED_NO_CERTIFICATES/)) { + stdout += 'Sign the build using \'-- --keystore\' or \'--buildConfig\'' + + ' or sign and deploy the unsigned apk manually using Android tools.'; + } else if (stdout.match(/INSTALL_FAILED_VERSION_DOWNGRADE/)) { + stdout += 'You\'re trying to install apk with a lower versionCode that is already installed.' + + '\nEither uninstall an app or increment the versionCode.'; + } + + reject(new CordovaError('Failed to install apk to emulator: ' + stdout)); + } else resolve(stdout); + }); + }); + } - return retriedInstall.then(function (output) { - if (output.match(/Failure/)) { - return Q.reject('Failed to install apk to emulator: ' + output); - } else { - console.log('INSTALL SUCCESS'); + function installPromise () { + return adbInstallWithOptions(target.target, apk_path, execOptions) + .catch(function (error) { + // CB-9557 CB-10157 only uninstall and reinstall app if the one that + // is already installed on device was signed w/different certificate + if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) + throw error; + + events.emit('warn', 'Uninstalling app from device and reinstalling it because the ' + + 'currently installed app was signed with different key'); + + // This promise is always resolved, even if 'adb uninstall' fails to uninstall app + // or the app doesn't installed at all, so no error catching needed. + return Adb.uninstall(target.target, pkgName) + .then(function() { + return adbInstallWithOptions(target.target, apk_path, execOptions); + }); + }); } - }, function (err) { - return Q.reject('Failed to install apk to emulator: ' + err); - }); + return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise) + .then(function (output) { + events.emit('log', 'INSTALL SUCCESS'); + }); + }); // unlock screen }).then(function () { - console.log('Unlocking screen...'); - return exec('adb -s ' + target.target + ' shell input keyevent 82', os.tmpdir()); - - // launch the application + events.emit('verbose', 'Unlocking screen...'); + return Adb.shell(target.target, 'input keyevent 82'); }).then(function () { - - console.log('Launching application...'); - var launchName = appinfo.getActivityName(); - var cmd = 'adb -s ' + target.target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName; - return exec(cmd, os.tmpdir()); - + Adb.start(target.target, pkgName + '/.' + manifest.getActivity().getName()); // report success or failure }).then(function (output) { - console.log('LAUNCH SUCCESS'); - }, function (err) { - return Q.reject('Failed to launch app on emulator: ' + err); + events.emit('log', 'LAUNCH SUCCESS'); }); }; diff --git a/StoneIsland/platforms/android/cordova/lib/exec.js b/StoneIsland/platforms/android/cordova/lib/exec.js deleted file mode 100755 index 798a93ba..00000000 --- a/StoneIsland/platforms/android/cordova/lib/exec.js +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env node - -/* - 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 child_process = require("child_process"); -var Q = require("q"); - -// constants -var DEFAULT_MAX_BUFFER = 1024000; - -// Takes a command and optional current working directory. -// Returns a promise that either resolves with the stdout, or -// rejects with an error message and the stderr. -// -// WARNING: -// opt_cwd is an artifact of an old design, and must -// be removed in the future; the correct solution is -// to pass the options object the same way that -// child_process.exec expects -// -// NOTE: -// exec documented here - https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback -module.exports = function(cmd, opt_cwd, options) { - - var d = Q.defer(); - - if (typeof options === "undefined") { - options = {}; - } - - // override cwd to preserve old opt_cwd behavior - options.cwd = opt_cwd; - - // set maxBuffer - if (typeof options.maxBuffer === "undefined") { - options.maxBuffer = DEFAULT_MAX_BUFFER; - } - - try { - child_process.exec(cmd, options, function(err, stdout, stderr) { - if (err) d.reject("Error executing \"" + cmd + "\": " + stderr); - else d.resolve(stdout); - }); - } catch(e) { - console.error("error caught: " + e); - d.reject(e); - } - - return d.promise; -}; - diff --git a/StoneIsland/platforms/android/cordova/lib/install-device.bat b/StoneIsland/platforms/android/cordova/lib/install-device.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/install-emulator.bat b/StoneIsland/platforms/android/cordova/lib/install-emulator.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/list-devices b/StoneIsland/platforms/android/cordova/lib/list-devices index e390bff6..fa84d7f6 100755 --- a/StoneIsland/platforms/android/cordova/lib/list-devices +++ b/StoneIsland/platforms/android/cordova/lib/list-devices @@ -22,12 +22,13 @@ var devices = require('./device'); // Usage support for when args are given -devices.list().done(function(device_list) { - device_list && device_list.forEach(function(dev) { - console.log(dev); +require('../lib/check_reqs').check_android().then(function() { + devices.list().done(function(device_list) { + device_list && device_list.forEach(function(dev) { + console.log(dev); + }); + }, function(err) { + console.error('ERROR: ' + err); + process.exit(2); }); -}, function(err) { - console.error('ERROR: ' + err); - process.exit(2); }); - diff --git a/StoneIsland/platforms/android/cordova/lib/list-devices.bat b/StoneIsland/platforms/android/cordova/lib/list-devices.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/list-emulator-images b/StoneIsland/platforms/android/cordova/lib/list-emulator-images index 996cf555..03c827fe 100755 --- a/StoneIsland/platforms/android/cordova/lib/list-emulator-images +++ b/StoneIsland/platforms/android/cordova/lib/list-emulator-images @@ -22,11 +22,13 @@ var emulators = require('./emulator'); // Usage support for when args are given -emulators.list_images().done(function(emulator_list) { - emulator_list && emulator_list.forEach(function(emu) { - console.log(emu.name); +require('../lib/check_reqs').check_android().then(function() { + emulators.list_images().done(function(emulator_list) { + emulator_list && emulator_list.forEach(function(emu) { + console.log(emu.name); + }); + }, function(err) { + console.error('ERROR: ' + err); + process.exit(2); }); -}, function(err) { - console.error('ERROR: ' + err); - process.exit(2); }); diff --git a/StoneIsland/platforms/android/cordova/lib/list-emulator-images.bat b/StoneIsland/platforms/android/cordova/lib/list-emulator-images.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/list-started-emulators b/StoneIsland/platforms/android/cordova/lib/list-started-emulators index 2ae8c5a8..a890dec6 100755 --- a/StoneIsland/platforms/android/cordova/lib/list-started-emulators +++ b/StoneIsland/platforms/android/cordova/lib/list-started-emulators @@ -22,11 +22,13 @@ var emulators = require('./emulator'); // Usage support for when args are given -emulators.list_started().done(function(emulator_list) { - emulator_list && emulator_list.forEach(function(emu) { - console.log(emu); +require('../lib/check_reqs').check_android().then(function() { + emulators.list_started().done(function(emulator_list) { + emulator_list && emulator_list.forEach(function(emu) { + console.log(emu); + }); + }, function(err) { + console.error('ERROR: ' + err); + process.exit(2); }); -}, function(err) { - console.error('ERROR: ' + err); - process.exit(2); }); diff --git a/StoneIsland/platforms/android/cordova/lib/list-started-emulators.bat b/StoneIsland/platforms/android/cordova/lib/list-started-emulators.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/log.js b/StoneIsland/platforms/android/cordova/lib/log.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/lib/plugin-build.gradle b/StoneIsland/platforms/android/cordova/lib/plugin-build.gradle old mode 100755 new mode 100644 index b345b90a..d1c63365 --- a/StoneIsland/platforms/android/cordova/lib/plugin-build.gradle +++ b/StoneIsland/platforms/android/cordova/lib/plugin-build.gradle @@ -21,28 +21,19 @@ buildscript { repositories { mavenCentral() + jcenter() } // Switch the Android Gradle plugin version requirement depending on the // installed version of Gradle. This dependency is documented at // http://tools.android.com/tech-docs/new-build-system/version-compatibility // and https://issues.apache.org/jira/browse/CB-8143 - if (gradle.gradleVersion >= "2.2") { - dependencies { - classpath 'com.android.tools.build:gradle:1.0.0+' - } - } else if (gradle.gradleVersion >= "2.1") { - dependencies { - classpath 'com.android.tools.build:gradle:0.14.0+' - } - } else { - dependencies { - classpath 'com.android.tools.build:gradle:0.12.0+' - } + dependencies { + classpath 'com.android.tools.build:gradle:1.0.0+' } } -apply plugin: 'android-library' +apply plugin: 'com.android.library' dependencies { compile fileTree(dir: 'libs', include: '*.jar') diff --git a/StoneIsland/platforms/android/cordova/lib/pluginHandlers.js b/StoneIsland/platforms/android/cordova/lib/pluginHandlers.js new file mode 100644 index 00000000..5e745fd5 --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/pluginHandlers.js @@ -0,0 +1,308 @@ +/* + * + * Copyright 2013 Anis Kadri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint unused: vars */ + +var fs = require('fs'); +var path = require('path'); +var shell = require('shelljs'); +var events = require('cordova-common').events; +var CordovaError = require('cordova-common').CordovaError; + +var handlers = { + 'source-file':{ + install:function(obj, plugin, project, options) { + if (!obj.src) throw new CordovaError(generateAttributeError('src', 'source-file', plugin.id)); + if (!obj.targetDir) throw new CordovaError(generateAttributeError('target-dir', 'source-file', plugin.id)); + + var dest = path.join(obj.targetDir, path.basename(obj.src)); + + if(options && options.android_studio === true) { + dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src)); + } + + if (options && options.force) { + copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link)); + } else { + copyNewFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link)); + } + }, + uninstall:function(obj, plugin, project, options) { + var dest = path.join(obj.targetDir, path.basename(obj.src)); + + if(options && options.android_studio === true) { + dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src)); + } + + deleteJava(project.projectDir, dest); + } + }, + 'lib-file':{ + install:function(obj, plugin, project, options) { + var dest = path.join('libs', path.basename(obj.src)); + if(options && options.android_studio === true) { + dest = path.join('app/libs', path.basename(obj.src)); + } + copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link)); + }, + uninstall:function(obj, plugin, project, options) { + var dest = path.join('libs', path.basename(obj.src)); + if(options && options.android_studio === true) { + dest = path.join('app/libs', path.basename(obj.src)); + } + removeFile(project.projectDir, dest); + } + }, + 'resource-file':{ + install:function(obj, plugin, project, options) { + copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), !!(options && options.link)); + }, + uninstall:function(obj, plugin, project, options) { + removeFile(project.projectDir, path.normalize(obj.target)); + } + }, + 'framework': { + install:function(obj, plugin, project, options) { + var src = obj.src; + if (!src) throw new CordovaError(generateAttributeError('src', 'framework', plugin.id)); + + events.emit('verbose', 'Installing Android library: ' + src); + var parentDir = obj.parent ? path.resolve(project.projectDir, obj.parent) : project.projectDir; + var subDir; + + if (obj.custom) { + var subRelativeDir = project.getCustomSubprojectRelativeDir(plugin.id, src); + copyNewFile(plugin.dir, src, project.projectDir, subRelativeDir, !!(options && options.link)); + subDir = path.resolve(project.projectDir, subRelativeDir); + } else { + obj.type = 'sys'; + subDir = src; + } + + if (obj.type == 'gradleReference') { + project.addGradleReference(parentDir, subDir); + } else if (obj.type == 'sys') { + project.addSystemLibrary(parentDir, subDir); + } else { + project.addSubProject(parentDir, subDir); + } + }, + uninstall:function(obj, plugin, project, options) { + var src = obj.src; + if (!src) throw new CordovaError(generateAttributeError('src', 'framework', plugin.id)); + + events.emit('verbose', 'Uninstalling Android library: ' + src); + var parentDir = obj.parent ? path.resolve(project.projectDir, obj.parent) : project.projectDir; + var subDir; + + if (obj.custom) { + var subRelativeDir = project.getCustomSubprojectRelativeDir(plugin.id, src); + removeFile(project.projectDir, subRelativeDir); + subDir = path.resolve(project.projectDir, subRelativeDir); + // If it's the last framework in the plugin, remove the parent directory. + var parDir = path.dirname(subDir); + if (fs.existsSync(parDir) && fs.readdirSync(parDir).length === 0) { + fs.rmdirSync(parDir); + } + } else { + obj.type = 'sys'; + subDir = src; + } + + if (obj.type == 'gradleReference') { + project.removeGradleReference(parentDir, subDir); + } else if (obj.type == 'sys') { + project.removeSystemLibrary(parentDir, subDir); + } else { + project.removeSubProject(parentDir, subDir); + } + } + }, + asset:{ + install:function(obj, plugin, project, options) { + if (!obj.src) { + throw new CordovaError(generateAttributeError('src', 'asset', plugin.id)); + } + if (!obj.target) { + throw new CordovaError(generateAttributeError('target', 'asset', plugin.id)); + } + + copyFile(plugin.dir, obj.src, project.www, obj.target); + if (options && options.usePlatformWww) { + // CB-11022 copy file to both directories if usePlatformWww is specified + copyFile(plugin.dir, obj.src, project.platformWww, obj.target); + } + }, + uninstall:function(obj, plugin, project, options) { + var target = obj.target || obj.src; + + if (!target) throw new CordovaError(generateAttributeError('target', 'asset', plugin.id)); + + removeFileF(path.resolve(project.www, target)); + removeFileF(path.resolve(project.www, 'plugins', plugin.id)); + if (options && options.usePlatformWww) { + // CB-11022 remove file from both directories if usePlatformWww is specified + removeFileF(path.resolve(project.platformWww, target)); + removeFileF(path.resolve(project.platformWww, 'plugins', plugin.id)); + } + } + }, + 'js-module': { + install: function (obj, plugin, project, options) { + // Copy the plugin's files into the www directory. + var moduleSource = path.resolve(plugin.dir, obj.src); + var moduleName = plugin.id + '.' + (obj.name || path.basename(obj.src, path.extname (obj.src))); + + // Read in the file, prepend the cordova.define, and write it back out. + var scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM + if (moduleSource.match(/.*\.json$/)) { + scriptContent = 'module.exports = ' + scriptContent; + } + scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) {\n' + scriptContent + '\n});\n'; + + var wwwDest = path.resolve(project.www, 'plugins', plugin.id, obj.src); + shell.mkdir('-p', path.dirname(wwwDest)); + fs.writeFileSync(wwwDest, scriptContent, 'utf-8'); + + if (options && options.usePlatformWww) { + // CB-11022 copy file to both directories if usePlatformWww is specified + var platformWwwDest = path.resolve(project.platformWww, 'plugins', plugin.id, obj.src); + shell.mkdir('-p', path.dirname(platformWwwDest)); + fs.writeFileSync(platformWwwDest, scriptContent, 'utf-8'); + } + }, + uninstall: function (obj, plugin, project, options) { + var pluginRelativePath = path.join('plugins', plugin.id, obj.src); + removeFileAndParents(project.www, pluginRelativePath); + if (options && options.usePlatformWww) { + // CB-11022 remove file from both directories if usePlatformWww is specified + removeFileAndParents(project.platformWww, pluginRelativePath); + } + } + } +}; + +module.exports.getInstaller = function (type) { + if (handlers[type] && handlers[type].install) { + return handlers[type].install; + } + + events.emit('verbose', '<' + type + '> is not supported for android plugins'); +}; + +module.exports.getUninstaller = function(type) { + if (handlers[type] && handlers[type].uninstall) { + return handlers[type].uninstall; + } + + events.emit('verbose', '<' + type + '> is not supported for android plugins'); +}; + +function copyFile (plugin_dir, src, project_dir, dest, link) { + src = path.resolve(plugin_dir, src); + if (!fs.existsSync(src)) throw new CordovaError('"' + src + '" not found!'); + + // check that src path is inside plugin directory + var real_path = fs.realpathSync(src); + var real_plugin_path = fs.realpathSync(plugin_dir); + if (real_path.indexOf(real_plugin_path) !== 0) + throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"'); + + dest = path.resolve(project_dir, dest); + + // check that dest path is located in project directory + if (dest.indexOf(project_dir) !== 0) + throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project'); + + shell.mkdir('-p', path.dirname(dest)); + if (link) { + symlinkFileOrDirTree(src, dest); + } else if (fs.statSync(src).isDirectory()) { + // XXX shelljs decides to create a directory when -R|-r is used which sucks. http://goo.gl/nbsjq + shell.cp('-Rf', src+'/*', dest); + } else { + shell.cp('-f', src, dest); + } +} + +// Same as copy file but throws error if target exists +function copyNewFile (plugin_dir, src, project_dir, dest, link) { + var target_path = path.resolve(project_dir, dest); + if (fs.existsSync(target_path)) + throw new CordovaError('"' + target_path + '" already exists!'); + + copyFile(plugin_dir, src, project_dir, dest, !!link); +} + +function symlinkFileOrDirTree(src, dest) { + if (fs.existsSync(dest)) { + shell.rm('-Rf', dest); + } + + if (fs.statSync(src).isDirectory()) { + shell.mkdir('-p', dest); + fs.readdirSync(src).forEach(function(entry) { + symlinkFileOrDirTree(path.join(src, entry), path.join(dest, entry)); + }); + } + else { + fs.symlinkSync(path.relative(fs.realpathSync(path.dirname(dest)), src), dest); + } +} + +// checks if file exists and then deletes. Error if doesn't exist +function removeFile (project_dir, src) { + var file = path.resolve(project_dir, src); + shell.rm('-Rf', file); +} + +// deletes file/directory without checking +function removeFileF (file) { + shell.rm('-Rf', file); +} + +// Sometimes we want to remove some java, and prune any unnecessary empty directories +function deleteJava (project_dir, destFile) { + removeFileAndParents(project_dir, destFile, 'src'); +} + +function removeFileAndParents (baseDir, destFile, stopper) { + stopper = stopper || '.'; + var file = path.resolve(baseDir, destFile); + if (!fs.existsSync(file)) return; + + removeFileF(file); + + // check if directory is empty + var curDir = path.dirname(file); + + while(curDir !== path.resolve(baseDir, stopper)) { + if(fs.existsSync(curDir) && fs.readdirSync(curDir).length === 0) { + fs.rmdirSync(curDir); + curDir = path.resolve(curDir, '..'); + } else { + // directory not empty...do nothing + break; + } + } +} + +function generateAttributeError(attribute, element, id) { + return 'Required attribute "' + attribute + '" not specified in <' + element + '> element from plugin: ' + id; +} diff --git a/StoneIsland/platforms/android/cordova/lib/prepare.js b/StoneIsland/platforms/android/cordova/lib/prepare.js new file mode 100644 index 00000000..10a69ea3 --- /dev/null +++ b/StoneIsland/platforms/android/cordova/lib/prepare.js @@ -0,0 +1,431 @@ +/** + 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 Q = require('q'); +var fs = require('fs'); +var path = require('path'); +var shell = require('shelljs'); +var events = require('cordova-common').events; +var AndroidManifest = require('./AndroidManifest'); +var xmlHelpers = require('cordova-common').xmlHelpers; +var CordovaError = require('cordova-common').CordovaError; +var ConfigParser = require('cordova-common').ConfigParser; +var FileUpdater = require('cordova-common').FileUpdater; +var PlatformJson = require('cordova-common').PlatformJson; +var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger; +var PluginInfoProvider = require('cordova-common').PluginInfoProvider; + +module.exports.prepare = function (cordovaProject, options) { + var self = this; + + var platformJson = PlatformJson.load(this.locations.root, this.platform); + var munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider()); + + this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations); + + // Update own www dir with project's www assets and plugins' assets and js-files + return Q.when(updateWww(cordovaProject, this.locations)) + .then(function () { + // update project according to config.xml changes. + return updateProjectAccordingTo(self._config, self.locations); + }) + .then(function () { + updateIcons(cordovaProject, path.relative(cordovaProject.root, self.locations.res)); + updateSplashes(cordovaProject, path.relative(cordovaProject.root, self.locations.res)); + }) + .then(function () { + events.emit('verbose', 'Prepared android project successfully'); + }); +}; + +module.exports.clean = function (options) { + // A cordovaProject isn't passed into the clean() function, because it might have + // been called from the platform shell script rather than the CLI. Check for the + // noPrepare option passed in by the non-CLI clean script. If that's present, or if + // there's no config.xml found at the project root, then don't clean prepared files. + var projectRoot = path.resolve(this.root, '../..'); + if ((options && options.noPrepare) || !fs.existsSync(this.locations.configXml) || + !fs.existsSync(this.locations.configXml)) { + return Q(); + } + + var projectConfig = new ConfigParser(this.locations.configXml); + + var self = this; + return Q().then(function () { + cleanWww(projectRoot, self.locations); + cleanIcons(projectRoot, projectConfig, path.relative(projectRoot, self.locations.res)); + cleanSplashes(projectRoot, projectConfig, path.relative(projectRoot, self.locations.res)); + }); +}; + +/** + * Updates config files in project based on app's config.xml and config munge, + * generated by plugins. + * + * @param {ConfigParser} sourceConfig A project's configuration that will + * be merged into platform's config.xml + * @param {ConfigChanges} configMunger An initialized ConfigChanges instance + * for this platform. + * @param {Object} locations A map of locations for this platform + * + * @return {ConfigParser} An instance of ConfigParser, that + * represents current project's configuration. When returned, the + * configuration is already dumped to appropriate config.xml file. + */ +function updateConfigFilesFrom(sourceConfig, configMunger, locations) { + events.emit('verbose', 'Generating platform-specific config.xml from defaults for android at ' + locations.configXml); + + // First cleanup current config and merge project's one into own + // Overwrite platform config.xml with defaults.xml. + shell.cp('-f', locations.defaultConfigXml, locations.configXml); + + // Then apply config changes from global munge to all config files + // in project (including project's config) + configMunger.reapply_global_munge().save_all(); + + events.emit('verbose', 'Merging project\'s config.xml into platform-specific android config.xml'); + // Merge changes from app's config.xml into platform's one + var config = new ConfigParser(locations.configXml); + xmlHelpers.mergeXml(sourceConfig.doc.getroot(), + config.doc.getroot(), 'android', /*clobber=*/true); + + config.write(); + return config; +} + +/** + * Logs all file operations via the verbose event stream, indented. + */ +function logFileOp(message) { + events.emit('verbose', ' ' + message); +} + +/** + * Updates platform 'www' directory by replacing it with contents of + * 'platform_www' and app www. Also copies project's overrides' folder into + * the platform 'www' folder + * + * @param {Object} cordovaProject An object which describes cordova project. + * @param {Object} destinations An object that contains destination + * paths for www files. + */ +function updateWww(cordovaProject, destinations) { + var sourceDirs = [ + path.relative(cordovaProject.root, cordovaProject.locations.www), + path.relative(cordovaProject.root, destinations.platformWww) + ]; + + // If project contains 'merges' for our platform, use them as another overrides + var merges_path = path.join(cordovaProject.root, 'merges', 'android'); + if (fs.existsSync(merges_path)) { + events.emit('verbose', 'Found "merges/android" folder. Copying its contents into the android project.'); + sourceDirs.push(path.join('merges', 'android')); + } + + var targetDir = path.relative(cordovaProject.root, destinations.www); + events.emit( + 'verbose', 'Merging and updating files from [' + sourceDirs.join(', ') + '] to ' + targetDir); + FileUpdater.mergeAndUpdateDir( + sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp); +} + +/** + * Cleans all files from the platform 'www' directory. + */ +function cleanWww(projectRoot, locations) { + var targetDir = path.relative(projectRoot, locations.www); + events.emit('verbose', 'Cleaning ' + targetDir); + + // No source paths are specified, so mergeAndUpdateDir() will clear the target directory. + FileUpdater.mergeAndUpdateDir( + [], targetDir, { rootDir: projectRoot, all: true }, logFileOp); +} + +/** + * Updates project structure and AndroidManifest according to project's configuration. + * + * @param {ConfigParser} platformConfig A project's configuration that will + * be used to update project + * @param {Object} locations A map of locations for this platform + */ +function updateProjectAccordingTo(platformConfig, locations) { + // Update app name by editing res/values/strings.xml + var name = platformConfig.name(); + var strings = xmlHelpers.parseElementtreeSync(locations.strings); + strings.find('string[@name="app_name"]').text = name.replace(/\'/g, '\\\''); + fs.writeFileSync(locations.strings, strings.write({indent: 4}), 'utf-8'); + events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings); + + // Java packages cannot support dashes + var pkg = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_'); + + var manifest = new AndroidManifest(locations.manifest); + var orig_pkg = manifest.getPackageId(); + + manifest.getActivity() + .setOrientation(platformConfig.getPreference('orientation')) + .setLaunchMode(findAndroidLaunchModePreference(platformConfig)); + + manifest.setVersionName(platformConfig.version()) + .setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version())) + .setPackageId(pkg) + .setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android')) + .setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android')) + .setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android')) + .write(); + + var javaPattern = path.join(locations.root, 'src', orig_pkg.replace(/\./g, '/'), '*.java'); + var java_files = shell.ls(javaPattern).filter(function(f) { + return shell.grep(/extends\s+CordovaActivity/g, f); + }); + + if (java_files.length === 0) { + throw new CordovaError('No Java files found that extend CordovaActivity.'); + } else if(java_files.length > 1) { + events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]); + } + + var destFile = path.join(locations.root, 'src', pkg.replace(/\./g, '/'), path.basename(java_files[0])); + shell.mkdir('-p', path.dirname(destFile)); + shell.sed(/package [\w\.]*;/, 'package ' + pkg + ';', java_files[0]).to(destFile); + events.emit('verbose', 'Wrote out Android package name "' + pkg + '" to ' + destFile); + + if (orig_pkg !== pkg) { + // If package was name changed we need to remove old java with main activity + shell.rm('-Rf',java_files[0]); + // remove any empty directories + var currentDir = path.dirname(java_files[0]); + var sourcesRoot = path.resolve(locations.root, 'src'); + while(currentDir !== sourcesRoot) { + if(fs.existsSync(currentDir) && fs.readdirSync(currentDir).length === 0) { + fs.rmdirSync(currentDir); + currentDir = path.resolve(currentDir, '..'); + } else { + break; + } + } + } +} + +// Consturct the default value for versionCode as +// PATCH + MINOR * 100 + MAJOR * 10000 +// see http://developer.android.com/tools/publishing/versioning.html +function default_versionCode(version) { + var nums = version.split('-')[0].split('.'); + var versionCode = 0; + if (+nums[0]) { + versionCode += +nums[0] * 10000; + } + if (+nums[1]) { + versionCode += +nums[1] * 100; + } + if (+nums[2]) { + versionCode += +nums[2]; + } + + events.emit('verbose', 'android-versionCode not found in config.xml. Generating a code based on version in config.xml (' + version + '): ' + versionCode); + return versionCode; +} + +function getImageResourcePath(resourcesDir, type, density, name, sourceName) { + if (/\.9\.png$/.test(sourceName)) { + name = name.replace(/\.png$/, '.9.png'); + } + var resourcePath = path.join(resourcesDir, (density ? type + '-' + density : type), name); + return resourcePath; +} + +function updateSplashes(cordovaProject, platformResourcesDir) { + var resources = cordovaProject.projectConfig.getSplashScreens('android'); + + // if there are "splash" elements in config.xml + if (resources.length === 0) { + events.emit('verbose', 'This app does not have splash screens defined'); + return; + } + + var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'drawable', 'screen.png'); + + var hadMdpi = false; + resources.forEach(function (resource) { + if (!resource.density) { + return; + } + if (resource.density == 'mdpi') { + hadMdpi = true; + } + var targetPath = getImageResourcePath( + platformResourcesDir, 'drawable', resource.density, 'screen.png', path.basename(resource.src)); + resourceMap[targetPath] = resource.src; + }); + + // There's no "default" drawable, so assume default == mdpi. + if (!hadMdpi && resources.defaultResource) { + var targetPath = getImageResourcePath( + platformResourcesDir, 'drawable', 'mdpi', 'screen.png', path.basename(resources.defaultResource.src)); + resourceMap[targetPath] = resources.defaultResource.src; + } + + events.emit('verbose', 'Updating splash screens at ' + platformResourcesDir); + FileUpdater.updatePaths( + resourceMap, { rootDir: cordovaProject.root }, logFileOp); +} + +function cleanSplashes(projectRoot, projectConfig, platformResourcesDir) { + var resources = projectConfig.getSplashScreens('android'); + if (resources.length > 0) { + var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'drawable', 'screen.png'); + events.emit('verbose', 'Cleaning splash screens at ' + platformResourcesDir); + + // No source paths are specified in the map, so updatePaths() will delete the target files. + FileUpdater.updatePaths( + resourceMap, { rootDir: projectRoot, all: true }, logFileOp); + } +} + +function updateIcons(cordovaProject, platformResourcesDir) { + var icons = cordovaProject.projectConfig.getIcons('android'); + + // if there are icon elements in config.xml + if (icons.length === 0) { + events.emit('verbose', 'This app does not have launcher icons defined'); + return; + } + + var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'icon.png'); + + var android_icons = {}; + var default_icon; + // http://developer.android.com/design/style/iconography.html + var sizeToDensityMap = { + 36: 'ldpi', + 48: 'mdpi', + 72: 'hdpi', + 96: 'xhdpi', + 144: 'xxhdpi', + 192: 'xxxhdpi' + }; + // find the best matching icon for a given density or size + // @output android_icons + var parseIcon = function(icon, icon_size) { + // do I have a platform icon for that density already + var density = icon.density || sizeToDensityMap[icon_size]; + if (!density) { + // invalid icon defition ( or unsupported size) + return; + } + var previous = android_icons[density]; + if (previous && previous.platform) { + return; + } + android_icons[density] = icon; + }; + + // iterate over all icon elements to find the default icon and call parseIcon + for (var i=0; i 0) { + var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'icon.png'); + events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir); + + // No source paths are specified in the map, so updatePaths() will delete the target files. + FileUpdater.updatePaths( + resourceMap, { rootDir: projectRoot, all: true }, logFileOp); + } +} + +/** + * Gets a map containing resources of a specified name from all drawable folders in a directory. + */ +function mapImageResources(rootDir, subDir, type, resourceName) { + var pathMap = {}; + shell.ls(path.join(rootDir, subDir, type + '-*')) + .forEach(function (drawableFolder) { + var imagePath = path.join(subDir, path.basename(drawableFolder), resourceName); + pathMap[imagePath] = null; + }); + return pathMap; +} + +/** + * Gets and validates 'AndroidLaunchMode' prepference from config.xml. Returns + * preference value and warns if it doesn't seems to be valid + * + * @param {ConfigParser} platformConfig A configParser instance for + * platform. + * + * @return {String} Preference's value from config.xml or + * default value, if there is no such preference. The default value is + * 'singleTop' + */ +function findAndroidLaunchModePreference(platformConfig) { + var launchMode = platformConfig.getPreference('AndroidLaunchMode'); + if (!launchMode) { + // Return a default value + return 'singleTop'; + } + + var expectedValues = ['standard', 'singleTop', 'singleTask', 'singleInstance']; + var valid = expectedValues.indexOf(launchMode) >= 0; + if (!valid) { + // Note: warn, but leave the launch mode as developer wanted, in case the list of options changes in the future + events.emit('warn', 'Unrecognized value for AndroidLaunchMode preference: ' + + launchMode + '. Expected values are: ' + expectedValues.join(', ')); + } + + return launchMode; +} diff --git a/StoneIsland/platforms/android/cordova/lib/retry.js b/StoneIsland/platforms/android/cordova/lib/retry.js old mode 100755 new mode 100644 index dc52a7d2..3cb49274 --- a/StoneIsland/platforms/android/cordova/lib/retry.js +++ b/StoneIsland/platforms/android/cordova/lib/retry.js @@ -21,7 +21,9 @@ /* jshint node: true */ -"use strict"; +'use strict'; + +var events = require('cordova-common').events; /* * Retry a promise-returning function a number of times, propagating its @@ -56,7 +58,7 @@ module.exports.retryPromise = function (attemts_left, promiseFunction) { throw error; } - console.log("A retried call failed. Retrying " + attemts_left + " more time(s)."); + events.emit('verbose', 'A retried call failed. Retrying ' + attemts_left + ' more time(s).'); // retry call self again with the same arguments, except attemts_left is now lower var fullArguments = [attemts_left, promiseFunction].concat(promiseFunctionArguments); diff --git a/StoneIsland/platforms/android/cordova/lib/run.js b/StoneIsland/platforms/android/cordova/lib/run.js old mode 100755 new mode 100644 index 7f15448c..214a1e19 --- a/StoneIsland/platforms/android/cordova/lib/run.js +++ b/StoneIsland/platforms/android/cordova/lib/run.js @@ -25,63 +25,36 @@ var path = require('path'), build = require('./build'), emulator = require('./emulator'), device = require('./device'), - shell = require('shelljs'), - Q = require('q'); + Q = require('q'), + events = require('cordova-common').events; -/* - * Runs the application on a device if available. - * If no device is found, it will use a started emulator. - * If no started emulators are found it will attempt to start an avd. - * If no avds are found it will error out. - * Returns a promise. - */ - module.exports.run = function(args) { - var buildFlags = []; +function getInstallTarget(runOptions) { var install_target; - var list = false; - - for (var i=2; i 0) { - console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.'); + events.emit('warn', 'No target specified, deploying to device \'' + device_list[0] + '\'.'); install_target = device_list[0]; } else { - console.log('WARNING : No target specified, deploying to emulator'); + events.emit('warn', 'No target specified and no devices found, deploying to emulator'); install_target = '--emulator'; } }); @@ -137,17 +110,25 @@ var path = require('path'), }); }); }).then(function(resolvedTarget) { - return build.run(buildFlags, resolvedTarget).then(function(buildResults) { + // Better just call self.build, but we're doing some processing of + // build results (according to platformApi spec) so they are in different + // format than emulator.install expects. + // TODO: Update emulator/device.install to handle this change + return build.run.call(self, runOptions, resolvedTarget) + .then(function(buildResults) { if (resolvedTarget.isEmulator) { - return emulator.install(resolvedTarget, buildResults); + return emulator.wait_for_boot(resolvedTarget.target) + .then(function () { + return emulator.install(resolvedTarget, buildResults); + }); } return device.install(resolvedTarget, buildResults); }); }); }; -module.exports.help = function(args) { - console.log('Usage: ' + path.relative(process.cwd(), args[1]) + ' [options]'); +module.exports.help = function() { + console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]) + ' [options]'); console.log('Build options :'); console.log(' --debug : Builds project in debug mode'); console.log(' --release : Builds project in release mode'); diff --git a/StoneIsland/platforms/android/cordova/lib/spawn.js b/StoneIsland/platforms/android/cordova/lib/spawn.js deleted file mode 100755 index 3e500a09..00000000 --- a/StoneIsland/platforms/android/cordova/lib/spawn.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node - -/* - 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 child_process = require('child_process'), - Q = require('q'); -var isWindows = process.platform.slice(0, 3) == 'win'; - -// Takes a command and optional current working directory. -module.exports = function(cmd, args, opt_cwd) { - var d = Q.defer(); - var opts = { cwd: opt_cwd, stdio: 'inherit' }; - try { - // Work around spawn not being able to find .bat files. - if (isWindows) { - args = [['/s', '/c', '"' + [cmd].concat(args).map(function(a){if (/^[^"].* .*[^"]/.test(a)) return '"' + a + '"'; return a;}).join(' ')+'"'].join(' ')]; - cmd = 'cmd'; - opts.windowsVerbatimArguments = true; - } - var child = child_process.spawn(cmd, args, opts); - child.on('exit', function(code) { - if (code) { - d.reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args); - } else { - d.resolve(); - } - }); - } catch(e) { - console.error('error caught: ' + e); - d.reject(e); - } - return d.promise; -}; diff --git a/StoneIsland/platforms/android/cordova/lib/start-emulator.bat b/StoneIsland/platforms/android/cordova/lib/start-emulator.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/log.bat b/StoneIsland/platforms/android/cordova/log.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/loggingHelper.js b/StoneIsland/platforms/android/cordova/loggingHelper.js new file mode 100644 index 00000000..32b2ee0a --- /dev/null +++ b/StoneIsland/platforms/android/cordova/loggingHelper.js @@ -0,0 +1,18 @@ +var CordovaLogger = require('cordova-common').CordovaLogger; + +module.exports = { + adjustLoggerLevel: function (opts) { + if (opts instanceof Array) { + opts.silent = opts.indexOf('--silent') !== -1; + opts.verbose = opts.indexOf('--verbose') !== -1; + } + + if (opts.silent) { + CordovaLogger.get().setLevel('error'); + } + + if (opts.verbose) { + CordovaLogger.get().setLevel('verbose'); + } + } +}; diff --git a/StoneIsland/platforms/android/cordova/run b/StoneIsland/platforms/android/cordova/run index 8c6fe38c..9544c1dc 100755 --- a/StoneIsland/platforms/android/cordova/run +++ b/StoneIsland/platforms/android/cordova/run @@ -19,19 +19,35 @@ under the License. */ -var run = require('./lib/run'), - reqs = require('./lib/check_reqs'), - args = process.argv; +var Api = require('./Api'); +var nopt = require('nopt'); +var path = require('path'); // Support basic help commands -if (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' || - args[2] == 'help' || args[2] == '-help' || args[2] == '/help') { - run.help(args); -} else { - reqs.run().done(function() { - return run.run(args); - }, function(err) { - console.error('ERROR: ' + err); - process.exit(2); - }); -} +if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) + require('./lib/run').help(); + +// Do some basic argument parsing +var runOpts = nopt({ + 'verbose' : Boolean, + 'silent' : Boolean, + 'debug' : Boolean, + 'release' : Boolean, + 'nobuild': Boolean, + 'buildConfig' : path, + 'archs' : String, + 'device' : Boolean, + 'emulator': Boolean, + 'target' : String +}, { 'd' : '--verbose' }); + +// Make runOptions compatible with PlatformApi run method spec +runOpts.argv = runOpts.argv.remain; + +require('./loggingHelper').adjustLoggerLevel(runOpts); + +new Api().run(runOpts) +.catch(function(err) { + console.error(err, err.stack); + process.exit(2); +}); diff --git a/StoneIsland/platforms/android/cordova/run.bat b/StoneIsland/platforms/android/cordova/run.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/cordova/version b/StoneIsland/platforms/android/cordova/version index 07442655..9bf79a18 100755 --- a/StoneIsland/platforms/android/cordova/version +++ b/StoneIsland/platforms/android/cordova/version @@ -20,6 +20,10 @@ */ // Coho updates this line: -var VERSION = "4.1.1"; +var VERSION = "6.1.2"; -console.log(VERSION); +module.exports.version = VERSION; + +if (!module.parent) { + console.log(VERSION); +} diff --git a/StoneIsland/platforms/android/cordova/version.bat b/StoneIsland/platforms/android/cordova/version.bat old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/google-services.json b/StoneIsland/platforms/android/google-services.json new file mode 100644 index 00000000..57497bf5 --- /dev/null +++ b/StoneIsland/platforms/android/google-services.json @@ -0,0 +1,4 @@ +{ + "project_info": {}, + "client": [] +} diff --git a/StoneIsland/platforms/android/phonegap-plugin-push/stoneisland-push.gradle b/StoneIsland/platforms/android/phonegap-plugin-push/stoneisland-push.gradle new file mode 100644 index 00000000..11e735ae --- /dev/null +++ b/StoneIsland/platforms/android/phonegap-plugin-push/stoneisland-push.gradle @@ -0,0 +1,21 @@ +import java.util.regex.Pattern + +def doExtractStringFromManifest(name) { + def manifestFile = file(android.sourceSets.main.manifest.srcFile) + def pattern = Pattern.compile(name + "=\"(.*?)\"") + def matcher = pattern.matcher(manifestFile.getText()) + matcher.find() + return matcher.group(1) +} + +android { + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + } + } + + defaultConfig { + applicationId = doExtractStringFromManifest("package") + } +} diff --git a/StoneIsland/platforms/android/platform_www/cordova-js-src/android/nativeapiprovider.js b/StoneIsland/platforms/android/platform_www/cordova-js-src/android/nativeapiprovider.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/platform_www/cordova-js-src/android/promptbasednativeapi.js b/StoneIsland/platforms/android/platform_www/cordova-js-src/android/promptbasednativeapi.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/platform_www/cordova-js-src/exec.js b/StoneIsland/platforms/android/platform_www/cordova-js-src/exec.js old mode 100755 new mode 100644 index fa8b41be..f73d87a1 --- a/StoneIsland/platforms/android/platform_www/cordova-js-src/exec.js +++ b/StoneIsland/platforms/android/platform_www/cordova-js-src/exec.js @@ -51,10 +51,11 @@ var cordova = require('cordova'), // For the ONLINE_EVENT to be viable, it would need to intercept all event // listeners (both through addEventListener and window.ononline) as well // as set the navigator property itself. - ONLINE_EVENT: 2 + ONLINE_EVENT: 2, + EVAL_BRIDGE: 3 }, jsToNativeBridgeMode, // Set lazily. - nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, + nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE, pollEnabled = false, bridgeSecret = -1; @@ -77,6 +78,9 @@ function androidExec(success, fail, service, action, args) { androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } + // If args is not provided, default to an empty array + args = args || []; + // Process any ArrayBuffers in the args into a string. for (var i = 0; i < args.length; i++) { if (utils.typeName(args[i]) == 'ArrayBuffer') { @@ -86,7 +90,6 @@ function androidExec(success, fail, service, action, args) { var callbackId = service + cordova.callbackId++, argsJson = JSON.stringify(args); - if (success || fail) { cordova.callbacks[callbackId] = {success:success, fail:fail}; } @@ -106,6 +109,17 @@ function androidExec(success, fail, service, action, args) { } androidExec.init = function() { + //CB-11828 + //This failsafe checks the version of Android and if it's Jellybean, it switches it to + //using the Online Event bridge for communicating from Native to JS + // + //It's ugly, but it's necessary. + var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/); + var version_code = check && check[0].match(/4.[0-3].*/); + if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) { + nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT; + } + bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode); channel.onNativeReady.fire(); }; diff --git a/StoneIsland/platforms/android/platform_www/cordova-js-src/platform.js b/StoneIsland/platforms/android/platform_www/cordova-js-src/platform.js old mode 100755 new mode 100644 index bffc6751..2bfd0247 --- a/StoneIsland/platforms/android/platform_www/cordova-js-src/platform.js +++ b/StoneIsland/platforms/android/platform_www/cordova-js-src/platform.js @@ -19,6 +19,9 @@ * */ +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -58,6 +61,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -79,12 +95,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } diff --git a/StoneIsland/platforms/android/platform_www/cordova-js-src/plugin/android/app.js b/StoneIsland/platforms/android/platform_www/cordova-js-src/plugin/android/app.js old mode 100755 new mode 100644 diff --git a/StoneIsland/platforms/android/platform_www/cordova.js b/StoneIsland/platforms/android/platform_www/cordova.js old mode 100755 new mode 100644 index 23f6e475..18c020e7 --- a/StoneIsland/platforms/android/platform_www/cordova.js +++ b/StoneIsland/platforms/android/platform_www/cordova.js @@ -1,5 +1,5 @@ // Platform: android -// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c +// 7c5fcc5a5adfbf3fb8ceaf36fbdd4bd970bd9c20 /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file @@ -19,7 +19,7 @@ under the License. */ ;(function() { -var PLATFORM_VERSION_BUILD_LABEL = '4.1.1'; +var PLATFORM_VERSION_BUILD_LABEL = '6.1.2'; // file: src/scripts/require.js /*jshint -W079 */ @@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { // file: src/cordova.js define("cordova", function(require, exports, module) { -if(window.cordova){ +// 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)) { throw new Error("cordova already defined"); } @@ -740,8 +742,13 @@ var Channel = function(type, sticky) { } }; -function forceFunction(f) { - if (typeof f != 'function') throw "Function required as first argument!"; +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." + ); + } } /** @@ -751,28 +758,39 @@ function forceFunction(f) { * and a guid that can be used to stop subscribing to the channel. * Returns the guid. */ -Channel.prototype.subscribe = function(f, c) { - // need a function to call - forceFunction(f); +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) { - f.apply(c || this, this.fireArgs); + handleEvent.apply(eventListener || this, this.fireArgs); return; } - var func = f, - guid = f.observer_guid; - if (typeof c == "object") { func = utils.close(c, f); } + guid = eventListenerOrFunction.observer_guid; + if (typeof eventListener === "object") { + handleEvent = utils.close(eventListener, handleEvent); + } if (!guid) { - // first time any channel has seen this subscriber + // First time any channel has seen this subscriber guid = '' + nextGuid++; } - func.observer_guid = guid; - f.observer_guid = guid; + handleEvent.observer_guid = guid; + eventListenerOrFunction.observer_guid = guid; // Don't add the same handler more than once. if (!this.handlers[guid]) { - this.handlers[guid] = func; + this.handlers[guid] = handleEvent; this.numHandlers++; if (this.numHandlers == 1) { this.onHasSubscribersChange && this.onHasSubscribersChange(); @@ -783,12 +801,20 @@ Channel.prototype.subscribe = function(f, c) { /** * Unsubscribes the function with the given guid from the channel. */ -Channel.prototype.unsubscribe = function(f) { - // need a function to unsubscribe - forceFunction(f); +Channel.prototype.unsubscribe = function(eventListenerOrFunction) { + checkSubscriptionArgument(eventListenerOrFunction); + var handleEvent, guid, handler; - var guid = f.observer_guid, - handler = this.handlers[guid]; + 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--; @@ -895,10 +921,11 @@ var cordova = require('cordova'), // For the ONLINE_EVENT to be viable, it would need to intercept all event // listeners (both through addEventListener and window.ononline) as well // as set the navigator property itself. - ONLINE_EVENT: 2 + ONLINE_EVENT: 2, + EVAL_BRIDGE: 3 }, jsToNativeBridgeMode, // Set lazily. - nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT, + nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE, pollEnabled = false, bridgeSecret = -1; @@ -921,6 +948,9 @@ function androidExec(success, fail, service, action, args) { androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT); } + // If args is not provided, default to an empty array + args = args || []; + // Process any ArrayBuffers in the args into a string. for (var i = 0; i < args.length; i++) { if (utils.typeName(args[i]) == 'ArrayBuffer') { @@ -930,7 +960,6 @@ function androidExec(success, fail, service, action, args) { var callbackId = service + cordova.callbackId++, argsJson = JSON.stringify(args); - if (success || fail) { cordova.callbacks[callbackId] = {success:success, fail:fail}; } @@ -950,6 +979,17 @@ function androidExec(success, fail, service, action, args) { } androidExec.init = function() { + //CB-11828 + //This failsafe checks the version of Android and if it's Jellybean, it switches it to + //using the Online Event bridge for communicating from Native to JS + // + //It's ugly, but it's necessary. + var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/); + var version_code = check && check[0].match(/4.[0-3].*/); + if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) { + nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT; + } + bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode); channel.onNativeReady.fire(); }; @@ -1291,10 +1331,12 @@ 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]; +var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady]; // setting exec cordova.exec = require('cordova/exec'); @@ -1379,10 +1421,19 @@ if (window._nativeReady) { // 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(); @@ -1499,11 +1550,111 @@ exports.getOriginalSymbol = function(context, symbolPath) { exports.reset(); +}); + +// file: src/common/modulemapper_b.js +define("cordova/modulemapper_b", function(require, exports, module) { + +var builder = require('cordova/builder'), + symbolList = [], + 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) { + 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); + // + 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/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js define("cordova/platform", function(require, exports, module) { +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -1543,6 +1694,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -1564,12 +1728,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } @@ -1673,10 +1855,6 @@ module.exports = { // file: src/common/pluginloader.js define("cordova/pluginloader", function(require, exports, module) { -/* - NOTE: this file is NOT used when we use the browserify workflow -*/ - var modulemapper = require('cordova/modulemapper'); var urlutil = require('cordova/urlutil'); @@ -1784,6 +1962,54 @@ exports.load = function(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++) { + 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 @@ -1895,7 +2121,10 @@ utils.clone = function(obj) { retVal = {}; for(i in obj){ - if(!(i in retVal) || retVal[i] != obj[i]) { + // 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') { retVal[i] = utils.clone(obj[i]); } } diff --git a/StoneIsland/platforms/android/platform_www/cordova_plugins.js b/StoneIsland/platforms/android/platform_www/cordova_plugins.js index a2734881..722b1683 100755 --- a/StoneIsland/platforms/android/platform_www/cordova_plugins.js +++ b/StoneIsland/platforms/android/platform_www/cordova_plugins.js @@ -104,6 +104,14 @@ module.exports = [ "cordova.plugins.Keyboard" ], "runs": true + }, + { + "id": "phonegap-plugin-push.PushNotification", + "file": "plugins/phonegap-plugin-push/www/push.js", + "pluginId": "phonegap-plugin-push", + "clobbers": [ + "PushNotification" + ] } ]; module.exports.metadata = @@ -121,7 +129,8 @@ module.exports.metadata = "cordova-plugin-splashscreen": "4.0.0", "cordova-plugin-compat": "1.1.0", "cordova-plugin-geolocation": "2.4.0", - "ionic-plugin-keyboard": "2.2.1" -} + "ionic-plugin-keyboard": "2.2.1", + "phonegap-plugin-push": "1.9.2" +}; // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/StoneIsland/platforms/android/platform_www/plugins/phonegap-plugin-push/www/push.js b/StoneIsland/platforms/android/platform_www/plugins/phonegap-plugin-push/www/push.js new file mode 100644 index 00000000..a5315486 --- /dev/null +++ b/StoneIsland/platforms/android/platform_www/plugins/phonegap-plugin-push/www/push.js @@ -0,0 +1,329 @@ +cordova.define("phonegap-plugin-push.PushNotification", function(require, exports, module) { +/* global cordova:false */ +/* globals window */ + +/*! + * Module dependencies. + */ + +var exec = cordova.require('cordova/exec'); + +/** + * PushNotification constructor. + * + * @param {Object} options to initiate Push Notifications. + * @return {PushNotification} instance that can be monitored and cancelled. + */ + +var PushNotification = function(options) { + this._handlers = { + 'registration': [], + 'notification': [], + 'error': [] + }; + + // require options parameter + if (typeof options === 'undefined') { + throw new Error('The options argument is required.'); + } + + // store the options to this object instance + this.options = options; + + // triggered on registration and notification + var that = this; + var success = function(result) { + if (result && typeof result.registrationId !== 'undefined') { + that.emit('registration', result); + } else if (result && result.additionalData && typeof result.additionalData.actionCallback !== 'undefined') { + var executeFuctionOrEmitEventByName = function(callbackName, context, arg) { + var namespaces = callbackName.split('.'); + var func = namespaces.pop(); + for (var i = 0; i < namespaces.length; i++) { + context = context[namespaces[i]]; + } + + if (typeof context[func] === 'function') { + context[func].call(context, arg); + } else { + that.emit(callbackName, arg); + } + }; + + executeFuctionOrEmitEventByName(result.additionalData.actionCallback, window, result); + } else if (result) { + that.emit('notification', result); + } + }; + + // triggered on error + var fail = function(msg) { + var e = (typeof msg === 'string') ? new Error(msg) : msg; + that.emit('error', e); + }; + + // wait at least one process tick to allow event subscriptions + setTimeout(function() { + exec(success, fail, 'PushNotification', 'init', [options]); + }, 10); +}; + +/** + * Unregister from push notifications + */ + +PushNotification.prototype.unregister = function(successCallback, errorCallback, options) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.unregister failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.unregister failure: success callback parameter must be a function'); + return; + } + + var that = this; + var cleanHandlersAndPassThrough = function() { + if (!options) { + that._handlers = { + 'registration': [], + 'notification': [], + 'error': [] + }; + } + successCallback(); + }; + + exec(cleanHandlersAndPassThrough, errorCallback, 'PushNotification', 'unregister', [options]); +}; + +/** + * subscribe to a topic + * @param {String} topic topic to subscribe + * @param {Function} successCallback success callback + * @param {Function} errorCallback error callback + * @return {void} + */ +PushNotification.prototype.subscribe = function(topic, successCallback, errorCallback) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.subscribe failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.subscribe failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'subscribe', [topic]); +}; + +/** + * unsubscribe to a topic + * @param {String} topic topic to unsubscribe + * @param {Function} successCallback success callback + * @param {Function} errorCallback error callback + * @return {void} + */ +PushNotification.prototype.unsubscribe = function(topic, successCallback, errorCallback) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.unsubscribe failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.unsubscribe failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'unsubscribe', [topic]); +}; + +/** + * Call this to set the application icon badge + */ + +PushNotification.prototype.setApplicationIconBadgeNumber = function(successCallback, errorCallback, badge) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.setApplicationIconBadgeNumber failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.setApplicationIconBadgeNumber failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'setApplicationIconBadgeNumber', [{badge: badge}]); +}; + +/** + * Get the application icon badge + */ + +PushNotification.prototype.getApplicationIconBadgeNumber = function(successCallback, errorCallback) { + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.getApplicationIconBadgeNumber failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.getApplicationIconBadgeNumber failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'getApplicationIconBadgeNumber', []); +}; + +/** + * Get the application icon badge + */ + +PushNotification.prototype.clearAllNotifications = function(successCallback, errorCallback) { + if (!successCallback) { successCallback = function() {}; } + if (!errorCallback) { errorCallback = function() {}; } + + if (typeof errorCallback !== 'function') { + console.log('PushNotification.clearAllNotifications failure: failure parameter not a function'); + return; + } + + if (typeof successCallback !== 'function') { + console.log('PushNotification.clearAllNotifications failure: success callback parameter must be a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'clearAllNotifications', []); +}; + +/** + * Listen for an event. + * + * Any event is supported, but the following are built-in: + * + * - registration + * - notification + * - error + * + * @param {String} eventName to subscribe to. + * @param {Function} callback triggered on the event. + */ + +PushNotification.prototype.on = function(eventName, callback) { + if (!this._handlers.hasOwnProperty(eventName)) { + this._handlers[eventName] = []; + } + this._handlers[eventName].push(callback); +}; + +/** + * Remove event listener. + * + * @param {String} eventName to match subscription. + * @param {Function} handle function associated with event. + */ + +PushNotification.prototype.off = function (eventName, handle) { + if (this._handlers.hasOwnProperty(eventName)) { + var handleIndex = this._handlers[eventName].indexOf(handle); + if (handleIndex >= 0) { + this._handlers[eventName].splice(handleIndex, 1); + } + } +}; + +/** + * Emit an event. + * + * This is intended for internal use only. + * + * @param {String} eventName is the event to trigger. + * @param {*} all arguments are passed to the event listeners. + * + * @return {Boolean} is true when the event is triggered otherwise false. + */ + +PushNotification.prototype.emit = function() { + var args = Array.prototype.slice.call(arguments); + var eventName = args.shift(); + + if (!this._handlers.hasOwnProperty(eventName)) { + return false; + } + + for (var i = 0, length = this._handlers[eventName].length; i < length; i++) { + var callback = this._handlers[eventName][i]; + if (typeof callback === 'function') { + callback.apply(undefined,args); + } else { + console.log('event handler: ' + eventName + ' must be a function'); + } + } + + return true; +}; + +PushNotification.prototype.finish = function(successCallback, errorCallback, id) { + if (!successCallback) { successCallback = function() {}; } + if (!errorCallback) { errorCallback = function() {}; } + if (!id) { id = 'handler'; } + + if (typeof successCallback !== 'function') { + console.log('finish failure: success callback parameter must be a function'); + return; + } + + if (typeof errorCallback !== 'function') { + console.log('finish failure: failure parameter not a function'); + return; + } + + exec(successCallback, errorCallback, 'PushNotification', 'finish', [id]); +}; + +/*! + * Push Notification Plugin. + */ + +module.exports = { + /** + * Register for Push Notifications. + * + * This method will instantiate a new copy of the PushNotification object + * and start the registration process. + * + * @param {Object} options + * @return {PushNotification} instance + */ + + init: function(options) { + return new PushNotification(options); + }, + + hasPermission: function(successCallback, errorCallback) { + exec(successCallback, errorCallback, 'PushNotification', 'hasPermission', []); + }, + + /** + * PushNotification Object. + * + * Expose the PushNotification object for direct use + * and testing. Typically, you should use the + * .init helper method. + */ + + PushNotification: PushNotification +}; + +}); diff --git a/StoneIsland/platforms/android/project.properties b/StoneIsland/platforms/android/project.properties index b06f0fa0..6936daa2 100755 --- a/StoneIsland/platforms/android/project.properties +++ b/StoneIsland/platforms/android/project.properties @@ -10,5 +10,9 @@ # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-22 +target=android-25 android.library.reference.1=CordovaLib +cordova.gradle.include.1=phonegap-plugin-push/stoneisland-push.gradle +cordova.system.library.1=com.android.support:support-v13:23+ +cordova.system.library.2=com.google.android.gms:play-services-gcm:9.8+ +cordova.system.library.3=me.leolin:ShortcutBadger:1.1.11@aar \ No newline at end of file diff --git a/StoneIsland/platforms/android/res/values/strings.xml b/StoneIsland/platforms/android/res/values/strings.xml index bd922fe9..60540e70 100755 --- a/StoneIsland/platforms/android/res/values/strings.xml +++ b/StoneIsland/platforms/android/res/values/strings.xml @@ -3,4 +3,5 @@ Stone Island @string/app_name @string/launcher_name + XXXXXXX diff --git a/StoneIsland/platforms/android/res/xml/config.xml b/StoneIsland/platforms/android/res/xml/config.xml old mode 100755 new mode 100644 index b9330793..00961deb --- a/StoneIsland/platforms/android/res/xml/config.xml +++ b/StoneIsland/platforms/android/res/xml/config.xml @@ -1,5 +1,5 @@ - + @@ -69,4 +69,7 @@ + + + diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/BackgroundActionButtonHandler.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/BackgroundActionButtonHandler.java new file mode 100644 index 00000000..3ccea6cb --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/BackgroundActionButtonHandler.java @@ -0,0 +1,41 @@ +package com.adobe.phonegap.push; + +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.support.v4.app.RemoteInput; + +public class BackgroundActionButtonHandler extends BroadcastReceiver implements PushConstants { + private static String LOG_TAG = "PushPlugin_BackgroundActionButtonHandler"; + + @Override + public void onReceive(Context context, Intent intent) { + Bundle extras = intent.getExtras(); + Log.d(LOG_TAG, "BackgroundActionButtonHandler = " + extras); + + int notId = intent.getIntExtra(NOT_ID, 0); + Log.d(LOG_TAG, "not id = " + notId); + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(GCMIntentService.getAppName(context), notId); + + if (extras != null) { + Bundle originalExtras = extras.getBundle(PUSH_BUNDLE); + + originalExtras.putBoolean(FOREGROUND, false); + originalExtras.putBoolean(COLDSTART, false); + originalExtras.putString(ACTION_CALLBACK, extras.getString(CALLBACK)); + + Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); + if (remoteInput != null) { + String inputString = remoteInput.getCharSequence(INLINE_REPLY).toString(); + Log.d(LOG_TAG, "response: " + inputString); + originalExtras.putString(INLINE_REPLY, inputString); + } + + PushPlugin.sendExtras(originalExtras); + } + } +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/GCMIntentService.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/GCMIntentService.java new file mode 100644 index 00000000..e1a2b75c --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/GCMIntentService.java @@ -0,0 +1,802 @@ +package com.adobe.phonegap.push; + +import android.annotation.SuppressLint; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; +import android.support.v4.app.NotificationCompat.WearableExtender; +import android.support.v4.app.RemoteInput; +import android.text.Html; +import android.text.Spanned; +import android.util.Log; + +import com.google.android.gms.gcm.GcmListenerService; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Random; + +@SuppressLint("NewApi") +public class GCMIntentService extends GcmListenerService implements PushConstants { + + private static final String LOG_TAG = "PushPlugin_GCMIntentService"; + private static HashMap> messageMap = new HashMap>(); + + public void setNotification(int notId, String message){ + ArrayList messageList = messageMap.get(notId); + if(messageList == null) { + messageList = new ArrayList(); + messageMap.put(notId, messageList); + } + + if(message.isEmpty()){ + messageList.clear(); + }else{ + messageList.add(message); + } + } + + @Override + public void onMessageReceived(String from, Bundle extras) { + Log.d(LOG_TAG, "onMessage - from: " + from); + + if (extras != null) { + Context applicationContext = getApplicationContext(); + + SharedPreferences prefs = applicationContext.getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + boolean forceShow = prefs.getBoolean(FORCE_SHOW, false); + boolean clearBadge = prefs.getBoolean(CLEAR_BADGE, false); + + extras = normalizeExtras(applicationContext, extras); + + if (clearBadge) { + PushPlugin.setApplicationIconBadgeNumber(getApplicationContext(), 0); + } + + // if we are in the foreground and forceShow is `false` only send data + if (!forceShow && PushPlugin.isInForeground()) { + Log.d(LOG_TAG, "foreground"); + extras.putBoolean(FOREGROUND, true); + extras.putBoolean(COLDSTART, false); + PushPlugin.sendExtras(extras); + } + // if we are in the foreground and forceShow is `true`, force show the notification if the data has at least a message or title + else if (forceShow && PushPlugin.isInForeground()) { + Log.d(LOG_TAG, "foreground force"); + extras.putBoolean(FOREGROUND, true); + extras.putBoolean(COLDSTART, false); + + showNotificationIfPossible(applicationContext, extras); + } + // if we are not in the foreground always send notification if the data has at least a message or title + else { + Log.d(LOG_TAG, "background"); + extras.putBoolean(FOREGROUND, false); + extras.putBoolean(COLDSTART, PushPlugin.isActive()); + + showNotificationIfPossible(applicationContext, extras); + } + } + } + + /* + * Change a values key in the extras bundle + */ + private void replaceKey(Context context, String oldKey, String newKey, Bundle extras, Bundle newExtras) { + Object value = extras.get(oldKey); + if ( value != null ) { + if (value instanceof String) { + value = localizeKey(context, newKey, (String) value); + + newExtras.putString(newKey, (String) value); + } else if (value instanceof Boolean) { + newExtras.putBoolean(newKey, (Boolean) value); + } else if (value instanceof Number) { + newExtras.putDouble(newKey, ((Number) value).doubleValue()); + } else { + newExtras.putString(newKey, String.valueOf(value)); + } + } + } + + /* + * Normalize localization for key + */ + private String localizeKey(Context context, String key, String value) { + if (key.equals(TITLE) || key.equals(MESSAGE) || key.equals(SUMMARY_TEXT)) { + try { + JSONObject localeObject = new JSONObject(value); + + String localeKey = localeObject.getString(LOC_KEY); + + ArrayList localeFormatData = new ArrayList(); + if (!localeObject.isNull(LOC_DATA)) { + String localeData = localeObject.getString(LOC_DATA); + JSONArray localeDataArray = new JSONArray(localeData); + for (int i = 0 ; i < localeDataArray.length(); i++) { + localeFormatData.add(localeDataArray.getString(i)); + } + } + + String packageName = context.getPackageName(); + Resources resources = context.getResources(); + + int resourceId = resources.getIdentifier(localeKey, "string", packageName); + + if (resourceId != 0) { + return resources.getString(resourceId, localeFormatData.toArray()); + } + else { + Log.d(LOG_TAG, "can't find resource for locale key = " + localeKey); + + return value; + } + } + catch(JSONException e) { + Log.d(LOG_TAG, "no locale found for key = " + key + ", error " + e.getMessage()); + + return value; + } + } + + return value; + } + + /* + * Replace alternate keys with our canonical value + */ + private String normalizeKey(String key) { + if (key.equals(BODY) || key.equals(ALERT) || key.equals(GCM_NOTIFICATION_BODY) || key.equals(TWILIO_BODY)) { + return MESSAGE; + } else if (key.equals(TWILIO_TITLE)) { + return TITLE; + }else if (key.equals(MSGCNT) || key.equals(BADGE)) { + return COUNT; + } else if (key.equals(SOUNDNAME) || key.equals(TWILIO_SOUND)) { + return SOUND; + } else if (key.startsWith(GCM_NOTIFICATION)) { + return key.substring(GCM_NOTIFICATION.length()+1, key.length()); + } else if (key.startsWith(GCM_N)) { + return key.substring(GCM_N.length()+1, key.length()); + } else if (key.startsWith(UA_PREFIX)) { + key = key.substring(UA_PREFIX.length()+1, key.length()); + return key.toLowerCase(); + } else { + return key; + } + } + + /* + * Parse bundle into normalized keys. + */ + private Bundle normalizeExtras(Context context, Bundle extras) { + Log.d(LOG_TAG, "normalize extras"); + Iterator it = extras.keySet().iterator(); + Bundle newExtras = new Bundle(); + + while (it.hasNext()) { + String key = it.next(); + + Log.d(LOG_TAG, "key = " + key); + + // If normalizeKeythe key is "data" or "message" and the value is a json object extract + // This is to support parse.com and other services. Issue #147 and pull #218 + if (key.equals(PARSE_COM_DATA) || key.equals(MESSAGE)) { + Object json = extras.get(key); + // Make sure data is json object stringified + if ( json instanceof String && ((String) json).startsWith("{") ) { + Log.d(LOG_TAG, "extracting nested message data from key = " + key); + try { + // If object contains message keys promote each value to the root of the bundle + JSONObject data = new JSONObject((String) json); + if ( data.has(ALERT) || data.has(MESSAGE) || data.has(BODY) || data.has(TITLE) ) { + Iterator jsonIter = data.keys(); + while (jsonIter.hasNext()) { + String jsonKey = jsonIter.next(); + + Log.d(LOG_TAG, "key = data/" + jsonKey); + + String value = data.getString(jsonKey); + jsonKey = normalizeKey(jsonKey); + value = localizeKey(context, jsonKey, value); + + newExtras.putString(jsonKey, value); + } + } + } catch( JSONException e) { + Log.e(LOG_TAG, "normalizeExtras: JSON exception"); + } + } + } else if (key.equals(("notification"))) { + Bundle value = extras.getBundle(key); + Iterator iterator = value.keySet().iterator(); + while (iterator.hasNext()) { + String notifkey = iterator.next(); + + Log.d(LOG_TAG, "notifkey = " + notifkey); + String newKey = normalizeKey(notifkey); + Log.d(LOG_TAG, "replace key " + notifkey + " with " + newKey); + + String valueData = value.getString(notifkey); + valueData = localizeKey(context, newKey, valueData); + + newExtras.putString(newKey, valueData); + } + continue; + } + + String newKey = normalizeKey(key); + Log.d(LOG_TAG, "replace key " + key + " with " + newKey); + replaceKey(context, key, newKey, extras, newExtras); + + } // while + + return newExtras; + } + + private int extractBadgeCount(Bundle extras) { + int count = -1; + String msgcnt = extras.getString(COUNT); + + try { + if (msgcnt != null) { + count = Integer.parseInt(msgcnt); + } + } catch (NumberFormatException e) { + Log.e(LOG_TAG, e.getLocalizedMessage(), e); + } + + return count; + } + + private void showNotificationIfPossible (Context context, Bundle extras) { + + // Send a notification if there is a message or title, otherwise just send data + String message = extras.getString(MESSAGE); + String title = extras.getString(TITLE); + String contentAvailable = extras.getString(CONTENT_AVAILABLE); + String forceStart = extras.getString(FORCE_START); + int badgeCount = extractBadgeCount(extras); + if (badgeCount >= 0) { + Log.d(LOG_TAG, "count =[" + badgeCount + "]"); + PushPlugin.setApplicationIconBadgeNumber(context, badgeCount); + } + + Log.d(LOG_TAG, "message =[" + message + "]"); + Log.d(LOG_TAG, "title =[" + title + "]"); + Log.d(LOG_TAG, "contentAvailable =[" + contentAvailable + "]"); + Log.d(LOG_TAG, "forceStart =[" + forceStart + "]"); + + if ((message != null && message.length() != 0) || + (title != null && title.length() != 0)) { + + Log.d(LOG_TAG, "create notification"); + + if(title == null || title.isEmpty()){ + extras.putString(TITLE, getAppName(this)); + } + + createNotification(context, extras); + } + + if(!PushPlugin.isActive() && "1".equals(forceStart)){ + Log.d(LOG_TAG, "app is not running but we should start it and put in background"); + Intent intent = new Intent(this, PushHandlerActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(PUSH_BUNDLE, extras); + intent.putExtra(START_IN_BACKGROUND, true); + intent.putExtra(FOREGROUND, false); + startActivity(intent); + } else if ("1".equals(contentAvailable)) { + Log.d(LOG_TAG, "app is not running and content available true"); + Log.d(LOG_TAG, "send notification event"); + PushPlugin.sendExtras(extras); + } + } + + public void createNotification(Context context, Bundle extras) { + NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + String appName = getAppName(this); + String packageName = context.getPackageName(); + Resources resources = context.getResources(); + + int notId = parseInt(NOT_ID, extras); + Intent notificationIntent = new Intent(this, PushHandlerActivity.class); + notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + notificationIntent.putExtra(PUSH_BUNDLE, extras); + notificationIntent.putExtra(NOT_ID, notId); + + int requestCode = new Random().nextInt(); + PendingIntent contentIntent = PendingIntent.getActivity(this, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + NotificationCompat.Builder mBuilder = + new NotificationCompat.Builder(context) + .setWhen(System.currentTimeMillis()) + .setContentTitle(fromHtml(extras.getString(TITLE))) + .setTicker(fromHtml(extras.getString(TITLE))) + .setContentIntent(contentIntent) + .setAutoCancel(true); + + SharedPreferences prefs = context.getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + String localIcon = prefs.getString(ICON, null); + String localIconColor = prefs.getString(ICON_COLOR, null); + boolean soundOption = prefs.getBoolean(SOUND, true); + boolean vibrateOption = prefs.getBoolean(VIBRATE, true); + Log.d(LOG_TAG, "stored icon=" + localIcon); + Log.d(LOG_TAG, "stored iconColor=" + localIconColor); + Log.d(LOG_TAG, "stored sound=" + soundOption); + Log.d(LOG_TAG, "stored vibrate=" + vibrateOption); + + /* + * Notification Vibration + */ + + setNotificationVibration(extras, vibrateOption, mBuilder); + + /* + * Notification Icon Color + * + * Sets the small-icon background color of the notification. + * To use, add the `iconColor` key to plugin android options + * + */ + setNotificationIconColor(extras.getString("color"), mBuilder, localIconColor); + + /* + * Notification Icon + * + * Sets the small-icon of the notification. + * + * - checks the plugin options for `icon` key + * - if none, uses the application icon + * + * The icon value must be a string that maps to a drawable resource. + * If no resource is found, falls + * + */ + setNotificationSmallIcon(context, extras, packageName, resources, mBuilder, localIcon); + + /* + * Notification Large-Icon + * + * Sets the large-icon of the notification + * + * - checks the gcm data for the `image` key + * - checks to see if remote image, loads it. + * - checks to see if assets image, Loads It. + * - checks to see if resource image, LOADS IT! + * - if none, we don't set the large icon + * + */ + setNotificationLargeIcon(extras, packageName, resources, mBuilder); + + /* + * Notification Sound + */ + if (soundOption) { + setNotificationSound(context, extras, mBuilder); + } + + /* + * LED Notification + */ + setNotificationLedColor(extras, mBuilder); + + /* + * Priority Notification + */ + setNotificationPriority(extras, mBuilder); + + /* + * Notification message + */ + setNotificationMessage(notId, extras, mBuilder); + + /* + * Notification count + */ + setNotificationCount(context, extras, mBuilder); + + /* + * Notification count + */ + setVisibility(context, extras, mBuilder); + + /* + * Notification add actions + */ + createActions(extras, mBuilder, resources, packageName, notId); + + mNotificationManager.notify(appName, notId, mBuilder.build()); + } + + private void updateIntent(Intent intent, String callback, Bundle extras, boolean foreground, int notId) { + intent.putExtra(CALLBACK, callback); + intent.putExtra(PUSH_BUNDLE, extras); + intent.putExtra(FOREGROUND, foreground); + intent.putExtra(NOT_ID, notId); + } + + private void createActions(Bundle extras, NotificationCompat.Builder mBuilder, Resources resources, String packageName, int notId) { + Log.d(LOG_TAG, "create actions: with in-line"); + String actions = extras.getString(ACTIONS); + if (actions != null) { + try { + JSONArray actionsArray = new JSONArray(actions); + ArrayList wActions = new ArrayList(); + for (int i=0; i < actionsArray.length(); i++) { + int min = 1; + int max = 2000000000; + Random random = new Random(); + int uniquePendingIntentRequestCode = random.nextInt((max - min) + 1) + min; + Log.d(LOG_TAG, "adding action"); + JSONObject action = actionsArray.getJSONObject(i); + Log.d(LOG_TAG, "adding callback = " + action.getString(CALLBACK)); + boolean foreground = action.optBoolean(FOREGROUND, true); + boolean inline = action.optBoolean("inline", false); + Intent intent = null; + PendingIntent pIntent = null; + if (inline) { + Log.d(LOG_TAG, "Version: " + android.os.Build.VERSION.SDK_INT + " = " + android.os.Build.VERSION_CODES.M); + if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.M) { + Log.d(LOG_TAG, "push activity"); + intent = new Intent(this, PushHandlerActivity.class); + } else { + Log.d(LOG_TAG, "push receiver"); + intent = new Intent(this, BackgroundActionButtonHandler.class); + } + + updateIntent(intent, action.getString(CALLBACK), extras, foreground, notId); + + if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.M) { + Log.d(LOG_TAG, "push activity for notId " + notId); + pIntent = PendingIntent.getActivity(this, uniquePendingIntentRequestCode, intent, PendingIntent.FLAG_ONE_SHOT); + } else { + Log.d(LOG_TAG, "push receiver for notId " + notId); + pIntent = PendingIntent.getBroadcast(this, uniquePendingIntentRequestCode, intent, PendingIntent.FLAG_ONE_SHOT); + } + } else if (foreground) { + intent = new Intent(this, PushHandlerActivity.class); + updateIntent(intent, action.getString(CALLBACK), extras, foreground, notId); + pIntent = PendingIntent.getActivity(this, uniquePendingIntentRequestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } else { + intent = new Intent(this, BackgroundActionButtonHandler.class); + updateIntent(intent, action.getString(CALLBACK), extras, foreground, notId); + pIntent = PendingIntent.getBroadcast(this, uniquePendingIntentRequestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + + NotificationCompat.Action.Builder actionBuilder = + new NotificationCompat.Action.Builder(resources.getIdentifier(action.optString(ICON, ""), DRAWABLE, packageName), + action.getString(TITLE), pIntent); + + RemoteInput remoteInput = null; + if (inline) { + Log.d(LOG_TAG, "create remote input"); + String replyLabel = "Enter your reply here"; + remoteInput = + new RemoteInput.Builder(INLINE_REPLY) + .setLabel(replyLabel) + .build(); + actionBuilder.addRemoteInput(remoteInput); + } + + NotificationCompat.Action wAction = actionBuilder.build(); + wActions.add(actionBuilder.build()); + + if (inline) { + mBuilder.addAction(wAction); + } else { + mBuilder.addAction(resources.getIdentifier(action.optString(ICON, ""), DRAWABLE, packageName), + action.getString(TITLE), pIntent); + } + wAction = null; + pIntent = null; + } + mBuilder.extend(new WearableExtender().addActions(wActions)); + wActions.clear(); + } catch(JSONException e) { + // nope + } + } + } + + private void setNotificationCount(Context context, Bundle extras, NotificationCompat.Builder mBuilder) { + int count = extractBadgeCount(extras); + if (count >= 0) { + Log.d(LOG_TAG, "count =[" + count + "]"); + mBuilder.setNumber(count); + } + } + + + private void setVisibility(Context context, Bundle extras, NotificationCompat.Builder mBuilder) { + String visibilityStr = extras.getString(VISIBILITY); + if (visibilityStr != null) { + try { + Integer visibility = Integer.parseInt(visibilityStr); + if (visibility >= NotificationCompat.VISIBILITY_SECRET && visibility <= NotificationCompat.VISIBILITY_PUBLIC) { + mBuilder.setVisibility(visibility); + } else { + Log.e(LOG_TAG, "Visibility parameter must be between -1 and 1"); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + } + + private void setNotificationVibration(Bundle extras, Boolean vibrateOption, NotificationCompat.Builder mBuilder) { + String vibrationPattern = extras.getString(VIBRATION_PATTERN); + if (vibrationPattern != null) { + String[] items = vibrationPattern.replaceAll("\\[", "").replaceAll("\\]", "").split(","); + long[] results = new long[items.length]; + for (int i = 0; i < items.length; i++) { + try { + results[i] = Long.parseLong(items[i].trim()); + } catch (NumberFormatException nfe) {} + } + mBuilder.setVibrate(results); + } else { + if (vibrateOption) { + mBuilder.setDefaults(Notification.DEFAULT_VIBRATE); + } + } + } + + private void setNotificationMessage(int notId, Bundle extras, NotificationCompat.Builder mBuilder) { + String message = extras.getString(MESSAGE); + + String style = extras.getString(STYLE, STYLE_TEXT); + if(STYLE_INBOX.equals(style)) { + setNotification(notId, message); + + mBuilder.setContentText(fromHtml(message)); + + ArrayList messageList = messageMap.get(notId); + Integer sizeList = messageList.size(); + if (sizeList > 1) { + String sizeListMessage = sizeList.toString(); + String stacking = sizeList + " more"; + if (extras.getString(SUMMARY_TEXT) != null) { + stacking = extras.getString(SUMMARY_TEXT); + stacking = stacking.replace("%n%", sizeListMessage); + } + NotificationCompat.InboxStyle notificationInbox = new NotificationCompat.InboxStyle() + .setBigContentTitle(fromHtml(extras.getString(TITLE))) + .setSummaryText(fromHtml(stacking)); + + for (int i = messageList.size() - 1; i >= 0; i--) { + notificationInbox.addLine(fromHtml(messageList.get(i))); + } + + mBuilder.setStyle(notificationInbox); + } else { + NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle(); + if (message != null) { + bigText.bigText(fromHtml(message)); + bigText.setBigContentTitle(fromHtml(extras.getString(TITLE))); + mBuilder.setStyle(bigText); + } + } + } else if (STYLE_PICTURE.equals(style)) { + setNotification(notId, ""); + + NotificationCompat.BigPictureStyle bigPicture = new NotificationCompat.BigPictureStyle(); + bigPicture.bigPicture(getBitmapFromURL(extras.getString(PICTURE))); + bigPicture.setBigContentTitle(fromHtml(extras.getString(TITLE))); + bigPicture.setSummaryText(fromHtml(extras.getString(SUMMARY_TEXT))); + + mBuilder.setContentTitle(fromHtml(extras.getString(TITLE))); + mBuilder.setContentText(fromHtml(message)); + + mBuilder.setStyle(bigPicture); + } else { + setNotification(notId, ""); + + NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle(); + + if (message != null) { + mBuilder.setContentText(fromHtml(message)); + + bigText.bigText(fromHtml(message)); + bigText.setBigContentTitle(fromHtml(extras.getString(TITLE))); + + String summaryText = extras.getString(SUMMARY_TEXT); + if (summaryText != null) { + bigText.setSummaryText(fromHtml(summaryText)); + } + + mBuilder.setStyle(bigText); + } + /* + else { + mBuilder.setContentText(""); + } + */ + } + } + + private void setNotificationSound(Context context, Bundle extras, NotificationCompat.Builder mBuilder) { + String soundname = extras.getString(SOUNDNAME); + if (soundname == null) { + soundname = extras.getString(SOUND); + } + if (SOUND_RINGTONE.equals(soundname)) { + mBuilder.setSound(android.provider.Settings.System.DEFAULT_RINGTONE_URI); + } else if (soundname != null && !soundname.contentEquals(SOUND_DEFAULT)) { + Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + + "://" + context.getPackageName() + "/raw/" + soundname); + Log.d(LOG_TAG, sound.toString()); + mBuilder.setSound(sound); + } else { + mBuilder.setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI); + } + } + + private void setNotificationLedColor(Bundle extras, NotificationCompat.Builder mBuilder) { + String ledColor = extras.getString(LED_COLOR); + if (ledColor != null) { + // Converts parse Int Array from ledColor + String[] items = ledColor.replaceAll("\\[", "").replaceAll("\\]", "").split(","); + int[] results = new int[items.length]; + for (int i = 0; i < items.length; i++) { + try { + results[i] = Integer.parseInt(items[i].trim()); + } catch (NumberFormatException nfe) {} + } + if (results.length == 4) { + mBuilder.setLights(Color.argb(results[0], results[1], results[2], results[3]), 500, 500); + } else { + Log.e(LOG_TAG, "ledColor parameter must be an array of length == 4 (ARGB)"); + } + } + } + + private void setNotificationPriority(Bundle extras, NotificationCompat.Builder mBuilder) { + String priorityStr = extras.getString(PRIORITY); + if (priorityStr != null) { + try { + Integer priority = Integer.parseInt(priorityStr); + if (priority >= NotificationCompat.PRIORITY_MIN && priority <= NotificationCompat.PRIORITY_MAX) { + mBuilder.setPriority(priority); + } else { + Log.e(LOG_TAG, "Priority parameter must be between -2 and 2"); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + } + + private void setNotificationLargeIcon(Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder) { + String gcmLargeIcon = extras.getString(IMAGE); // from gcm + if (gcmLargeIcon != null && !"".equals(gcmLargeIcon)) { + if (gcmLargeIcon.startsWith("http://") || gcmLargeIcon.startsWith("https://")) { + mBuilder.setLargeIcon(getBitmapFromURL(gcmLargeIcon)); + Log.d(LOG_TAG, "using remote large-icon from gcm"); + } else { + AssetManager assetManager = getAssets(); + InputStream istr; + try { + istr = assetManager.open(gcmLargeIcon); + Bitmap bitmap = BitmapFactory.decodeStream(istr); + mBuilder.setLargeIcon(bitmap); + Log.d(LOG_TAG, "using assets large-icon from gcm"); + } catch (IOException e) { + int largeIconId = 0; + largeIconId = resources.getIdentifier(gcmLargeIcon, DRAWABLE, packageName); + if (largeIconId != 0) { + Bitmap largeIconBitmap = BitmapFactory.decodeResource(resources, largeIconId); + mBuilder.setLargeIcon(largeIconBitmap); + Log.d(LOG_TAG, "using resources large-icon from gcm"); + } else { + Log.d(LOG_TAG, "Not setting large icon"); + } + } + } + } + } + + private void setNotificationSmallIcon(Context context, Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder, String localIcon) { + int iconId = 0; + String icon = extras.getString(ICON); + if (icon != null && !"".equals(icon)) { + iconId = resources.getIdentifier(icon, DRAWABLE, packageName); + Log.d(LOG_TAG, "using icon from plugin options"); + } + else if (localIcon != null && !"".equals(localIcon)) { + iconId = resources.getIdentifier(localIcon, DRAWABLE, packageName); + Log.d(LOG_TAG, "using icon from plugin options"); + } + if (iconId == 0) { + Log.d(LOG_TAG, "no icon resource found - using application icon"); + iconId = context.getApplicationInfo().icon; + } + mBuilder.setSmallIcon(iconId); + } + + private void setNotificationIconColor(String color, NotificationCompat.Builder mBuilder, String localIconColor) { + int iconColor = 0; + if (color != null && !"".equals(color)) { + try { + iconColor = Color.parseColor(color); + } catch (IllegalArgumentException e) { + Log.e(LOG_TAG, "couldn't parse color from android options"); + } + } + else if (localIconColor != null && !"".equals(localIconColor)) { + try { + iconColor = Color.parseColor(localIconColor); + } catch (IllegalArgumentException e) { + Log.e(LOG_TAG, "couldn't parse color from android options"); + } + } + if (iconColor != 0) { + mBuilder.setColor(iconColor); + } + } + + public Bitmap getBitmapFromURL(String strURL) { + try { + URL url = new URL(strURL); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + return BitmapFactory.decodeStream(input); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static String getAppName(Context context) { + CharSequence appName = context.getPackageManager().getApplicationLabel(context.getApplicationInfo()); + return (String)appName; + } + + private int parseInt(String value, Bundle extras) { + int retval = 0; + + try { + retval = Integer.parseInt(extras.getString(value)); + } + catch(NumberFormatException e) { + Log.e(LOG_TAG, "Number format exception - Error parsing " + value + ": " + e.getMessage()); + } + catch(Exception e) { + Log.e(LOG_TAG, "Number format exception - Error parsing " + value + ": " + e.getMessage()); + } + + return retval; + } + + private Spanned fromHtml(String source) { + if (source != null) + return Html.fromHtml(source); + else + return null; + } +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PermissionUtils.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PermissionUtils.java new file mode 100644 index 00000000..6aa5c9bf --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PermissionUtils.java @@ -0,0 +1,55 @@ +package com.adobe.phonegap.push; + +import android.content.Context; +import android.content.pm.ApplicationInfo; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class PermissionUtils { + + private static final String CHECK_OP_NO_THROW = "checkOpNoThrow"; + + public static boolean hasPermission(Context appContext, String appOpsServiceId) throws UnknownError { + + ApplicationInfo appInfo = appContext.getApplicationInfo(); + + String pkg = appContext.getPackageName(); + int uid = appInfo.uid; + Class appOpsClass = null; + Object appOps = appContext.getSystemService("appops"); + + try { + + appOpsClass = Class.forName("android.app.AppOpsManager"); + + Method checkOpNoThrowMethod = appOpsClass.getMethod( + CHECK_OP_NO_THROW, + Integer.TYPE, + Integer.TYPE, + String.class + ); + + Field opValue = appOpsClass.getDeclaredField(appOpsServiceId); + + int value = (int) opValue.getInt(Integer.class); + Object result = checkOpNoThrowMethod.invoke(appOps, value, uid, pkg); + + return Integer.parseInt(result.toString()) == 0; // AppOpsManager.MODE_ALLOWED + + } catch (ClassNotFoundException e) { + throw new UnknownError("class not found"); + } catch (NoSuchMethodException e) { + throw new UnknownError("no such method"); + } catch (NoSuchFieldException e) { + throw new UnknownError("no such field"); + } catch (InvocationTargetException e) { + throw new UnknownError("invocation target"); + } catch (IllegalAccessException e) { + throw new UnknownError("illegal access"); + } + + } + +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushConstants.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushConstants.java new file mode 100644 index 00000000..37874e04 --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushConstants.java @@ -0,0 +1,72 @@ +package com.adobe.phonegap.push; + +public interface PushConstants { + public static final String COM_ADOBE_PHONEGAP_PUSH = "com.adobe.phonegap.push"; + public static final String REGISTRATION_ID = "registrationId"; + public static final String FOREGROUND = "foreground"; + public static final String TITLE = "title"; + public static final String NOT_ID = "notId"; + public static final String PUSH_BUNDLE = "pushBundle"; + public static final String ICON = "icon"; + public static final String ICON_COLOR = "iconColor"; + public static final String SOUND = "sound"; + public static final String SOUND_DEFAULT = "default"; + public static final String SOUND_RINGTONE = "ringtone"; + public static final String VIBRATE = "vibrate"; + public static final String ACTIONS = "actions"; + public static final String CALLBACK = "callback"; + public static final String ACTION_CALLBACK = "actionCallback"; + public static final String DRAWABLE = "drawable"; + public static final String MSGCNT = "msgcnt"; + public static final String VIBRATION_PATTERN = "vibrationPattern"; + public static final String STYLE = "style"; + public static final String SUMMARY_TEXT = "summaryText"; + public static final String PICTURE = "picture"; + public static final String GCM_N = "gcm.n."; + public static final String GCM_NOTIFICATION = "gcm.notification"; + public static final String GCM_NOTIFICATION_BODY = "gcm.notification.body"; + public static final String UA_PREFIX = "com.urbanairship.push"; + public static final String PARSE_COM_DATA = "data"; + public static final String ALERT = "alert"; + public static final String MESSAGE = "message"; + public static final String BODY = "body"; + public static final String SOUNDNAME = "soundname"; + public static final String LED_COLOR = "ledColor"; + public static final String PRIORITY = "priority"; + public static final String IMAGE = "image"; + public static final String STYLE_INBOX = "inbox"; + public static final String STYLE_PICTURE = "picture"; + public static final String STYLE_TEXT = "text"; + public static final String BADGE = "badge"; + public static final String INITIALIZE = "init"; + public static final String SUBSCRIBE = "subscribe"; + public static final String UNSUBSCRIBE = "unsubscribe"; + public static final String UNREGISTER = "unregister"; + public static final String EXIT = "exit"; + public static final String FINISH = "finish"; + public static final String HAS_PERMISSION = "hasPermission"; + public static final String ANDROID = "android"; + public static final String SENDER_ID = "senderID"; + public static final String CLEAR_BADGE = "clearBadge"; + public static final String CLEAR_NOTIFICATIONS = "clearNotifications"; + public static final String COLDSTART = "coldstart"; + public static final String ADDITIONAL_DATA = "additionalData"; + public static final String COUNT = "count"; + public static final String FROM = "from"; + public static final String COLLAPSE_KEY = "collapse_key"; + public static final String FORCE_SHOW = "forceShow"; + public static final String GCM = "GCM"; + public static final String CONTENT_AVAILABLE = "content-available"; + public static final String TOPICS = "topics"; + public static final String SET_APPLICATION_ICON_BADGE_NUMBER = "setApplicationIconBadgeNumber"; + public static final String CLEAR_ALL_NOTIFICATIONS = "clearAllNotifications"; + public static final String VISIBILITY = "visibility"; + public static final String INLINE_REPLY = "inlineReply"; + public static final String LOC_KEY = "locKey"; + public static final String LOC_DATA = "locData"; + public static final String TWILIO_BODY = "twi_body"; + public static final String TWILIO_TITLE = "twi_title"; + public static final String TWILIO_SOUND = "twi_sound"; + public static final String START_IN_BACKGROUND = "cdvStartInBackground"; + public static final String FORCE_START = "force-start"; +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushHandlerActivity.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushHandlerActivity.java new file mode 100644 index 00000000..23682ac8 --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushHandlerActivity.java @@ -0,0 +1,120 @@ +package com.adobe.phonegap.push; + +import android.app.Activity; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.util.Log; +import android.support.v4.app.RemoteInput; + + +public class PushHandlerActivity extends Activity implements PushConstants { + private static String LOG_TAG = "PushPlugin_PushHandlerActivity"; + + /* + * this activity will be started if the user touches a notification that we own. + * We send it's data off to the push plugin for processing. + * If needed, we boot up the main activity to kickstart the application. + * @see android.app.Activity#onCreate(android.os.Bundle) + */ + @Override + public void onCreate(Bundle savedInstanceState) { + GCMIntentService gcm = new GCMIntentService(); + + Intent intent = getIntent(); + + int notId = intent.getExtras().getInt(NOT_ID, 0); + Log.d(LOG_TAG, "not id = " + notId); + gcm.setNotification(notId, ""); + super.onCreate(savedInstanceState); + Log.v(LOG_TAG, "onCreate"); + String callback = getIntent().getExtras().getString("callback"); + Log.d(LOG_TAG, "callback = " + callback); + boolean foreground = getIntent().getExtras().getBoolean("foreground", true); + boolean startOnBackground = getIntent().getExtras().getBoolean(START_IN_BACKGROUND, false); + + if(!startOnBackground){ + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(GCMIntentService.getAppName(this), notId); + } + + boolean isPushPluginActive = PushPlugin.isActive(); + boolean inline = processPushBundle(isPushPluginActive, intent); + + if(inline && android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N){ + foreground = true; + } + + Log.d(LOG_TAG, "bringToForeground = " + foreground); + + finish(); + + Log.d(LOG_TAG, "isPushPluginActive = " + isPushPluginActive); + if (!isPushPluginActive && foreground && inline) { + Log.d(LOG_TAG, "forceMainActivityReload"); + forceMainActivityReload(false); + } else if(startOnBackground) { + Log.d(LOG_TAG, "startOnBackgroundTrue"); + forceMainActivityReload(true); + } else { + Log.d(LOG_TAG, "don't want main activity"); + } + } + + /** + * Takes the pushBundle extras from the intent, + * and sends it through to the PushPlugin for processing. + */ + private boolean processPushBundle(boolean isPushPluginActive, Intent intent) { + Bundle extras = getIntent().getExtras(); + Bundle remoteInput = null; + + if (extras != null) { + Bundle originalExtras = extras.getBundle(PUSH_BUNDLE); + + originalExtras.putBoolean(FOREGROUND, false); + originalExtras.putBoolean(COLDSTART, !isPushPluginActive); + originalExtras.putString(ACTION_CALLBACK, extras.getString(CALLBACK)); + + remoteInput = RemoteInput.getResultsFromIntent(intent); + if (remoteInput != null) { + String inputString = remoteInput.getCharSequence(INLINE_REPLY).toString(); + Log.d(LOG_TAG, "response: " + inputString); + originalExtras.putString(INLINE_REPLY, inputString); + } + + PushPlugin.sendExtras(originalExtras); + } + return remoteInput == null; + } + + /** + * Forces the main activity to re-launch if it's unloaded. + */ + private void forceMainActivityReload(boolean startOnBackground) { + PackageManager pm = getPackageManager(); + Intent launchIntent = pm.getLaunchIntentForPackage(getApplicationContext().getPackageName()); + + Bundle extras = getIntent().getExtras(); + if (extras != null) { + Bundle originalExtras = extras.getBundle(PUSH_BUNDLE); + if (originalExtras != null) { + launchIntent.putExtras(originalExtras); + } + launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + launchIntent.addFlags(Intent.FLAG_FROM_BACKGROUND); + launchIntent.putExtra(START_IN_BACKGROUND, startOnBackground); + } + + startActivity(launchIntent); + } + + @Override + protected void onResume() { + super.onResume(); + final NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + } +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushInstanceIDListenerService.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushInstanceIDListenerService.java new file mode 100644 index 00000000..eaa39a48 --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushInstanceIDListenerService.java @@ -0,0 +1,27 @@ +package com.adobe.phonegap.push; + +import android.content.Intent; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +import com.google.android.gms.iid.InstanceID; +import com.google.android.gms.iid.InstanceIDListenerService; + +import org.json.JSONException; + +import java.io.IOException; + +public class PushInstanceIDListenerService extends InstanceIDListenerService implements PushConstants { + public static final String LOG_TAG = "PushPlugin_PushInstanceIDListenerService"; + + @Override + public void onTokenRefresh() { + SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + String senderID = sharedPref.getString(SENDER_ID, ""); + if (!"".equals(senderID)) { + Intent intent = new Intent(this, RegistrationIntentService.class); + startService(intent); + } + } +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushPlugin.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushPlugin.java new file mode 100644 index 00000000..f6faaa2b --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/PushPlugin.java @@ -0,0 +1,458 @@ +package com.adobe.phonegap.push; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; + +import com.google.android.gms.gcm.GcmPubSub; +import com.google.android.gms.iid.InstanceID; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; + +import me.leolin.shortcutbadger.ShortcutBadger; + +public class PushPlugin extends CordovaPlugin implements PushConstants { + + public static final String LOG_TAG = "PushPlugin"; + + private static CallbackContext pushContext; + private static CordovaWebView gWebView; + private static List gCachedExtras = Collections.synchronizedList(new ArrayList()); + private static boolean gForeground = false; + + private static String registration_id = ""; + + /** + * Gets the application context from cordova's main activity. + * @return the application context + */ + private Context getApplicationContext() { + return this.cordova.getActivity().getApplicationContext(); + } + + @Override + public boolean execute(final String action, final JSONArray data, final CallbackContext callbackContext) { + Log.v(LOG_TAG, "execute: action=" + action); + gWebView = this.webView; + + if (INITIALIZE.equals(action)) { + cordova.getThreadPool().execute(new Runnable() { + public void run() { + pushContext = callbackContext; + JSONObject jo = null; + + Log.v(LOG_TAG, "execute: data=" + data.toString()); + SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + String senderID = null; + + try { + jo = data.getJSONObject(0).getJSONObject(ANDROID); + + Log.v(LOG_TAG, "execute: jo=" + jo.toString()); + + senderID = jo.getString(SENDER_ID); + + Log.v(LOG_TAG, "execute: senderID=" + senderID); + + String savedSenderID = sharedPref.getString(SENDER_ID, ""); + registration_id = InstanceID.getInstance(getApplicationContext()).getToken(senderID, GCM); + + if (!"".equals(registration_id)) { + JSONObject json = new JSONObject().put(REGISTRATION_ID, registration_id); + + Log.v(LOG_TAG, "onRegistered: " + json.toString()); + + JSONArray topics = jo.optJSONArray(TOPICS); + subscribeToTopics(topics, registration_id); + + PushPlugin.sendEvent( json ); + } else { + callbackContext.error("Empty registration ID received from GCM"); + return; + } + } catch (JSONException e) { + Log.e(LOG_TAG, "execute: Got JSON Exception " + e.getMessage()); + callbackContext.error(e.getMessage()); + } catch (IOException e) { + Log.e(LOG_TAG, "execute: Got JSON Exception " + e.getMessage()); + callbackContext.error(e.getMessage()); + } + + if (jo != null) { + SharedPreferences.Editor editor = sharedPref.edit(); + try { + editor.putString(ICON, jo.getString(ICON)); + } catch (JSONException e) { + Log.d(LOG_TAG, "no icon option"); + } + try { + editor.putString(ICON_COLOR, jo.getString(ICON_COLOR)); + } catch (JSONException e) { + Log.d(LOG_TAG, "no iconColor option"); + } + + boolean clearBadge = jo.optBoolean(CLEAR_BADGE, false); + if (clearBadge) { + setApplicationIconBadgeNumber(getApplicationContext(), 0); + } + + editor.putBoolean(SOUND, jo.optBoolean(SOUND, true)); + editor.putBoolean(VIBRATE, jo.optBoolean(VIBRATE, true)); + editor.putBoolean(CLEAR_BADGE, clearBadge); + editor.putBoolean(CLEAR_NOTIFICATIONS, jo.optBoolean(CLEAR_NOTIFICATIONS, true)); + editor.putBoolean(FORCE_SHOW, jo.optBoolean(FORCE_SHOW, false)); + editor.putString(SENDER_ID, senderID); + editor.commit(); + + } + + if (!gCachedExtras.isEmpty()) { + Log.v(LOG_TAG, "sending cached extras"); + synchronized(gCachedExtras) { + Iterator gCachedExtrasIterator = gCachedExtras.iterator(); + while (gCachedExtrasIterator.hasNext()) { + sendExtras(gCachedExtrasIterator.next()); + } + } + gCachedExtras.clear(); + } + } + }); + } else if (UNREGISTER.equals(action)) { + cordova.getThreadPool().execute(new Runnable() { + public void run() { + try { + SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + JSONArray topics = data.optJSONArray(0); + if (topics != null && !"".equals(registration_id)) { + unsubscribeFromTopics(topics, registration_id); + } else { + InstanceID.getInstance(getApplicationContext()).deleteInstanceID(); + Log.v(LOG_TAG, "UNREGISTER"); + + // Remove shared prefs + SharedPreferences.Editor editor = sharedPref.edit(); + editor.remove(SOUND); + editor.remove(VIBRATE); + editor.remove(CLEAR_BADGE); + editor.remove(CLEAR_NOTIFICATIONS); + editor.remove(FORCE_SHOW); + editor.remove(SENDER_ID); + editor.commit(); + } + + callbackContext.success(); + } catch (IOException e) { + Log.e(LOG_TAG, "execute: Got JSON Exception " + e.getMessage()); + callbackContext.error(e.getMessage()); + } + } + }); + } else if (FINISH.equals(action)) { + callbackContext.success(); + } else if (HAS_PERMISSION.equals(action)) { + cordova.getThreadPool().execute(new Runnable() { + public void run() { + JSONObject jo = new JSONObject(); + try { + jo.put("isEnabled", PermissionUtils.hasPermission(getApplicationContext(), "OP_POST_NOTIFICATION")); + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, jo); + pluginResult.setKeepCallback(true); + callbackContext.sendPluginResult(pluginResult); + } catch (UnknownError e) { + callbackContext.error(e.getMessage()); + } catch (JSONException e) { + callbackContext.error(e.getMessage()); + } + } + }); + } else if (SET_APPLICATION_ICON_BADGE_NUMBER.equals(action)) { + cordova.getThreadPool().execute(new Runnable() { + public void run() { + Log.v(LOG_TAG, "setApplicationIconBadgeNumber: data=" + data.toString()); + try { + setApplicationIconBadgeNumber(getApplicationContext(), data.getJSONObject(0).getInt(BADGE)); + } catch (JSONException e) { + callbackContext.error(e.getMessage()); + } + callbackContext.success(); + } + }); + } else if (CLEAR_ALL_NOTIFICATIONS.equals(action)) { + cordova.getThreadPool().execute(new Runnable() { + public void run() { + Log.v(LOG_TAG, "clearAllNotifications"); + clearAllNotifications(); + callbackContext.success(); + } + }); + } else if (SUBSCRIBE.equals(action)){ + // Subscribing for a topic + cordova.getThreadPool().execute(new Runnable() { + public void run() { + try { + String topic = data.getString(0); + subscribeToTopic(topic, registration_id); + callbackContext.success(); + } catch (JSONException e) { + callbackContext.error(e.getMessage()); + } catch (IOException e) { + callbackContext.error(e.getMessage()); + } + } + }); + } else if (UNSUBSCRIBE.equals(action)){ + // un-subscribing for a topic + cordova.getThreadPool().execute(new Runnable(){ + public void run() { + try { + String topic = data.getString(0); + unsubscribeFromTopic(topic, registration_id); + callbackContext.success(); + } catch (JSONException e) { + callbackContext.error(e.getMessage()); + } catch (IOException e) { + callbackContext.error(e.getMessage()); + } + } + }); + } else { + Log.e(LOG_TAG, "Invalid action : " + action); + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.INVALID_ACTION)); + return false; + } + + return true; + } + + public static void sendEvent(JSONObject _json) { + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, _json); + pluginResult.setKeepCallback(true); + if (pushContext != null) { + pushContext.sendPluginResult(pluginResult); + } + } + + public static void sendError(String message) { + PluginResult pluginResult = new PluginResult(PluginResult.Status.ERROR, message); + pluginResult.setKeepCallback(true); + if (pushContext != null) { + pushContext.sendPluginResult(pluginResult); + } + } + + /* + * Sends the pushbundle extras to the client application. + * If the client application isn't currently active, it is cached for later processing. + */ + public static void sendExtras(Bundle extras) { + if (extras != null) { + if (gWebView != null) { + sendEvent(convertBundleToJson(extras)); + } else { + Log.v(LOG_TAG, "sendExtras: caching extras to send at a later time."); + gCachedExtras.add(extras); + } + } + } + + public static void setApplicationIconBadgeNumber(Context context, int badgeCount) { + if (badgeCount > 0) { + ShortcutBadger.applyCount(context, badgeCount); + } else { + ShortcutBadger.removeCount(context); + } + } + + @Override + public void initialize(CordovaInterface cordova, CordovaWebView webView) { + super.initialize(cordova, webView); + gForeground = true; + } + + @Override + public void onPause(boolean multitasking) { + super.onPause(multitasking); + gForeground = false; + + SharedPreferences prefs = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + if (prefs.getBoolean(CLEAR_NOTIFICATIONS, true)) { + clearAllNotifications(); + } + } + + @Override + public void onResume(boolean multitasking) { + super.onResume(multitasking); + gForeground = true; + } + + @Override + public void onDestroy() { + super.onDestroy(); + gForeground = false; + gWebView = null; + } + + private void clearAllNotifications() { + final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + } + + /** + * Transform `topic name` to `topic path` + * Normally, the `topic` inputed from end-user is `topic name` only. + * We should convert them to GCM `topic path` + * Example: + * when topic name = 'my-topic' + * then topic path = '/topics/my-topic' + * + * @param String topic The topic name + * @return The topic path + */ + private String getTopicPath(String topic) + { + return "/topics/" + topic; + } + + private void subscribeToTopics(JSONArray topics, String registrationToken) throws IOException { + if (topics != null) { + String topic = null; + for (int i=0; i jsonKeySet = new HashSet(); + Collections.addAll(jsonKeySet, TITLE,MESSAGE,COUNT,SOUND,IMAGE); + + Iterator it = extras.keySet().iterator(); + while (it.hasNext()) { + String key = it.next(); + Object value = extras.get(key); + + Log.d(LOG_TAG, "key = " + key); + + if (jsonKeySet.contains(key)) { + json.put(key, value); + } + else if (key.equals(COLDSTART)) { + additionalData.put(key, extras.getBoolean(COLDSTART)); + } + else if (key.equals(FOREGROUND)) { + additionalData.put(key, extras.getBoolean(FOREGROUND)); + } + else if ( value instanceof String ) { + String strValue = (String)value; + try { + // Try to figure out if the value is another JSON object + if (strValue.startsWith("{")) { + additionalData.put(key, new JSONObject(strValue)); + } + // Try to figure out if the value is another JSON array + else if (strValue.startsWith("[")) { + additionalData.put(key, new JSONArray(strValue)); + } + else { + additionalData.put(key, value); + } + } catch (Exception e) { + additionalData.put(key, value); + } + } + } // while + + json.put(ADDITIONAL_DATA, additionalData); + Log.v(LOG_TAG, "extrasToJSON: " + json.toString()); + + return json; + } + catch( JSONException e) { + Log.e(LOG_TAG, "extrasToJSON: JSON exception"); + } + return null; + } + + public static boolean isInForeground() { + return gForeground; + } + + public static boolean isActive() { + return gWebView != null; + } + + protected static void setRegistrationID(String token) { + registration_id = token; + } +} diff --git a/StoneIsland/platforms/android/src/com/adobe/phonegap/push/RegistrationIntentService.java b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/RegistrationIntentService.java new file mode 100644 index 00000000..b181e88e --- /dev/null +++ b/StoneIsland/platforms/android/src/com/adobe/phonegap/push/RegistrationIntentService.java @@ -0,0 +1,38 @@ +package com.adobe.phonegap.push; + +import android.content.Context; + +import android.app.IntentService; +import android.content.Intent; +import android.content.SharedPreferences; +import android.util.Log; + +import com.google.android.gms.gcm.GoogleCloudMessaging; +import com.google.android.gms.iid.InstanceID; + +import java.io.IOException; + +public class RegistrationIntentService extends IntentService implements PushConstants { + public static final String LOG_TAG = "PushPlugin_RegistrationIntentService"; + + public RegistrationIntentService() { + super(LOG_TAG); + } + + @Override + protected void onHandleIntent(Intent intent) { + SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); + + try { + InstanceID instanceID = InstanceID.getInstance(this); + String senderID = sharedPreferences.getString(SENDER_ID, ""); + String token = instanceID.getToken(senderID, + GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); + PushPlugin.setRegistrationID(token); + Log.i(LOG_TAG, "new GCM Registration Token: " + token); + + } catch (Exception e) { + Log.d(LOG_TAG, "Failed to complete token refresh", e); + } + } +} diff --git a/StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/CordovaLib.xcscheme b/StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/CordovaLib.xcscheme deleted file mode 100644 index c01d78b7..00000000 --- a/StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/CordovaLib.xcscheme +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/xcschememanagement.plist b/StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 283503be..00000000 --- a/StoneIsland/platforms/ios/CordovaLib/CordovaLib.xcodeproj/xcuserdata/julie.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - CordovaLib.xcscheme - - orderHint - 1 - - - SuppressBuildableAutocreation - - D2AAC07D0554694100DB518D - - primary - - - - - diff --git a/StoneIsland/platforms/ios/Podfile b/StoneIsland/platforms/ios/Podfile new file mode 100644 index 00000000..65988dd6 --- /dev/null +++ b/StoneIsland/platforms/ios/Podfile @@ -0,0 +1,7 @@ +# DO NOT MODIFY -- auto-generated by Apache Cordova +platform :ios, '8.0' +target 'Stone Island' do + project 'Stone Island.xcodeproj' + pod 'GoogleCloudMessaging', '~> 1.2.0' + pod 'GGLInstanceID', '~> 1.2.1' +end diff --git a/StoneIsland/platforms/ios/Podfile.lock b/StoneIsland/platforms/ios/Podfile.lock new file mode 100644 index 00000000..0fe15b8a --- /dev/null +++ b/StoneIsland/platforms/ios/Podfile.lock @@ -0,0 +1,30 @@ +PODS: + - GGLInstanceID (1.2.1) + - GoogleCloudMessaging (1.2.0): + - GoogleInterchangeUtilities (~> 1.0) + - GoogleIPhoneUtilities (~> 1.0) + - GoogleSymbolUtilities (~> 1.0) + - GoogleInterchangeUtilities (1.2.2): + - GoogleSymbolUtilities (~> 1.1) + - GoogleIPhoneUtilities (1.2.1): + - GoogleSymbolUtilities (~> 1.0) + - GoogleUtilities (~> 1.0) + - GoogleSymbolUtilities (1.1.2) + - GoogleUtilities (1.3.2): + - GoogleSymbolUtilities (~> 1.1) + +DEPENDENCIES: + - GGLInstanceID (~> 1.2.1) + - GoogleCloudMessaging (~> 1.2.0) + +SPEC CHECKSUMS: + GGLInstanceID: 4a317044f744281b82cd03015f379899f277cad3 + GoogleCloudMessaging: f37ea14dd0f41d4d889c10b5559dd35bbfd9ac26 + GoogleInterchangeUtilities: d5bc4d88d5b661ab72f9d70c58d02ca8c27ad1f7 + GoogleIPhoneUtilities: 63f25e93a3ddcb66884d182aab3a660d98f1479b + GoogleSymbolUtilities: 631ee17048aa5e9ab133470d768ea997a5ef9b96 + GoogleUtilities: 8bbc733218aad26306f9d4a253823986110e3358 + +PODFILE CHECKSUM: 49a15453d072b09c3f930a9bd96e706663ee516a + +COCOAPODS: 1.2.0 diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/CHANGELOG.md b/StoneIsland/platforms/ios/Pods/GGLInstanceID/CHANGELOG.md new file mode 100644 index 00000000..755828e3 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GGLInstanceID/CHANGELOG.md @@ -0,0 +1,28 @@ +# 2016-02-25 -- v1.2.1 +- Fix incorrect caching during library updates. + +# 2016-02-17 -- v1.2.0 +- Add Bitcode markers. + +# 2016-01-25 -- v1.1.7 +- Fix bug in InstanceID generation + +# 2016-01-25 -- v1.1.6 +- Greatly reduce IID library size. +- Bug fixes. + +# 2015-12-08 -- v1.1.4 +- Bug fixes. +- Fix dSYM warnings. + +# 2015-11-09 -- v1.1.3 +- Bug fixes. + +# 2015-10-28 -- v1.1.2 +- Bug fixes. + +# 2015-10-8 -- v1.1.1 + +- Resets InstanceID tokens on app delete and reinstall. +- Adds better error reporting. +- Bug fixes. diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceID.h b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceID.h new file mode 100644 index 00000000..e3fd3c64 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceID.h @@ -0,0 +1,273 @@ +#import + +@class GGLInstanceIDConfig; + +/** + * @memberof GGLInstanceID + * + * The key for APNS token to be included in the options dictionary when + * registering for GCM (Google Cloud Messaging). The value should be a + * NSData object that represents the APNS token for the app. This + * key is required to get a GCM token. + */ +FOUNDATION_EXPORT NSString *const kGGLInstanceIDRegisterAPNSOption; + +/** + * @memberof GGLInstanceID + * + * The key to specify if the APNS token type is sandbox or production. Set + * to YES if the app was built with Sandbox certificate else NO for production. + * At any point of time InstanceID library will support only one type of token. + */ +FOUNDATION_EXPORT NSString *const kGGLInstanceIDAPNSServerTypeSandboxOption; + +/** + * @memberof GGLInstanceID + * + * The scope to be used when fetching/deleting a token for + * GCM (Google Cloud Messaging). + */ +FOUNDATION_EXPORT NSString *const kGGLInstanceIDScopeGCM; + +/** + * @related GGLInstanceID + * + * The completion handler invoked when the InstanceID token returns. If + * the call fails we return the appropriate `error code` as described below. + * + * @param token The valid token as returned by InstanceID backend. + * + * @param error The error describing why generating a new token + * failed. See the error codes below for a more detailed + * description. + */ +typedef void(^GGLInstanceIDTokenHandler)(NSString *token, NSError *error); + + +/** + * @related GGLInstanceID + * + * The completion handler invoked when the InstanceID `deleteToken` returns. If + * the call fails we return the appropriate `error code` as described below + * + * @param error The error describing why deleting the token failed. + * See the error codes below for a more detailed description. + */ +typedef void(^GGLInstanceIDDeleteTokenHandler)(NSError *error); + +/** + * @related GGLInstanceID + * + * The completion handler invoked when the app identity is created. If the + * identity wasn't created for some reason we return the appropriate error code. + * + * @param identity A valid identity for the app instance, nil if there was an error + * while creating an identity. + * @param error The error if fetching the identity fails else nil. + */ +typedef void(^GGLInstanceIDHandler)(NSString *identity, NSError *error); + +/** + * @related GGLInstanceID + * + * The completion handler invoked when the app identity and all the tokens associated + * with it are deleted. Returns a valid error object in case of failure else nil. + * + * @param error The error if deleting the identity and all the tokens associated with + * it fails else nil. + */ +typedef void(^GGLInstanceIDDeleteHandler)(NSError *error); + +/** + * @enum GGLInstanceIDOperationErrorCode + * Description of error codes + */ +typedef NS_ENUM(NSUInteger, GGLInstanceIDOperationErrorCode) { + // Http related errors. + + /// InvalidRequest -- Some parameters of the request were invalid. + kGGLInstanceIDOperationErrorCodeInvalidRequest = 0, + + /// Auth Error -- GCM couldn't validate request from this client. + kGGLInstanceIDOperationErrorCodeAuthentication = 1, + + /// NoAccess -- InstanceID service cannot be accessed. + kGGLInstanceIDOperationErrorCodeNoAccess = 2, + + /// Timeout -- Request to InstanceID backend timed out. + kGGLInstanceIDOperationErrorCodeTimeout = 3, + + + /// Network -- No network available to reach the servers. + kGGLInstanceIDOperationErrorCodeNetwork = 4, + + /// OperationInProgress -- Another similar operation in progress, + /// bailing this one. + kGGLInstanceIDOperationErrorCodeOperationInProgress = 5, + + /// Unknown error. + kGGLInstanceIDOperationErrorCodeUnknown = 7, + + // InstanceID specific errors + + /* + * Generic errors. + */ + + // Device seems to be missing a valid deviceID. Cannot + // authenticate device requests. + kGGLInstanceIDOperationErrorCodeMissingDeviceID = 501, + + /** + * Token specific errors. + */ + + /// GCM token request is missing APNS token. + kGGLInstanceIDOperationErrorCodeMissingAPNSToken = 1001, + + /// GCM token request is missing server type. + kGGLInstanceIDOperationErrorCodeMissingAPNSServerType = 1002, + + /// Token request has invalid authorizedEntity. + kGGLInstanceIDOperationErrorCodeInvalidAuthorizedEntity = 1003, + + /// Token request has invalid scope. + kGGLInstanceIDOperationErrorCodeInvalidScope = 1004, + + /// Should call `startWithConfig:` before requesting token. + kGGLInstanceIDOperationErrorCodeInvalidStart = 1005, + + /// KeyPair access error. + kGGLInstanceIDOperationErrorCodeInvalidKeyPair = 1006, + + /** + * Identity specific errors. + */ + + /// Missing KeyPair. + kGGLInstanceIDOperationErrorCodeMissingKeyPair = 2001, +}; + +/** + * Instance ID provides a unique identifier for each app instance and a mechanism + * to authenticate and authorize actions (for example, sending a GCM message). + * + * Instance ID is long lived but, may be reset if the device is not used for + * a long time or the Instance ID service detects a problem. + * If Instance ID is reset, the app will be notified with a callback to + * [GGLInstanceIDDelegate onTokenRefresh] + * + * If the Instance ID has become invalid, the app can request a new one and + * send it to the app server. + * To prove ownership of Instance ID and to allow servers to access data or + * services associated with the app, call + * `[GGLInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. + */ +@interface GGLInstanceID : NSObject + +/** + * GGLInstanceID. + * + * @return A shared instance of GGLInstanceID. + */ ++ (instancetype)sharedInstance; + +/** + * Start `GGLInstanceID` with the specified config. + * + * @see GGLInstanceIDConfig + * + * @param config The `GGLInstanceIDConfig` used to build the service. + */ +- (void)startWithConfig:(GGLInstanceIDConfig *)config; + +/** + * Stop any network requests started by the client and release any handlers + * associated with it. + */ +- (void)stopAllRequests; + +#pragma mark - Tokens + +/** + * Returns a token that authorizes an Entity (example: cloud service) to perform + * an action on behalf of the application identified by Instance ID. + * + * This is similar to an OAuth2 token except, it applies to the + * application instance instead of a user. + * + * This is an asynchronous call. If the token fetching fails for some reason + * we invoke the completion callback with nil `token` and the appropriate + * error. + * + * Note, you can only have one `token` or `deleteToken` call for a given + * authorizedEntity and scope at any point of time. Making another such call with the + * same authorizedEntity and scope before the last one finishes will result in an + * error with code `OperationInProgress`. + * + * @see GGLInstanceID deleteTokenWithAuthorizedEntity:scope:handler: + * + * @param authorizedEntity Entity authorized by the token. + * @param scope Action authorized for authorizedEntity. + * @param options The extra options to be sent with your token request. The + * value for the `apns_token` should be the NSData object + * passed to UIApplication's + * `didRegisterForRemoteNotificationsWithDeviceToken` method. + * All other keys and values in the options dict need to be + * instances of NSString or else they will be discarded. Bundle + * keys starting with 'GCM.' and 'GOOGLE.' are reserved. + * @param handler The callback handler which is invoked when the token is + * successfully fetched. In case of success a valid `token` and + * `nil` error are returned. In case of any error the `token` + * is nil and a valid `error` is returned. The valid error + * codes have been documented above. + */ +- (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(NSDictionary *)options + handler:(GGLInstanceIDTokenHandler)handler; + +/** + * Revokes access to a scope (action) for an entity previously + * authorized by `[GGLInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. + * + * This is an asynchronous call. Call this on the main thread since InstanceID lib + * is not thread safe. In case token deletion fails for some reason we invoke the + * `handler` callback passed in with the appropriate error code. + * + * Note, you can only have one `token` or `deleteToken` call for a given + * authorizedEntity and scope at a point of time. Making another such call with the + * same authorizedEntity and scope before the last one finishes will result in an error + * with code `OperationInProgress`. + * + * @param authorizedEntity Entity that must no longer have access. + * @param scope Action that entity is no longer authorized to perform. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of error an appropriate error object is returned + * else error is nil. + */ +- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + handler:(GGLInstanceIDDeleteTokenHandler)handler; + +#pragma mark - Identity + +/** + * Asynchronously fetch a stable identifier that uniquely identifies the app + * instance. If the identifier has been revoked or has expired, this method will + * return a new identifier. + * + * + * @param handler The handler to invoke once the identifier has been fetched. + * In case of error an appropriate error object is returned else + * a valid identifier is returned and a valid identifier for the + * application instance. + */ +- (void)getIDWithHandler:(GGLInstanceIDHandler)handler; + +/** + * Resets Instance ID and revokes all tokens. + */ +- (void)deleteIDWithHandler:(GGLInstanceIDDeleteHandler)handler; + +@end diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDConfig.h b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDConfig.h new file mode 100644 index 00000000..da885569 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDConfig.h @@ -0,0 +1,32 @@ +@protocol GGLInstanceIDDelegate; + +typedef NS_ENUM(int8_t, GGLInstanceIDLogLevel) { + kGGLInstanceIDLogLevelDebug, + kGGLInstanceIDLogLevelInfo, + kGGLInstanceIDLogLevelError, + kGGLInstanceIDLogLevelAssert, +}; + +/** + * The config used to configure different options in GGLInstanceID library. + */ +@interface GGLInstanceIDConfig : NSObject + +/** + * Set the GGLInstanceIDDelegate to receive callbacks. + * + * @see GGLInstanceIDDelegate + */ +@property(nonatomic, readwrite, weak) id delegate; + +// the log level for the GGLInstanceID library. +@property(nonatomic, readwrite, assign) GGLInstanceIDLogLevel logLevel; + +/** + * Initialize a default config with logLevel set to `kGGLInstanceIDLogLevelError`. + * + * @return A default config for GGLInstanceID. + */ ++ (instancetype)defaultConfig; + +@end diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDDelegate.h b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDDelegate.h new file mode 100644 index 00000000..dc706a2d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDDelegate.h @@ -0,0 +1,13 @@ +@protocol GGLInstanceIDDelegate + +/** + * Called when the system determines that tokens need to be refreshed. + * This method is also called if Instance ID has been reset in which + * case, tokens and `GcmPubSub` subscriptions also need to be refreshed. + * + * Instance ID service will throttle the refresh event across all devices + * to control the rate of token updates on application servers. + */ +- (void)onTokenRefresh; + +@end diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDHeaders.h b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDHeaders.h new file mode 100644 index 00000000..2aa4eddd --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Headers/Public/GGLInstanceIDHeaders.h @@ -0,0 +1,4 @@ +#import "GGLInstanceID.h" +#import "GGLInstanceIDConfig.h" +#import "GGLInstanceIDDelegate.h" + diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/Libraries/libGGLInstanceIDLib.a b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Libraries/libGGLInstanceIDLib.a new file mode 100755 index 00000000..d5e6b3a4 Binary files /dev/null and b/StoneIsland/platforms/ios/Pods/GGLInstanceID/Libraries/libGGLInstanceIDLib.a differ diff --git a/StoneIsland/platforms/ios/Pods/GGLInstanceID/README.md b/StoneIsland/platforms/ios/Pods/GGLInstanceID/README.md new file mode 100644 index 00000000..e6fb90db --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GGLInstanceID/README.md @@ -0,0 +1,10 @@ +# InstanceID SDK for iOS + +Instance ID provides a unique ID per instance of your apps and also provides a +mechanism to authenticate and authorize actions, like sending messages via +Google Cloud Messaging (GCM). + + +Please visit [our developer +site](https://developers.google.com/instance-id/) for integration instructions, +documentation, support information, and terms of service. diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/CHANGELOG.md b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/CHANGELOG.md new file mode 100644 index 00000000..9f24a7a5 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/CHANGELOG.md @@ -0,0 +1,32 @@ +# 2016-01-25 -- v1.2.0 + +Add Bitcode markers. + +# 2016-01-25 -- v1.1.3 + +- Bug fixes. + +# 2015-12-08 -- v1.1.2 + +- Bug fixes. +- Fix dSYM warnings. + +# 2015-10-21 -- v1.1.1 + +- Adds analytics support. +- Bug fixes. + +# 2015-10-8 -- v1.1.0 + +- `[GCMService appDidReceiveMessage:]` now returns `BOOL` to signify if the + message has already been received before. +- Fixes deleting old GCM registrations and topic subscriptions on app deletion + and reinstall. +- Removes usage of clang modules for ObjC++ support. +- `GCMReceiverDelegate` protocol methods are now **optional**. +- Add `useNewRemoteNotificationCallback` property in `GCMConfig` to use new + iOS8+ notification callback i.e. + `application:didReceiveRemoteNotification:fetchCompletionHandler:`. +- Add better error reporting. +- Fix some compiler warnings. +- Bug fixes. diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMConfig.h b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMConfig.h new file mode 100644 index 00000000..4e65fb87 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMConfig.h @@ -0,0 +1,49 @@ +@protocol GCMReceiverDelegate; + +typedef NS_ENUM(int8_t, GCMLogLevel) { + kGCMLogLevelDebug, + kGCMLogLevelInfo, + kGCMLogLevelError, + kGCMLogLevelAssert, +}; + +/** + * Config used to set different options in Google Cloud Messaging. + */ +@interface GCMConfig : NSObject + +/** + * Set the `GCMReceiverDelegate` to receive callbacks on upstream messages. + * + * @see GCMReceiverDelegate + */ +@property(nonatomic, readwrite, weak) id receiverDelegate; + +/** + * The log level for the GCM library. Valid values are `kGCMLogLevelDebug`, + * `kGCMLogLevelInfo`, `kGCMLogLevelError`, and `kGCMLogLevelAssert`. + */ +@property(nonatomic, readwrite, assign) GCMLogLevel logLevel; + +/** + * Specify which remote notification callback to invoke when a GCM message is + * received. + * + * If set to "YES" GCM uses the new remote notification callback i.e. + * application:didReceiveRemoteNotification:fetchCompletionHandler:. + * If set to "NO" GCM invokes application:didReceiveRemoteNotification: callback. + * + * Defaults to "NO". + */ +@property(nonatomic, readwrite, assign) BOOL useNewRemoteNotificationCallback; + +/** + * Get default configuration for GCM. The default config has logLevel set to + * `kGCMLogLevelError` and `receiverDelegate` is set to nil. + * + * @return GCMConfig sharedInstance. + */ ++ (instancetype)defaultConfig; + +@end + diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMPubSub.h b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMPubSub.h new file mode 100644 index 00000000..37e0a6b3 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMPubSub.h @@ -0,0 +1,82 @@ +/** + * @related GCMPubSub + * + * The completion handler invoked when the GCM subscribe/unsubscribe returns. + * If the call fails we return the approprirate `error code` as documented in + * `GCMService`. + * + * @param error The error describing subscribe failure else nil. + */ +typedef void(^GCMPubSubCompletion)(NSError *error); + +/** + * GcmPubSub provides a publish-subscribe model for sending GCM topic messages. + * + * An app can subscribe to different topics defined by the + * developer. The app server can then send messages to the subscribed devices + * without having to maintain topic-subscribers mapping. Topics do not + * need to be explicitly created before subscribing or publishing—they + * are automatically created when publishing or subscribing. + * + * Messages published to the topic will be received as regular GCM messages + * with `"from"` set to `"/topics/myTopic"`. + * + * Only topic names that match the pattern `"/topics/[a-zA-Z0-9-_.~%]{1,900}"` + * are allowed for subscribing and publishing. + */ +@interface GCMPubSub : NSObject + +/** + * Returns an instance of GCMPubSub. Note you need to call + * `GCMService startWithConfig` to start using GCM. + * + * @return A shared instance of GCMPubSub. + */ ++ (instancetype)sharedInstance; + +/** + * Subscribes an app instance to a topic, enabling it to receive messages + * sent to that topic. + * + * This is an asynchronous call. If subscription fails, GCM + * invokes the completion callback with the appropriate error. + * + * Call this function from the main thread. GCM is not thread safe. + * + * @see GCMPubSub unsubscribeWithToken:topic:handler: + * + * @param token The registration token as received from the InstanceID + * library for a given `authorizedEntity` and "gcm" scope. + * @param topic The topic to subscribe to. Should be of the form + * `"/topics/"`. + * @param handler The callback handler invoked when the subscribe call + * ends. In case of success, a nil error is returned. Otherwise, + * an appropriate error object is returned. + */ +- (void)subscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + handler:(GCMPubSubCompletion)handler; + + +/** + * Unsubscribes an app instance from a topic, stopping it from receiving + * any further messages sent to that topic. + * + * This is an asynchronous call. If the attempt to unsubscribe fails, + * we invoke the `completion` callback passed in with an appropriate error. + * + * Call this function from the main thread. + * + * @param token The token used to subscribe to this topic. + * @param topic The topic to unsubscribe from. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)unsubscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + handler:(GCMPubSubCompletion)handler; + +@end diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMReceiverDelegate.h b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMReceiverDelegate.h new file mode 100644 index 00000000..45433aed --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMReceiverDelegate.h @@ -0,0 +1,35 @@ +/** + * Delegate for receiving status of upstream messages sent via Google Cloud Messaging. + */ +@protocol GCMReceiverDelegate + +@optional +/** + * The callback is invoked once GCM processes the message. If processing fails, the + * callback is invoked with a valid error object representing the error. + * Otherwise, the message is ready to be sent. + * + * @param messageID The messageID for the message that failed to be sent upstream. + * @param error The error describing why the send operation failed. + */ +- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error; + +/** + * This callback is invoked if GCM successfully sent the message upstream + * and the message was successfully received. + * + * @param messageID The messageID for the message sent. + */ +- (void)didSendDataMessageWithID:(NSString *)messageID; + +/** + * Called when the GCM server deletes pending messages due to exceeded + * storage limits. This may occur, for example, when the device cannot be + * reached for an extended period of time. + * + * It is recommended to retrieve any missing messages directly from the + * app server. + */ +- (void)didDeleteMessagesOnServer; + +@end diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMService.h b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMService.h new file mode 100644 index 00000000..d903e5a3 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GCMService.h @@ -0,0 +1,243 @@ +@class GCMConfig; + +/** + * The completion handler invoked once the data connection with GCM is + * established. The data connection is used to send a continous stream of + * data and all the GCM data notifications arrive through this connection. + * Once the connection is established we invoke the callback with `nil` error. + * Correspondingly if we get an error while trying to establish a connection + * we invoke the handler with an appropriate error object and do an + * exponential backoff to try and connect again unless successful. + + * + * @param error The error object if any describing why the data connection + * to GCM failed. + */ +typedef void(^GCMServiceConnectCompletion)(NSError *error); + + +/** + * @enum GCMServiceErrorCode + * Description of error codes + */ +typedef NS_ENUM(NSUInteger, GCMServiceErrorCode) { + /** + * HTTP errors. + */ + + // InvalidRequest -- Some parameters of the request were invalid. + kGCMServiceErrorCodeInvalidRequest = 0, + + // Auth Error -- GCM couldn't validate request from this client. + kGCMServiceErrorCodeAuthentication = 1, + + // NoAccess -- InstanceID service cannot be accessed. + kGCMServiceErrorCodeNoAccess = 2, + + // Timeout -- Request to InstanceID backend timed out. + kGCMServiceErrorCodeTimeout = 3, + + // Network -- No network available to reach the servers. + kGCMServiceErrorCodeNetwork = 4, + + // OperationInProgress -- Another similar operation in progress, + // bailing this one. + kGCMServiceErrorCodeOperationInProgress = 5, + + // Unknown error. + kGCMServiceErrorCodeUnknown = 7, + + /** + * Generic errors. + */ + + // Device seems to be missing a valid deviceID. Cannot authenticate + // device requests. + kGCMServiceErrorMissingDeviceID = 501, + + /** + * Upstream Send errors + */ + + // Upstream send not available (e.g. network issues) + kGCMServiceErrorCodeUpstreamServiceNotAvailable = 1001, + + // Invalid send parameters. + kGCMServiceErrorCodeInvalidParameters = 1002, + + // Invalid missing to. + kGCMServiceErrorCodeMissingTo = 1003, + + // GCM could not cache the message for sending. + kGCMServiceErrorSave = 1004, + + // Message size exceeded (size > 4KB). + kGCMServiceErrorSizeExceeded = 1005, + + /** + * GCM Connect errors. + */ + + // GCM already connected with the client. + kGCMServiceErrorCodeAlreadyConnected = 2001, + + /** + * PubSub errors. + */ + + // Topic already subscribed to. + kGCMServiceErrorCodePubSubAlreadySubscribed = 3001, + + // Topic already unsubscribed from. + kGCMServiceErrorCodePubSubAlreadyUnsubscribed = 3002, + + // Invalid topic name, does not match the topic regex "/topics/[a-zA-Z0-9-_.~%]+" + kGCMServiceErrorCodePubSubInvalidTopic = 3003, +}; + +/** + * GoogleCloudMessaging (GCM) enables apps to communicate with their app servers + * using simple messages. + * + * To send or receive messages, the app must get a + * registration token from GGLInstanceID, which authorizes an + * app server to send messages to an app instance. Pass your sender ID and + * `kGGLInstanceIDScopeGCM` as parameters to the method. + * + * A sender ID is a project number created when you configure your API project. + * It is labeled "Project Number" in the Google Developers Console. + * + * In order to receive GCM messages, declare application:didReceiveRemoteNotification: + * + * Client apps can send upstream messages back to the app server using the XMPP-based + * Cloud Connection Server, + * + */ +@interface GCMService : NSObject + +/** + * GCMService + * + * @return A shared instance of GCMService. + */ ++ (instancetype)sharedInstance; + +/** + * Start the `GCMService` with config. This starts the `GCMService` and + * allocates the required resources. + * + * @see GCMConfig + * + * @param config The `GCMConfig` used to build the service. + */ +- (void)startWithConfig:(GCMConfig *)config; + +/** + * Teardown the GCM connection and free all the resources owned by GCM. + * + * Call this when you don't need the GCM connection or to cancel all + * subscribe/unsubscribe requests. If GCM connection is alive before + * calling this, it would implicitly disconnect the connection. + * + * Calling `disconect` before invoking this method is useful but not required. + * Once you call this you won't be able to use `GCMService` for this session + * of your app. Therefore call this only when the app is going to exit. + * In case of background you should rather use `disconnect` and then + * if the app comes to the foreground again you can call `connect` again to + * establish a new connection. + */ +- (void)teardown; + +#pragma mark - Messages + +/** + * Call this to let GCM know that the app received a downstream message. Used + * to detect duplicate messages and to track message delivery for messages + * with different routes. + * + * @param message The downstream message received by the app. + * + * @return For APNs messages this always returns FALSE. For other messages, + * this returns FALSE for new, non-duplicated messages. + */ +- (BOOL)appDidReceiveMessage:(NSDictionary *)message; + + #pragma mark - Connect + +/** + * Create a GCM data connection which will be used to send the data notifications + * send by your server. It will also be used to send ACKS and other messages based + * on the GCM ACKS and other messages based on the GCM protocol. + * + * Use the `disconnect` method to disconnect the connection. + * + * @see GCMService disconnect + * + * @param handler The handler to be invoked once the connection is established. + * If the connection fails we invoke the handler with an + * appropriate error code letting you know why it failed. At + * the same time, GCM performs exponential backoff to retry + * establishing a connection and invoke the handler when successful. + */ +- (void)connectWithHandler:(GCMServiceConnectCompletion)handler; + +/** + * Disconnect the current GCM data connection. This stops any attempts to + * connect to GCM. Calling this on an already disconnected client is a no-op. + * + * Call this before `teardown` when your app is going to the background. + * Since the GCM connection won't be allowed to live when in background it is + * prudent to close the connection. + * + * @see GCMService teardown + */ +- (void)disconnect; + +#pragma mark - Send + +/** + * Send an upstream ("device to cloud") message. + * + * The message will be queued if we don't have an active connection for the max + * interval. + * + * @param message Key/Value pairs to be sent. Values must be String, any other + * type will be ignored. + * @param to String identifying the receiver of the message. For GCM + * project IDs the value is `SENDER_ID@gcm.googleapis.com`. + * @param msgId A unique ID of the message. This is generated by the + * application. It must be unique for each message. This allows + * error callbacks and debugging. + */ +- (void)sendMessage:(NSDictionary *)message + to:(NSString *)to + withId:(NSString *)msgId; + +/** + * Send an upstream ("device to cloud") message. + * + * The message will be queued if we don't have an active connection for the max + * interval. You can only use the upstream feature if your GCM implementation + * uses the XMPP-based Cloud Connection Server. + * + * @param message Key/Value pairs to be sent. Values must be String, any + * other type will be ignored. + * @param to A string identifying the receiver of the message. For GCM + * project IDs the value is `SENDER_ID@gcm.googleapis.com`. + * @param ttl The Time to live for the message. In case we aren't able to + * send the message before the ttl expires we will send you a + * callback. If 0, we'll attempt to send immediately and return + * an error if we're not connected. Otherwise, the message will + * be queued.As for server-side messages, we don't return an error + * if the message has been dropped because of TTL; this can happen + * on the server side, and it would require extra communication. + * @param msgId The ID of the message. This is generated by the application. It + * must be unique for each message. It allows error callbacks and + * debugging, to uniquely identify each message. + */ +- (void)sendMessage:(NSDictionary *)message + to:(NSString *)to + timeToLive:(int64_t)ttl + withId:(NSString *)msgId; + +@end diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GoogleCloudMessaging.h b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GoogleCloudMessaging.h new file mode 100644 index 00000000..aab64fbe --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Headers/Public/GoogleCloudMessaging.h @@ -0,0 +1,5 @@ +#import "GCMConfig.h" +#import "GCMPubSub.h" +#import "GCMReceiverDelegate.h" +#import "GCMService.h" + diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Libraries/libGcmLib.a b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Libraries/libGcmLib.a new file mode 100755 index 00000000..a9356d23 Binary files /dev/null and b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/Libraries/libGcmLib.a differ diff --git a/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/README.md b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/README.md new file mode 100644 index 00000000..2c900de2 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/GoogleCloudMessaging/README.md @@ -0,0 +1,10 @@ +# Google Cloud Messaging SDK for iOS + +Google Cloud Messaging (GCM) is a free service that enables developers to send +messages between servers and client apps. This includes downstream messages +from servers to client apps, and upstream messages from client apps to servers. + + +Please visit [our developer +site](https://developers.google.com/cloud-messaging/ios/start) for integration +instructions, documentation, support information, and terms of service. diff --git a/StoneIsland/platforms/ios/Pods/GoogleIPhoneUtilities/Frameworks/GoogleIPhoneUtilities.framework/GoogleIPhoneUtilities b/StoneIsland/platforms/ios/Pods/GoogleIPhoneUtilities/Frameworks/GoogleIPhoneUtilities.framework/GoogleIPhoneUtilities new file mode 100644 index 00000000..7ab2cf26 Binary files /dev/null and b/StoneIsland/platforms/ios/Pods/GoogleIPhoneUtilities/Frameworks/GoogleIPhoneUtilities.framework/GoogleIPhoneUtilities differ diff --git a/StoneIsland/platforms/ios/Pods/GoogleInterchangeUtilities/Frameworks/frameworks/GoogleInterchangeUtilities.framework/GoogleInterchangeUtilities b/StoneIsland/platforms/ios/Pods/GoogleInterchangeUtilities/Frameworks/frameworks/GoogleInterchangeUtilities.framework/GoogleInterchangeUtilities new file mode 100755 index 00000000..de404247 Binary files /dev/null and b/StoneIsland/platforms/ios/Pods/GoogleInterchangeUtilities/Frameworks/frameworks/GoogleInterchangeUtilities.framework/GoogleInterchangeUtilities differ diff --git a/StoneIsland/platforms/ios/Pods/GoogleSymbolUtilities/Frameworks/frameworks/GoogleSymbolUtilities.framework/GoogleSymbolUtilities b/StoneIsland/platforms/ios/Pods/GoogleSymbolUtilities/Frameworks/frameworks/GoogleSymbolUtilities.framework/GoogleSymbolUtilities new file mode 100755 index 00000000..408a0026 Binary files /dev/null and b/StoneIsland/platforms/ios/Pods/GoogleSymbolUtilities/Frameworks/frameworks/GoogleSymbolUtilities.framework/GoogleSymbolUtilities differ diff --git a/StoneIsland/platforms/ios/Pods/GoogleUtilities/Frameworks/frameworks/GoogleUtilities.framework/GoogleUtilities b/StoneIsland/platforms/ios/Pods/GoogleUtilities/Frameworks/frameworks/GoogleUtilities.framework/GoogleUtilities new file mode 100755 index 00000000..0fd17b65 Binary files /dev/null and b/StoneIsland/platforms/ios/Pods/GoogleUtilities/Frameworks/frameworks/GoogleUtilities.framework/GoogleUtilities differ diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceID.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceID.h new file mode 120000 index 00000000..6a5ede6e --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceID.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceID.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDConfig.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDConfig.h new file mode 120000 index 00000000..95605988 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDConfig.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceIDConfig.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDDelegate.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDDelegate.h new file mode 120000 index 00000000..e7d44b8c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDDelegate.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceIDDelegate.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDHeaders.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDHeaders.h new file mode 120000 index 00000000..b1d72b29 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GGLInstanceID/GGLInstanceIDHeaders.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceIDHeaders.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMConfig.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMConfig.h new file mode 120000 index 00000000..b5187f24 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMConfig.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMConfig.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMPubSub.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMPubSub.h new file mode 120000 index 00000000..0072792c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMPubSub.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMPubSub.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMReceiverDelegate.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMReceiverDelegate.h new file mode 120000 index 00000000..e6e1be97 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMReceiverDelegate.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMReceiverDelegate.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMService.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMService.h new file mode 120000 index 00000000..256f388d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GCMService.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMService.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GoogleCloudMessaging.h b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GoogleCloudMessaging.h new file mode 120000 index 00000000..18678070 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Private/GoogleCloudMessaging/GoogleCloudMessaging.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GoogleCloudMessaging.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceID.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceID.h new file mode 120000 index 00000000..6a5ede6e --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceID.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceID.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDConfig.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDConfig.h new file mode 120000 index 00000000..95605988 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDConfig.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceIDConfig.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDDelegate.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDDelegate.h new file mode 120000 index 00000000..e7d44b8c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDDelegate.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceIDDelegate.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDHeaders.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDHeaders.h new file mode 120000 index 00000000..b1d72b29 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GGLInstanceID/GGLInstanceIDHeaders.h @@ -0,0 +1 @@ +../../../GGLInstanceID/Headers/Public/GGLInstanceIDHeaders.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMConfig.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMConfig.h new file mode 120000 index 00000000..b5187f24 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMConfig.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMConfig.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMPubSub.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMPubSub.h new file mode 120000 index 00000000..0072792c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMPubSub.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMPubSub.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMReceiverDelegate.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMReceiverDelegate.h new file mode 120000 index 00000000..e6e1be97 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMReceiverDelegate.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMReceiverDelegate.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMService.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMService.h new file mode 120000 index 00000000..256f388d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GCMService.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GCMService.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GoogleCloudMessaging.h b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GoogleCloudMessaging.h new file mode 120000 index 00000000..18678070 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Headers/Public/GoogleCloudMessaging/GoogleCloudMessaging.h @@ -0,0 +1 @@ +../../../GoogleCloudMessaging/Headers/Public/GoogleCloudMessaging.h \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/Manifest.lock b/StoneIsland/platforms/ios/Pods/Manifest.lock new file mode 100644 index 00000000..0fe15b8a --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Manifest.lock @@ -0,0 +1,30 @@ +PODS: + - GGLInstanceID (1.2.1) + - GoogleCloudMessaging (1.2.0): + - GoogleInterchangeUtilities (~> 1.0) + - GoogleIPhoneUtilities (~> 1.0) + - GoogleSymbolUtilities (~> 1.0) + - GoogleInterchangeUtilities (1.2.2): + - GoogleSymbolUtilities (~> 1.1) + - GoogleIPhoneUtilities (1.2.1): + - GoogleSymbolUtilities (~> 1.0) + - GoogleUtilities (~> 1.0) + - GoogleSymbolUtilities (1.1.2) + - GoogleUtilities (1.3.2): + - GoogleSymbolUtilities (~> 1.1) + +DEPENDENCIES: + - GGLInstanceID (~> 1.2.1) + - GoogleCloudMessaging (~> 1.2.0) + +SPEC CHECKSUMS: + GGLInstanceID: 4a317044f744281b82cd03015f379899f277cad3 + GoogleCloudMessaging: f37ea14dd0f41d4d889c10b5559dd35bbfd9ac26 + GoogleInterchangeUtilities: d5bc4d88d5b661ab72f9d70c58d02ca8c27ad1f7 + GoogleIPhoneUtilities: 63f25e93a3ddcb66884d182aab3a660d98f1479b + GoogleSymbolUtilities: 631ee17048aa5e9ab133470d768ea997a5ef9b96 + GoogleUtilities: 8bbc733218aad26306f9d4a253823986110e3358 + +PODFILE CHECKSUM: 49a15453d072b09c3f930a9bd96e706663ee516a + +COCOAPODS: 1.2.0 diff --git a/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/project.pbxproj b/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 00000000..c9b4f412 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,447 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 8B931F94A15CEC623D339DA3C38BE3A3 /* Pods-Stone Island-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E17C0998C78916667291BC7B0048B0 /* Pods-Stone Island-dummy.m */; }; + A236CF7DD81B48ADA6EC58CCD7C8704E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0C86D2D78080EDCEE85A13AA1692ACD6 /* Pods-Stone Island.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Stone Island.release.xcconfig"; sourceTree = ""; }; + 10B3D03939EC1F098DF4D390572E7A70 /* Pods-Stone Island-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Stone Island-acknowledgements.markdown"; sourceTree = ""; }; + 173B36DA9A5ED406088A50C1589B0B4E /* GGLInstanceID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GGLInstanceID.h; path = Headers/Public/GGLInstanceID.h; sourceTree = ""; }; + 2313F1DCFFF1A82931A5DF3F158D5DA3 /* Pods-Stone Island.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Stone Island.debug.xcconfig"; sourceTree = ""; }; + 36F75FFC47B4DBEB5982F58544A7B2FC /* GoogleInterchangeUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleInterchangeUtilities.framework; path = Frameworks/frameworks/GoogleInterchangeUtilities.framework; sourceTree = ""; }; + 474CBC9EAF59DE318EE6611AAE5D0291 /* GoogleIPhoneUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleIPhoneUtilities.framework; path = Frameworks/GoogleIPhoneUtilities.framework; sourceTree = ""; }; + 4A59C4528E6B71DFA7011DF095E0C8B8 /* GCMReceiverDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCMReceiverDelegate.h; path = Headers/Public/GCMReceiverDelegate.h; sourceTree = ""; }; + 5890B2B91852CF430B0772AD7C3B4C2B /* Pods-Stone Island-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Stone Island-frameworks.sh"; sourceTree = ""; }; + 6A055A93C3564E5CDA417C640324E176 /* GoogleUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleUtilities.framework; path = Frameworks/frameworks/GoogleUtilities.framework; sourceTree = ""; }; + 6A52371D28A634057B785F5B581084AF /* GoogleSymbolUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleSymbolUtilities.framework; path = Frameworks/frameworks/GoogleSymbolUtilities.framework; sourceTree = ""; }; + 8127A92CEFC4B6BC0D037BBDADA1B051 /* GGLInstanceIDConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GGLInstanceIDConfig.h; path = Headers/Public/GGLInstanceIDConfig.h; sourceTree = ""; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + A110B0A704D9AE1951A8F07D446042C1 /* Pods-Stone Island-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Stone Island-resources.sh"; sourceTree = ""; }; + B47CA48C3A76744553D639170A059DED /* Pods-Stone Island-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Stone Island-acknowledgements.plist"; sourceTree = ""; }; + BD469413B9D194472712F81C4C19217C /* GGLInstanceIDHeaders.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GGLInstanceIDHeaders.h; path = Headers/Public/GGLInstanceIDHeaders.h; sourceTree = ""; }; + BD5E36BF0B6CBFDEC0927984332B535A /* GCMService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCMService.h; path = Headers/Public/GCMService.h; sourceTree = ""; }; + CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + D6448B738D0F834A89872ACF4F33A1AA /* libGGLInstanceIDLib.a */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = archive.ar; name = libGGLInstanceIDLib.a; path = Libraries/libGGLInstanceIDLib.a; sourceTree = ""; }; + E04BE7A3CBD84DBAA76FC51758B7CED6 /* GCMConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCMConfig.h; path = Headers/Public/GCMConfig.h; sourceTree = ""; }; + E7C2BA0DA51EB36ED5DB61FE0CD57F36 /* libPods-Stone Island.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Stone Island.a"; path = "libPods-Stone Island.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + EA6ECB7498639194EA9C76AA5A5335AA /* GCMPubSub.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCMPubSub.h; path = Headers/Public/GCMPubSub.h; sourceTree = ""; }; + EE0A605C9B1A1EA6221D258D4E528AD7 /* GGLInstanceIDDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GGLInstanceIDDelegate.h; path = Headers/Public/GGLInstanceIDDelegate.h; sourceTree = ""; }; + EEFE0B43B6BEB77AB2B72163776B3431 /* libGcmLib.a */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = archive.ar; name = libGcmLib.a; path = Libraries/libGcmLib.a; sourceTree = ""; }; + F1E17C0998C78916667291BC7B0048B0 /* Pods-Stone Island-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Stone Island-dummy.m"; sourceTree = ""; }; + F3E864806D6F83145EA52D163BA1A423 /* GoogleCloudMessaging.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GoogleCloudMessaging.h; path = Headers/Public/GoogleCloudMessaging.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4393326EAD1C0D0F9AECF9FC78E6DAD8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A236CF7DD81B48ADA6EC58CCD7C8704E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 121A86CC4AAF79B70266B959308D3CA7 /* Pods */ = { + isa = PBXGroup; + children = ( + 3758E30E87F41188A58D53252E8DC67F /* GGLInstanceID */, + F52CA7A5CDCB3F8FEAEAD0AD400F9313 /* GoogleCloudMessaging */, + 5E3943FF863A867D4D99F3E17093D9D7 /* GoogleInterchangeUtilities */, + 9DCD9E1660319E9727375653D3EBBA13 /* GoogleIPhoneUtilities */, + BBD88AD6F1DF792566DB101E1D7A50AB /* GoogleSymbolUtilities */, + 736A89F858E6E6D5DDEC5BBDA2E1C51B /* GoogleUtilities */, + ); + name = Pods; + sourceTree = ""; + }; + 2FD026630DDFF013082B2945DB20B798 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 474CBC9EAF59DE318EE6611AAE5D0291 /* GoogleIPhoneUtilities.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 3758E30E87F41188A58D53252E8DC67F /* GGLInstanceID */ = { + isa = PBXGroup; + children = ( + 173B36DA9A5ED406088A50C1589B0B4E /* GGLInstanceID.h */, + 8127A92CEFC4B6BC0D037BBDADA1B051 /* GGLInstanceIDConfig.h */, + EE0A605C9B1A1EA6221D258D4E528AD7 /* GGLInstanceIDDelegate.h */, + BD469413B9D194472712F81C4C19217C /* GGLInstanceIDHeaders.h */, + FEEE277DB90FD41AA0B77E6258108DFB /* Frameworks */, + ); + name = GGLInstanceID; + path = GGLInstanceID; + sourceTree = ""; + }; + 5E3943FF863A867D4D99F3E17093D9D7 /* GoogleInterchangeUtilities */ = { + isa = PBXGroup; + children = ( + CAFDBEDBC9861619C5BC0B5A525B32E5 /* Frameworks */, + ); + name = GoogleInterchangeUtilities; + path = GoogleInterchangeUtilities; + sourceTree = ""; + }; + 736A89F858E6E6D5DDEC5BBDA2E1C51B /* GoogleUtilities */ = { + isa = PBXGroup; + children = ( + E8A2173F40F6AA192DD2A76C1203C416 /* Frameworks */, + ); + name = GoogleUtilities; + path = GoogleUtilities; + sourceTree = ""; + }; + 7531C8F8DE19F1AA3C8A7AC97A91DC29 /* iOS */ = { + isa = PBXGroup; + children = ( + CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, + 121A86CC4AAF79B70266B959308D3CA7 /* Pods */, + EA7DD587FC2EAD1ECAA75B2850B62903 /* Products */, + 838A3B364ADE24D6443C58DDBACFF0C2 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 838A3B364ADE24D6443C58DDBACFF0C2 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + BA3FA15D22651C0425DF92E8A2A4517F /* Pods-Stone Island */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 9DCD9E1660319E9727375653D3EBBA13 /* GoogleIPhoneUtilities */ = { + isa = PBXGroup; + children = ( + 2FD026630DDFF013082B2945DB20B798 /* Frameworks */, + ); + name = GoogleIPhoneUtilities; + path = GoogleIPhoneUtilities; + sourceTree = ""; + }; + A770D2EDC6FA25DCD787792DF757FA50 /* Frameworks */ = { + isa = PBXGroup; + children = ( + EEFE0B43B6BEB77AB2B72163776B3431 /* libGcmLib.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + B9E958B53590711D484747E648D2BBAF /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6A52371D28A634057B785F5B581084AF /* GoogleSymbolUtilities.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + BA3FA15D22651C0425DF92E8A2A4517F /* Pods-Stone Island */ = { + isa = PBXGroup; + children = ( + 10B3D03939EC1F098DF4D390572E7A70 /* Pods-Stone Island-acknowledgements.markdown */, + B47CA48C3A76744553D639170A059DED /* Pods-Stone Island-acknowledgements.plist */, + F1E17C0998C78916667291BC7B0048B0 /* Pods-Stone Island-dummy.m */, + 5890B2B91852CF430B0772AD7C3B4C2B /* Pods-Stone Island-frameworks.sh */, + A110B0A704D9AE1951A8F07D446042C1 /* Pods-Stone Island-resources.sh */, + 2313F1DCFFF1A82931A5DF3F158D5DA3 /* Pods-Stone Island.debug.xcconfig */, + 0C86D2D78080EDCEE85A13AA1692ACD6 /* Pods-Stone Island.release.xcconfig */, + ); + name = "Pods-Stone Island"; + path = "Target Support Files/Pods-Stone Island"; + sourceTree = ""; + }; + BBD88AD6F1DF792566DB101E1D7A50AB /* GoogleSymbolUtilities */ = { + isa = PBXGroup; + children = ( + B9E958B53590711D484747E648D2BBAF /* Frameworks */, + ); + name = GoogleSymbolUtilities; + path = GoogleSymbolUtilities; + sourceTree = ""; + }; + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7531C8F8DE19F1AA3C8A7AC97A91DC29 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + CAFDBEDBC9861619C5BC0B5A525B32E5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 36F75FFC47B4DBEB5982F58544A7B2FC /* GoogleInterchangeUtilities.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + E8A2173F40F6AA192DD2A76C1203C416 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6A055A93C3564E5CDA417C640324E176 /* GoogleUtilities.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + EA7DD587FC2EAD1ECAA75B2850B62903 /* Products */ = { + isa = PBXGroup; + children = ( + E7C2BA0DA51EB36ED5DB61FE0CD57F36 /* libPods-Stone Island.a */, + ); + name = Products; + sourceTree = ""; + }; + F52CA7A5CDCB3F8FEAEAD0AD400F9313 /* GoogleCloudMessaging */ = { + isa = PBXGroup; + children = ( + E04BE7A3CBD84DBAA76FC51758B7CED6 /* GCMConfig.h */, + EA6ECB7498639194EA9C76AA5A5335AA /* GCMPubSub.h */, + 4A59C4528E6B71DFA7011DF095E0C8B8 /* GCMReceiverDelegate.h */, + BD5E36BF0B6CBFDEC0927984332B535A /* GCMService.h */, + F3E864806D6F83145EA52D163BA1A423 /* GoogleCloudMessaging.h */, + A770D2EDC6FA25DCD787792DF757FA50 /* Frameworks */, + ); + name = GoogleCloudMessaging; + path = GoogleCloudMessaging; + sourceTree = ""; + }; + FEEE277DB90FD41AA0B77E6258108DFB /* Frameworks */ = { + isa = PBXGroup; + children = ( + D6448B738D0F834A89872ACF4F33A1AA /* libGGLInstanceIDLib.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 270B46424A6E550E1583E7A97AAD265A /* Pods-Stone Island */ = { + isa = PBXNativeTarget; + buildConfigurationList = BD1D1A57A9121FF061B86F474E27AA5E /* Build configuration list for PBXNativeTarget "Pods-Stone Island" */; + buildPhases = ( + 04C4D2FB97E65104032C84BA808D29B0 /* Sources */, + 4393326EAD1C0D0F9AECF9FC78E6DAD8 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-Stone Island"; + productName = "Pods-Stone Island"; + productReference = E7C2BA0DA51EB36ED5DB61FE0CD57F36 /* libPods-Stone Island.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0730; + LastUpgradeCheck = 0700; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = EA7DD587FC2EAD1ECAA75B2850B62903 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 270B46424A6E550E1583E7A97AAD265A /* Pods-Stone Island */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 04C4D2FB97E65104032C84BA808D29B0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B931F94A15CEC623D339DA3C38BE3A3 /* Pods-Stone Island-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 015A368F878AC3E2CEAE21DDE8026304 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 44CDBB6D11DE06DB64D6268622BDC47E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5B7429374B6EEABBFC1E1EABA7B4556D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2313F1DCFFF1A82931A5DF3F158D5DA3 /* Pods-Stone Island.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACH_O_TYPE = staticlib; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + B2C80873CD55005750F481B734E9380D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C86D2D78080EDCEE85A13AA1692ACD6 /* Pods-Stone Island.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACH_O_TYPE = staticlib; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 015A368F878AC3E2CEAE21DDE8026304 /* Debug */, + 44CDBB6D11DE06DB64D6268622BDC47E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BD1D1A57A9121FF061B86F474E27AA5E /* Build configuration list for PBXNativeTarget "Pods-Stone Island" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5B7429374B6EEABBFC1E1EABA7B4556D /* Debug */, + B2C80873CD55005750F481B734E9380D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/Pods-Stone Island.xcscheme b/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/Pods-Stone Island.xcscheme new file mode 100644 index 00000000..3079e230 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/Pods-Stone Island.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist b/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..b85ff3ff --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Pods.xcodeproj/xcuserdata/user.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,16 @@ + + + + + SchemeUserState + + Pods-Stone Island.xcscheme + + isShown + + + + SuppressBuildableAutocreation + + + diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.markdown b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.markdown new file mode 100644 index 00000000..c07bb6cb --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.markdown @@ -0,0 +1,27 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## GGLInstanceID + +Copyright 2015 Google Inc. + +## GoogleCloudMessaging + +Copyright 2015 Google Inc. + +## GoogleIPhoneUtilities + +Copyright 2015 Google Inc. + +## GoogleInterchangeUtilities + +Copyright 2016 Google + +## GoogleSymbolUtilities + +Copyright 2016 Google + +## GoogleUtilities + +Copyright 2016 Google +Generated by CocoaPods - https://cocoapods.org diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.plist b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.plist new file mode 100644 index 00000000..bf288035 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-acknowledgements.plist @@ -0,0 +1,89 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright 2015 Google Inc. + License + Copyright + Title + GGLInstanceID + Type + PSGroupSpecifier + + + FooterText + Copyright 2015 Google Inc. + License + Copyright + Title + GoogleCloudMessaging + Type + PSGroupSpecifier + + + FooterText + Copyright 2015 Google Inc. + License + Copyright + Title + GoogleIPhoneUtilities + Type + PSGroupSpecifier + + + FooterText + Copyright 2016 Google + License + Copyright + Title + GoogleInterchangeUtilities + Type + PSGroupSpecifier + + + FooterText + Copyright 2016 Google + License + Copyright + Title + GoogleSymbolUtilities + Type + PSGroupSpecifier + + + FooterText + Copyright 2016 Google + License + Copyright + Title + GoogleUtilities + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-dummy.m b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-dummy.m new file mode 100644 index 00000000..d7c71b29 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_Stone_Island : NSObject +@end +@implementation PodsDummy_Pods_Stone_Island +@end diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-frameworks.sh b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-frameworks.sh new file mode 100755 index 00000000..0f29f13c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-frameworks.sh @@ -0,0 +1,92 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-resources.sh b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-resources.sh new file mode 100755 index 00000000..4602c68a --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island-resources.sh @@ -0,0 +1,99 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.debug.xcconfig b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.debug.xcconfig new file mode 100644 index 00000000..fcb5941f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.debug.xcconfig @@ -0,0 +1,9 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/GoogleIPhoneUtilities/Frameworks" "${PODS_ROOT}/GoogleInterchangeUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleSymbolUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleUtilities/Frameworks/frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/GGLInstanceID" "${PODS_ROOT}/Headers/Public/GoogleCloudMessaging" "${PODS_ROOT}/Headers/Public/GoogleIPhoneUtilities" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/GGLInstanceID/Libraries" $(inherited) "${PODS_ROOT}/GoogleCloudMessaging/Libraries" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/GGLInstanceID" -isystem "${PODS_ROOT}/Headers/Public/GoogleCloudMessaging" -isystem "${PODS_ROOT}/Headers/Public/GoogleIPhoneUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" +OTHER_LDFLAGS = $(inherited) -ObjC -l"GGLInstanceIDLib" -l"GcmLib" -l"sqlite3" -l"z" -framework "AddressBook" -framework "CoreGraphics" -framework "GoogleIPhoneUtilities" -framework "GoogleInterchangeUtilities" -framework "GoogleSymbolUtilities" -framework "GoogleUtilities" -framework "SystemConfiguration" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.release.xcconfig b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.release.xcconfig new file mode 100644 index 00000000..fcb5941f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/Target Support Files/Pods-Stone Island/Pods-Stone Island.release.xcconfig @@ -0,0 +1,9 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/GoogleIPhoneUtilities/Frameworks" "${PODS_ROOT}/GoogleInterchangeUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleSymbolUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleUtilities/Frameworks/frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/GGLInstanceID" "${PODS_ROOT}/Headers/Public/GoogleCloudMessaging" "${PODS_ROOT}/Headers/Public/GoogleIPhoneUtilities" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/GGLInstanceID/Libraries" $(inherited) "${PODS_ROOT}/GoogleCloudMessaging/Libraries" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/GGLInstanceID" -isystem "${PODS_ROOT}/Headers/Public/GoogleCloudMessaging" -isystem "${PODS_ROOT}/Headers/Public/GoogleIPhoneUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" +OTHER_LDFLAGS = $(inherited) -ObjC -l"GGLInstanceIDLib" -l"GcmLib" -l"sqlite3" -l"z" -framework "AddressBook" -framework "CoreGraphics" -framework "GoogleIPhoneUtilities" -framework "GoogleInterchangeUtilities" -framework "GoogleSymbolUtilities" -framework "GoogleUtilities" -framework "SystemConfiguration" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Info.plist b/StoneIsland/platforms/ios/Stone Island.xcarchive/Info.plist deleted file mode 100644 index 74217279..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Info.plist +++ /dev/null @@ -1,27 +0,0 @@ - - - - - ApplicationProperties - - ApplicationPath - Applications/Stone Island.app - CFBundleIdentifier - us.okfoc.stoneisland - CFBundleShortVersionString - 0.8.0 - CFBundleVersion - 0.8.0 - SigningIdentity - iPhone Developer: Francesca Agusani (3ECUPBTQ5W) - - ArchiveVersion - 2 - CreationDate - 2017-01-20T20:36:33Z - Name - Stone Island - SchemeName - Stone Island - - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29.png deleted file mode 100644 index 115e4fc3..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x.png deleted file mode 100644 index c0047782..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x~ipad.png deleted file mode 100644 index c0047782..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@3x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@3x.png deleted file mode 100644 index 0a2a876e..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29@3x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29~ipad.png deleted file mode 100644 index 115e4fc3..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon29x29~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x.png deleted file mode 100644 index 6bc8a6f9..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x~ipad.png deleted file mode 100644 index 6bc8a6f9..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@3x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@3x.png deleted file mode 100644 index fcbbd302..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40@3x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40~ipad.png deleted file mode 100644 index 616ad6df..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon40x40~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50@2x~ipad.png deleted file mode 100644 index 4d72e228..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50~ipad.png deleted file mode 100644 index 6feab376..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon50x50~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57.png deleted file mode 100644 index b6ef8313..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57@2x.png deleted file mode 100644 index 1dc85876..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon57x57@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@2x.png deleted file mode 100644 index fcbbd302..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@3x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@3x.png deleted file mode 100644 index 8cf30490..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon60x60@3x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72@2x~ipad.png deleted file mode 100644 index 8ef501ff..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72~ipad.png deleted file mode 100644 index ffe52c04..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon72x72~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76@2x~ipad.png deleted file mode 100644 index cc77f8b1..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76~ipad.png deleted file mode 100644 index f7e44a55..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon76x76~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon83.5x83.5@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon83.5x83.5@2x~ipad.png deleted file mode 100644 index 676bfd72..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/AppIcon83.5x83.5@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib deleted file mode 100644 index 05706433..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/Info.plist b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/Info.plist deleted file mode 100644 index 32288e88..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/Info.plist and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib deleted file mode 100644 index 98b46dbe..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVLaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVNotification.bundle/beep.wav b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVNotification.bundle/beep.wav deleted file mode 100644 index 05f5997f..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/CDVNotification.bundle/beep.wav and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Info.plist b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Info.plist deleted file mode 100644 index 8bb5e25b..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Info.plist and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-568h@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-568h@2x.png deleted file mode 100644 index 83144521..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-568h@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-568h@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-568h@2x.png deleted file mode 100644 index 83144521..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-568h@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape@2x~ipad.png deleted file mode 100644 index 88028e75..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape~ipad.png deleted file mode 100644 index 82389130..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Landscape~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait@2x~ipad.png deleted file mode 100644 index a3e503b6..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait~ipad.png deleted file mode 100644 index 5ca496f6..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700-Portrait~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700@2x.png deleted file mode 100644 index 020f271e..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-700@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-667h@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-667h@2x.png deleted file mode 100644 index 91a2c52d..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-667h@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Landscape-736h@3x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Landscape-736h@3x.png deleted file mode 100644 index 3e7445e4..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Landscape-736h@3x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Portrait-736h@3x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Portrait-736h@3x.png deleted file mode 100644 index 05e491f7..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-800-Portrait-736h@3x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait@2x~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait@2x~ipad.png deleted file mode 100644 index a3e503b6..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait@2x~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait~ipad.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait~ipad.png deleted file mode 100644 index 5ca496f6..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage-Portrait~ipad.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage.png deleted file mode 100644 index a1fae077..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage@2x.png b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage@2x.png deleted file mode 100644 index 020f271e..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/LaunchImage@2x.png and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/MainViewController.nib b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/MainViewController.nib deleted file mode 100644 index cf4370bd..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/MainViewController.nib and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/PkgInfo b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/PkgInfo deleted file mode 100644 index bd04210f..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/PkgInfo +++ /dev/null @@ -1 +0,0 @@ -APPL???? \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Stone Island b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Stone Island deleted file mode 100755 index ef762831..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/Stone Island and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/_CodeSignature/CodeResources b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/_CodeSignature/CodeResources deleted file mode 100644 index 879771f1..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/_CodeSignature/CodeResources +++ /dev/null @@ -1,2750 +0,0 @@ - - - - - files - - AppIcon29x29.png - - SkcaGHVnT9P/qSQQ+4Gv5KAIFiE= - - AppIcon29x29@2x.png - - p48H+Zyg+XP4UN0qToFo2pq2hIc= - - AppIcon29x29@2x~ipad.png - - p48H+Zyg+XP4UN0qToFo2pq2hIc= - - AppIcon29x29@3x.png - - HsbfsNZ1o5le1gNlcpLUg+po+Lc= - - AppIcon29x29~ipad.png - - SkcaGHVnT9P/qSQQ+4Gv5KAIFiE= - - AppIcon40x40@2x.png - - 2QvPCK1KnweKJcG2tBKJCHrznYQ= - - AppIcon40x40@2x~ipad.png - - 2QvPCK1KnweKJcG2tBKJCHrznYQ= - - AppIcon40x40@3x.png - - Y8AqU81+OvTufS8MWc61wWwCQTQ= - - AppIcon40x40~ipad.png - - ueXCfpeU+pPUsBdO4asHM4KymDA= - - AppIcon50x50@2x~ipad.png - - oj0shAA4Su/191R8Q+LKP/BEzVA= - - AppIcon50x50~ipad.png - - 5VtyO9TphV2a3z4Vbfhti0zZtKs= - - AppIcon57x57.png - - gfmfO9TfHEebSWBpkWNV6FUurI8= - - AppIcon57x57@2x.png - - /r8UoF/P106RAXYZvmwNgiydWYM= - - AppIcon60x60@2x.png - - Y8AqU81+OvTufS8MWc61wWwCQTQ= - - AppIcon60x60@3x.png - - 5oI27AnauPDNh2F5q+YrpZtD+48= - - AppIcon72x72@2x~ipad.png - - HD012utiYu+ek8NlIBtzrJhCmC8= - - AppIcon72x72~ipad.png - - qSLjH0jQg38tX9Bx+hOuMk6NxNk= - - AppIcon76x76@2x~ipad.png - - dlOcJOtcPjRjkwulTjLAY8GPZZA= - - AppIcon76x76~ipad.png - - Ve9ZqOTK8BihA4HYTJwykgfgY28= - - AppIcon83.5x83.5@2x~ipad.png - - GHVEhRmiedGcz8KLqZCEPh+kXPo= - - CDVLaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib - - c/Pl+qBPl3aIxiLxTUtR4k0lMiA= - - CDVLaunchScreen.storyboardc/Info.plist - - n2t8gsDpfE6XkhG31p7IQJRxTxU= - - CDVLaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib - - GMZV3G/NdtOLRhkDopr22KVeDbI= - - CDVNotification.bundle/beep.wav - - /kSUVvLLJcbtfXnxFEolil3/NRk= - - Info.plist - - 20BKX4+7uBklXrzLi9XzA/B4ri4= - - LaunchImage-568h@2x.png - - UH+OgGAjK3cqXizBT304d3mMrqw= - - LaunchImage-700-568h@2x.png - - UH+OgGAjK3cqXizBT304d3mMrqw= - - LaunchImage-700-Landscape@2x~ipad.png - - b34M7KURjI3tAEYJyb9bDetEOKk= - - LaunchImage-700-Landscape~ipad.png - - +Q4Z+wK1o5OlogeOT/EZ1O9HSaY= - - LaunchImage-700-Portrait@2x~ipad.png - - SFAx/rYayxKUYJysfdHAq6HZYGU= - - LaunchImage-700-Portrait~ipad.png - - YIR03CUXDHj5DD41uIziOwvCe0Q= - - LaunchImage-700@2x.png - - wdVG4cEwbXYocG4qtLe6YaFce3s= - - LaunchImage-800-667h@2x.png - - Nclq3E0wzq4fEV+Yt1jg4tD7YRI= - - LaunchImage-800-Landscape-736h@3x.png - - 7nwUm4RbhDvy8jLxj4Xf245WRzY= - - LaunchImage-800-Portrait-736h@3x.png - - fjeNqjI6d5Acj2HHzZnNbjuxrPw= - - LaunchImage-Portrait@2x~ipad.png - - SFAx/rYayxKUYJysfdHAq6HZYGU= - - LaunchImage-Portrait~ipad.png - - YIR03CUXDHj5DD41uIziOwvCe0Q= - - LaunchImage.png - - /zAVX3eDQibf5oRIPirMaTRqfVo= - - LaunchImage@2x.png - - wdVG4cEwbXYocG4qtLe6YaFce3s= - - MainViewController.nib - - 6nzop6hXIMvzUpdxP3go0YETHzA= - - PkgInfo - - n57qDP4tZfLD1rCS43W0B4LQjzE= - - archived-expanded-entitlements.xcent - - vO/gVYVVkU1zHBaxd4xJ53/ga5k= - - config.xml - - 3Z0rjLA1N9mMa7ltNZco1L8VxSs= - - embedded.mobileprovision - - 0t7sQABsmS5sfpNBdmq1A75IaTs= - - www/cordova-js-src/exec.js - - 3QDPaUQrAr8Wq2XcQhqcl8DLabQ= - - www/cordova-js-src/platform.js - - s+KdzB0mMHQsQQTAofDqS0ApWpY= - - www/cordova.js - - hYeg9zH5hCPufSL3lQ4iz/z1w5U= - - www/cordova_plugins.js - - J8E51PJTqSRuVx7LiqXq+AjlIco= - - www/css/account.css - - axxgrXIetV5Et2yI9QIjafIEpa0= - - www/css/blogs.css - - uoDbpZ20pX9gG/U1j4RiYqBz1oc= - - www/css/cart.css - - f8AmevHsGVmWkazWNR/SkQ8ctDE= - - www/css/fonts/andale_mono.ttf - - LNdqAJjPnsKnT1GghSkYxImlFvQ= - - www/css/fonts/andale_mono.woff - - uOPMweytjo+6Egyqhu+4GdPmgq8= - - www/css/fonts/fonts.css - - NKnz6tasTlqoICSI4V4YlOeHVJM= - - www/css/fonts/ionicons.css - - gzPAFostLVCiwxkgMsSWmTe+A/c= - - www/css/fonts/ionicons.eot - - YVMuieIS+N0WujHz6881wKczQDU= - - www/css/fonts/ionicons.svg - - Pxyij8sELSvMbuak492BflEy7uo= - - www/css/fonts/ionicons.ttf - - GwoN4ISQWUaiAwDKjDVIZd7EZ2Q= - - www/css/fonts/ionicons.woff - - 5GgZ6GOkZ1HWIsEZDE6Kg+vCBhI= - - www/css/fonts/pfdintextpro-bold-webfont.woff - - mDYay3ArKzHK+mu3l0GGL7AJYI8= - - www/css/fonts/pfdintextpro-italic-webfont.woff - - gtSnNX5Vtd1JOciHX7Q2IGnhYEk= - - www/css/fonts/pfdintextpro-light-webfont.woff - - 2ZQAPshoOfFBipDEgccDh0IDokQ= - - www/css/fonts/pfdintextpro-medium-webfont.woff - - KyUoyPHWVunK8heDhzHDUKbf1VA= - - www/css/fonts/pfdintextpro-regular-webfont.woff - - zn1xFRXWNWSV7oJEL0mt+0JLjNE= - - www/css/index.css - - sS5Z897GbFcFtJaWKk9Ft6T/Vtg= - - www/css/nav.css - - aCFlsZzgMtbv6Z6bkKwkakJFAdo= - - www/css/products.css - - 8NxXmll+RoAdH9QSHGDD3UVZps8= - - www/css/vendor/flickity.css - - xW5wsn/T/+uaGvIT+Sl9WY/IM2k= - - www/img/Resources/CDVNotification.bundle/beep.wav - - /kSUVvLLJcbtfXnxFEolil3/NRk= - - www/img/Resources/splash/Default-568h@2x~iphone.png - - J8BakinXs4g2c3rjIlkaUKc1m3k= - - www/img/Resources/splash/Default-667h.png - - KeM+qh3e57f5eeltxETo6kNL/lk= - - www/img/Resources/splash/Default-736h.png - - 5egepTM4V7rMvBkpkxUc8RAcJaI= - - www/img/Resources/splash/Default-Landscape-736h.png - - OakZWPocy5SHfGOIcwCCOoHVEqA= - - www/img/Resources/splash/Default-Landscape@2x~ipad.png - - q8VJZgMwFNZmWGD/Lf1/2KJt42c= - - www/img/Resources/splash/Default-Landscape~ipad.png - - PhNiOU4rbDZLXNv3olAhvfd9XQk= - - www/img/Resources/splash/Default-Portrait@2x~ipad.png - - CwZQXSzj9Gai0+MUt1mGzHuYO4U= - - www/img/Resources/splash/Default-Portrait~ipad.png - - ONniQfICjQTe8yPDO4mhWp9I2pM= - - www/img/Resources/splash/Default@2x~iphone.png - - uMF7RsyJGko7JaycVJ1sdu4hN/A= - - www/img/Resources/splash/Default~iphone.png - - btYS0PqHlIXDTLPf+7ZkA8uadDw= - - www/img/angle-down.png - - I9z7X0QqPVunkk2Pp6QVBfjF/Ug= - - www/img/bottom-fade.png - - doxZCcQch8Yt0UXMMvPBppxacg0= - - www/img/cart-box.png - - 76PMCjdfolbYk9wB0iPxqaLwpzk= - - www/img/cart-handle.png - - DIrmugvltD/RB0iy1latRCJGUec= - - www/img/compass-logo.png - - hO/U4zzOyjwTppKJ9FKI73NPrGU= - - www/img/compass-logo.png.old - - vwVmYayeHMzxccFD/TN328PqiVk= - - www/img/fade-to-bottom-threshold.gif - - GR0zpcR8KMByQIz2FFd4chj4bGE= - - www/img/fade-to-bottom.png - - doxZCcQch8Yt0UXMMvPBppxacg0= - - www/img/left-arrow.png - - gJa/2uVfymH2Yxi4/cvGN+OdrWM= - - www/img/right-arrow.png - - MSgmEvsEIKkviNZIWWCPJeKdJqY= - - www/img/small-cart-box.png - - DJxx7Sxv9HGOumgrHLmIk1YfW7c= - - www/img/small-cart-handle.png - - SlZeorPNUiYlNNv0UCnVXxyNZPc= - - www/img/small-logo.png - - FRbH5vLd9Z1i4k0dBsW+I5+g4qo= - - www/img/spinner.gif - - oEyz0SzCG90twGaMhPwiIjXakkg= - - www/img/wide-logo.png - - WJ/FbJfrZcN2Pg0w6S5c202hwSs= - - www/index.html - - cHaAaJFUHzkRsRxxXUYgbZ7bTU8= - - www/js/index.js - - lHrAnPULXf+uCnPUC5QOpNRZus0= - - www/js/lib/_router.js - - kEgP1UyqTxv0qdxIM4py0YvbGI0= - - www/js/lib/account/AccountView.js - - W2IiMSfOb/ivtxm7golqGg9Dry4= - - www/js/lib/account/OrdersView.js - - zEEbcESh8kYxm6fkztCPSUnjOLI= - - www/js/lib/account/PaymentView.js - - vfzNv1bbaCT//rEXo75q9TiF8Pw= - - www/js/lib/account/ProfileView.js - - DgZUkAEKZ42L8/H/KVc/Q+/dfks= - - www/js/lib/account/SettingsView.js - - 799oolaHYxeTXVS5OVo1GzkT8Vs= - - www/js/lib/account/ShippingView.js - - QpU4sBWoLqQix318vfnMz8Z/vwk= - - www/js/lib/auth/LoginView.js - - Q8LTQvuQwncpnskoB44zgMeJlbU= - - www/js/lib/auth/LogoutView.js - - jhf/Pzr8A/yk68t3W15g32q4eQ4= - - www/js/lib/auth/SignupView.js - - BW47+iLRQW0R+VvYKbQMpjlMn9Y= - - www/js/lib/blogs/ArchiveView.js - - 0MoYu/cf89T9Yj3/GqkxVS5Kn0s= - - www/js/lib/blogs/BlogView.js - - v8Sji53Jji6wQl1MUQtgg0B/ML8= - - www/js/lib/blogs/HubView.js - - 6DGehG89PP9aUQaW7PHtwuDnErE= - - www/js/lib/blogs/PageView.js - - fnTO0QKgJ08PPNTrTuT+hgmLtqc= - - www/js/lib/blogs/StoryView.js - - 0uCBjGnwq8xsO5chZu/C1rGZ/SQ= - - www/js/lib/cart/CartConfirm.js - - jqryKPHj843xlpHaPq2On9mfaeM= - - www/js/lib/cart/CartError.js - - AeAnmVjk6HP4fhuICpuG8nHnFuI= - - www/js/lib/cart/CartPayment.js - - rDqDb4NQqfdMi2jqwjRebdL9ZPU= - - www/js/lib/cart/CartShipping.js - - TNWriqY40wM6Yr9PTPmSjNqwxqs= - - www/js/lib/cart/CartSummary.js - - YYiOPlDBi/ESvBJZ+bBt5ElQ254= - - www/js/lib/cart/CartThanks.js - - JOo957U9zyzfOkwPIJ7K0oMB5SA= - - www/js/lib/cart/CartView.js - - +kmEZ9ukx0LiHKArz7oWZyBZr/4= - - www/js/lib/etc/backup_db.js - - BwItWjWxRLRdqFFVUnLyB+Cz/94= - - www/js/lib/etc/deeplink.js - - Xjr3J9pMm16R4X4Ez0w2889N4Is= - - www/js/lib/etc/geo.js - - xaQ5M8Pao+Ewh6usOyD5UV/49gc= - - www/js/lib/etc/push.js - - hfTCoCCPYRemV3DKX6CQdpF9aok= - - www/js/lib/nav/AddressView.js - - JFoETIdARQvI5GU6tc1YJhhttEc= - - www/js/lib/nav/CreditCardView.js - - uV1Y5XohZktnJXSKPs/gt/vhlzk= - - www/js/lib/nav/CurtainView.js - - VHa9pwxWtQ31RhBknlTCAqrKA7c= - - www/js/lib/nav/FooterView.js - - WaOKgFizQ3W8RPEhwga57tf3sLM= - - www/js/lib/nav/HeaderView.js - - Ui2nti/7MEoaanRA/U1QuO6cVSQ= - - www/js/lib/nav/IntroView.js - - FSNPuiLwJs4MyLmkvAY6k3RPRF8= - - www/js/lib/nav/NavView.js - - vVy7+c8F2D+3VFixaG8D1GqdHL4= - - www/js/lib/nav/SearchView.js - - b8Xg3rQZIafOl+uBceHrk6yVqYU= - - www/js/lib/products/ClosedStoreView.js - - iDWe+pvx3vGBohpZ05biGudY71o= - - www/js/lib/products/CollectionView.js - - 4jUFxdjwhpGFj1x4zVhis4hY7Uw= - - www/js/lib/products/GalleryView.js - - CpqSBwnIKxV0wFGD8GdU82L9oqI= - - www/js/lib/products/ProductView.js - - au2e+E3AV/VQdK0dax41Y7Kzbrw= - - www/js/lib/products/Selector.js - - fVQwXy2n+BjjueoUiZNX5I2f//w= - - www/js/lib/products/filters/CategoryFilter.js - - z8glR9hNUq3u4RpoKJRCV6oag8o= - - www/js/lib/products/filters/DepartmentFilter.js - - LueAI+hrodiC7/iu987ag8xkACw= - - www/js/lib/view/Router.js - - nC19loTSWgo+YghXIQTdo2qViKw= - - www/js/lib/view/Scrollable.js - - eUKMRV6KXM82cDq9rFnmFWP4QAQ= - - www/js/lib/view/Serializable.js - - 1axFnf92uYJ5GPvZdeKU+zPGLuw= - - www/js/lib/view/View.js - - 1vOGv/o4d073vpU6t8Dn08nZsnY= - - www/js/sdk/_sdk.js - - lQSwQ13C2sQbmhoFgz8BMYN/dIk= - - www/js/sdk/account.js - - iFcyfpZSqqeP8RQ80FNBdRFrjNI= - - www/js/sdk/address.js - - 58zTcGuj9yQkjVJYaxboOYe+LiI= - - www/js/sdk/auth.js - - GeG4SscTJbq+zn8HT+R3CEvfKc4= - - www/js/sdk/cart.js - - TWij8pn0/F4YBj04iBZzNX2NyuQ= - - www/js/sdk/payment.js - - j3efOwLU577n/V2UAVxVHU/0NB8= - - www/js/sdk/product.js - - ZYf0fQuZdLIS1ZXTJSingxo32Hs= - - www/js/sdk/shipping.js - - 04qsgSJ7isNdqyVfM1LQ7Q6wRwM= - - www/js/vendor/fastclick.js - - GsPVekcRLSRd6GYRskvAbulostc= - - www/js/vendor/flickity.pkgd.js - - 7+L7DJW+IWJnI8uOkBFuyww3Bk0= - - www/js/vendor/iscroll.js - - zmIJQRtMdsZHuPuHvHEe8K1HC7w= - - www/js/vendor/jquery-2.1.4.min.js - - Q9xVRgjfiFpZ3e7OFZjGrOQ010c= - - www/js/vendor/jquery.creditCardValidator.js - - Y27vkeRB6sxVVgVnzd82mRHab3g= - - www/js/vendor/loader.js - - rX3eSoXrP9KCszh6/7wYgtEAKIE= - - www/js/vendor/lodash.min.js - - QH5J71GV/YmbKvW8dOzPWmIy2Js= - - www/js/vendor/moment.js - - up6xZ/qvAr5h9VNpOTtzN9Jzv6Y= - - www/js/vendor/oktween.js - - IbqDpG6Qitgu8bvKthKC6hJyb1g= - - www/js/vendor/prefixfree.js - - ImNOjml3qilBB3P2Q+D2oh0XZlo= - - www/js/vendor/promise.js - - c/6/xZdHlYR9yLjMoxE3Tk2wdgc= - - www/js/vendor/util.js - - awGO8rHbB+UyNdCDbLXrp2nihQg= - - www/plugins/com.parse.cordova.core.pushplugin/www/cdv-plugin-parse.js - - AJEko/0+djDFCw9vjtZplT91zAQ= - - www/plugins/cordova-plugin-console/www/console-via-logger.js - - NyUkntRl9vFIiOC3onmXNsxpedU= - - www/plugins/cordova-plugin-console/www/logger.js - - tmAfmQQR8NZd7y+bTWuju4/TbY0= - - www/plugins/cordova-plugin-customurlscheme/www/ios/LaunchMyApp.js - - 0NrlXTwBHUS5u9XaqkoSJ+waVDo= - - www/plugins/cordova-plugin-device/www/device.js - - DgD9WKGqlbNViEZBSi4Wenbl/uM= - - www/plugins/cordova-plugin-dialogs/www/notification.js - - 7DTImwpj5B7VCelKiHdmmFLX6h0= - - www/plugins/cordova-plugin-geolocation/www/Coordinates.js - - B+vlNAwNL/8E91a2w8xN/QZtP9o= - - www/plugins/cordova-plugin-geolocation/www/Position.js - - 1DZ/xrP/zFT+anCeCYYt+uuQIyU= - - www/plugins/cordova-plugin-geolocation/www/PositionError.js - - NZQ0MpOiURNiYMJS79+bdtSDnzI= - - www/plugins/cordova-plugin-geolocation/www/geolocation.js - - DBMSf1DRKjXfKMDgaSJHjnx+wgI= - - www/plugins/cordova-plugin-inappbrowser/www/inappbrowser.js - - EfUzmAcUagDDJeG2yHQTy4FngxU= - - www/plugins/cordova-plugin-network-information/www/Connection.js - - QP5YzumNbUCPIZ96Xkpu5RegRY0= - - www/plugins/cordova-plugin-network-information/www/network.js - - jxeuXL/JPk6C5eQC7iVThLg7NPc= - - www/plugins/cordova-plugin-splashscreen/www/splashscreen.js - - n2E0W8B/grOxM2ORx/haAYOWIcA= - - www/plugins/cordova-plugin-x-socialsharing/www/SocialSharing.js - - p2ovf3IcCK49/GvqK+j7UmFu1zI= - - www/plugins/ionic-plugin-keyboard/www/ios/keyboard.js - - gexyZjGUVvhbQiJbBzCrImXWv34= - - - files2 - - AppIcon29x29.png - - hash - - SkcaGHVnT9P/qSQQ+4Gv5KAIFiE= - - hash2 - - r927cBNXePynmQbhHAevM/M9ocggRFeggjDNXqnxnyU= - - - AppIcon29x29@2x.png - - hash - - p48H+Zyg+XP4UN0qToFo2pq2hIc= - - hash2 - - LgG141XkDY5yLwj6qCct8NiEtfc4vqbCJDqc0PK6+PE= - - - AppIcon29x29@2x~ipad.png - - hash - - p48H+Zyg+XP4UN0qToFo2pq2hIc= - - hash2 - - LgG141XkDY5yLwj6qCct8NiEtfc4vqbCJDqc0PK6+PE= - - - AppIcon29x29@3x.png - - hash - - HsbfsNZ1o5le1gNlcpLUg+po+Lc= - - hash2 - - IgtYuDMY0hyX6URwrm+pFugUQZXnl9qMB/049arV068= - - - AppIcon29x29~ipad.png - - hash - - SkcaGHVnT9P/qSQQ+4Gv5KAIFiE= - - hash2 - - r927cBNXePynmQbhHAevM/M9ocggRFeggjDNXqnxnyU= - - - AppIcon40x40@2x.png - - hash - - 2QvPCK1KnweKJcG2tBKJCHrznYQ= - - hash2 - - GDGFJbqFrg0J0QQTphMQ5dVcXWHOpFXm66eK91Nm1ts= - - - AppIcon40x40@2x~ipad.png - - hash - - 2QvPCK1KnweKJcG2tBKJCHrznYQ= - - hash2 - - GDGFJbqFrg0J0QQTphMQ5dVcXWHOpFXm66eK91Nm1ts= - - - AppIcon40x40@3x.png - - hash - - Y8AqU81+OvTufS8MWc61wWwCQTQ= - - hash2 - - awe2pg7dmJb4KuSEtgCPaNWANX9yYZW+GHf8bnzgSx8= - - - AppIcon40x40~ipad.png - - hash - - ueXCfpeU+pPUsBdO4asHM4KymDA= - - hash2 - - 11WxFXAaQ3xiyIo5JUpOXG+M1khMxepa134kiB4RX2c= - - - AppIcon50x50@2x~ipad.png - - hash - - oj0shAA4Su/191R8Q+LKP/BEzVA= - - hash2 - - IP2DyAGlSJWHLlRb3myuud6jCbJtAv8a3+GBm6Sy/lc= - - - AppIcon50x50~ipad.png - - hash - - 5VtyO9TphV2a3z4Vbfhti0zZtKs= - - hash2 - - 1nRtF8loYY7Go8n1yFI/PKmfd2a93PdnbGiMeI5Ohzc= - - - AppIcon57x57.png - - hash - - gfmfO9TfHEebSWBpkWNV6FUurI8= - - hash2 - - tjtKf5tCaWRnQubRvjYsu6+LR7Py4lMgF6yAd00tnpg= - - - AppIcon57x57@2x.png - - hash - - /r8UoF/P106RAXYZvmwNgiydWYM= - - hash2 - - B9x9Ug2vzqnl6hTockB7Luj418Q15jnssbmPll1omp4= - - - AppIcon60x60@2x.png - - hash - - Y8AqU81+OvTufS8MWc61wWwCQTQ= - - hash2 - - awe2pg7dmJb4KuSEtgCPaNWANX9yYZW+GHf8bnzgSx8= - - - AppIcon60x60@3x.png - - hash - - 5oI27AnauPDNh2F5q+YrpZtD+48= - - hash2 - - EJLn5BFZ+TkFp9hS7yBLUIe0RJWiWjQ6cUJVK8+SbRw= - - - AppIcon72x72@2x~ipad.png - - hash - - HD012utiYu+ek8NlIBtzrJhCmC8= - - hash2 - - QJQis7hwMgWD7W8kogxTcK2mg5y0c1LicSAzKKx5bbc= - - - AppIcon72x72~ipad.png - - hash - - qSLjH0jQg38tX9Bx+hOuMk6NxNk= - - hash2 - - rJPabQlJ3Aanz5U6rBLHaAQXniUHMUko0+4stQ/yyws= - - - AppIcon76x76@2x~ipad.png - - hash - - dlOcJOtcPjRjkwulTjLAY8GPZZA= - - hash2 - - mtaIhhFULit64M3iKYKu7iAutmgtBWkp3gh3k+cZ1KM= - - - AppIcon76x76~ipad.png - - hash - - Ve9ZqOTK8BihA4HYTJwykgfgY28= - - hash2 - - Dffa9VZx3iycdMB4HMZc5ysKNRIWxxEh4JHtaVGmxhM= - - - AppIcon83.5x83.5@2x~ipad.png - - hash - - GHVEhRmiedGcz8KLqZCEPh+kXPo= - - hash2 - - CNU1YmRLcAD0qWy/LBbidDHabx5le6WDGFqAQ5EXJV0= - - - CDVLaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib - - hash - - c/Pl+qBPl3aIxiLxTUtR4k0lMiA= - - hash2 - - LnF5YYLIL1rsTwq9AhHz77NANFejlsY/YBexKpFbgpw= - - - CDVLaunchScreen.storyboardc/Info.plist - - hash - - n2t8gsDpfE6XkhG31p7IQJRxTxU= - - hash2 - - HyVdXMU7Ux4/KalAao30mpWOK/lEPT4gvYN09wf31cg= - - - CDVLaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib - - hash - - GMZV3G/NdtOLRhkDopr22KVeDbI= - - hash2 - - URhWRC1aBxuLyRT3maXwcCA/ACnR7iviM+isI49PZOw= - - - CDVNotification.bundle/beep.wav - - hash - - /kSUVvLLJcbtfXnxFEolil3/NRk= - - hash2 - - KfYd4hFlyPwinBGKi4ruYae1MyeQ2TKrPJvIngKdC38= - - - LaunchImage-568h@2x.png - - hash - - UH+OgGAjK3cqXizBT304d3mMrqw= - - hash2 - - RQPG/EP5D7a90jDop0xOgps/wNNd5f21v7GIwdfPgPQ= - - - LaunchImage-700-568h@2x.png - - hash - - UH+OgGAjK3cqXizBT304d3mMrqw= - - hash2 - - RQPG/EP5D7a90jDop0xOgps/wNNd5f21v7GIwdfPgPQ= - - - LaunchImage-700-Landscape@2x~ipad.png - - hash - - b34M7KURjI3tAEYJyb9bDetEOKk= - - hash2 - - s/HRaUtpRYxFG3TTQ1iHmWkfiX6TlTgYMEtVPO3ejQg= - - - LaunchImage-700-Landscape~ipad.png - - hash - - +Q4Z+wK1o5OlogeOT/EZ1O9HSaY= - - hash2 - - dwS7dKv/fQuy/0XMC9PiCWBR3sD18vHB4T4XhOWsYGc= - - - LaunchImage-700-Portrait@2x~ipad.png - - hash - - SFAx/rYayxKUYJysfdHAq6HZYGU= - - hash2 - - zGfDttX4ljdH8YPxSlw+W2CymhUlq9/jqIiY9A3oK9Q= - - - LaunchImage-700-Portrait~ipad.png - - hash - - YIR03CUXDHj5DD41uIziOwvCe0Q= - - hash2 - - ceZV45wiHEaeS9ldpeCOXLW0GHrOWNEejrPWExpTAiY= - - - LaunchImage-700@2x.png - - hash - - wdVG4cEwbXYocG4qtLe6YaFce3s= - - hash2 - - zS4kg67C3jYjqn8tsDg+HISUnqSMiFCdXwWnGF4/kNk= - - - LaunchImage-800-667h@2x.png - - hash - - Nclq3E0wzq4fEV+Yt1jg4tD7YRI= - - hash2 - - YbiOzohoMEZIQrDNA3wefntLUyfuWt9jrXfwab/n48I= - - - LaunchImage-800-Landscape-736h@3x.png - - hash - - 7nwUm4RbhDvy8jLxj4Xf245WRzY= - - hash2 - - qhHyOrSsQFil0Z4vwnjQF2d2at/WNTmL5oHOcP31pdU= - - - LaunchImage-800-Portrait-736h@3x.png - - hash - - fjeNqjI6d5Acj2HHzZnNbjuxrPw= - - hash2 - - HV/AAUZbbqVF8+LAhAdG1r69e0HkNZo+Y6MckiESpGg= - - - LaunchImage-Portrait@2x~ipad.png - - hash - - SFAx/rYayxKUYJysfdHAq6HZYGU= - - hash2 - - zGfDttX4ljdH8YPxSlw+W2CymhUlq9/jqIiY9A3oK9Q= - - - LaunchImage-Portrait~ipad.png - - hash - - YIR03CUXDHj5DD41uIziOwvCe0Q= - - hash2 - - ceZV45wiHEaeS9ldpeCOXLW0GHrOWNEejrPWExpTAiY= - - - LaunchImage.png - - hash - - /zAVX3eDQibf5oRIPirMaTRqfVo= - - hash2 - - Ihk1Y/sxRtDwlb/R5jYPR9UGjtvD3mLAmjfHVCCCx3k= - - - LaunchImage@2x.png - - hash - - wdVG4cEwbXYocG4qtLe6YaFce3s= - - hash2 - - zS4kg67C3jYjqn8tsDg+HISUnqSMiFCdXwWnGF4/kNk= - - - MainViewController.nib - - hash - - 6nzop6hXIMvzUpdxP3go0YETHzA= - - hash2 - - zm/YBxu7XpNg0hjUTDCF4PLB4cw7a5wLh08bzdNePOY= - - - archived-expanded-entitlements.xcent - - hash - - vO/gVYVVkU1zHBaxd4xJ53/ga5k= - - hash2 - - l3BKiWC0+szu9UOXoI+10KRWJHw2JzWSFaoqJ98iZWw= - - - config.xml - - hash - - 3Z0rjLA1N9mMa7ltNZco1L8VxSs= - - hash2 - - uNwXS2htps0KNHClB/BHQqeKM+AoWGiP84vTs2Eltsw= - - - embedded.mobileprovision - - hash - - 0t7sQABsmS5sfpNBdmq1A75IaTs= - - hash2 - - IyefHw++6L0b/5Vg7P0cdhekWU/YEnaOFycYNL/p7HQ= - - - www/cordova-js-src/exec.js - - hash - - 3QDPaUQrAr8Wq2XcQhqcl8DLabQ= - - hash2 - - 3k+JZ8ZeHITt5+/EQNMxMv9o6gJ7PJ7TdGiLTUKTJlU= - - - www/cordova-js-src/platform.js - - hash - - s+KdzB0mMHQsQQTAofDqS0ApWpY= - - hash2 - - VC59qcohWe5Awbx7BGlb0BBJtIPuhBSwQNM2k5RQi/8= - - - www/cordova.js - - hash - - hYeg9zH5hCPufSL3lQ4iz/z1w5U= - - hash2 - - dfmFgVVKEylAM88S8U6sOC51nA/iWk1KrTshtEvuBmo= - - - www/cordova_plugins.js - - hash - - J8E51PJTqSRuVx7LiqXq+AjlIco= - - hash2 - - 7a+H+FerREYdXrrZt6pdm6lvF9H2QsMPP4n/nTAMzwA= - - - www/css/account.css - - hash - - axxgrXIetV5Et2yI9QIjafIEpa0= - - hash2 - - nsNGFwMIcwnLLhikBcrDBJ8ToyqceNHbvavj3z8BRYI= - - - www/css/blogs.css - - hash - - uoDbpZ20pX9gG/U1j4RiYqBz1oc= - - hash2 - - QqQZ5BjyBPjGxiUx+SBuzLiem6repcQ61KRxr4s9fI0= - - - www/css/cart.css - - hash - - f8AmevHsGVmWkazWNR/SkQ8ctDE= - - hash2 - - TnNnjg3PuKGERZhJmaiUD+YBWeRPFEwYC0zwkBHo1TE= - - - www/css/fonts/andale_mono.ttf - - hash - - LNdqAJjPnsKnT1GghSkYxImlFvQ= - - hash2 - - ykNqjwf2aZEHVC6+GdzJR48SqmZpJ2men6EBFefS7pU= - - - www/css/fonts/andale_mono.woff - - hash - - uOPMweytjo+6Egyqhu+4GdPmgq8= - - hash2 - - +E6sojOf4n4Euc8WeVtrjWQrtJ6yUKGjmLUrgURiacs= - - - www/css/fonts/fonts.css - - hash - - NKnz6tasTlqoICSI4V4YlOeHVJM= - - hash2 - - 6whr8edBMPAq5ujWe3GmyVrDTPnYdaDkBaujq1xY2Ng= - - - www/css/fonts/ionicons.css - - hash - - gzPAFostLVCiwxkgMsSWmTe+A/c= - - hash2 - - D3+gw6JE4hEJ9pnCs+BglSfZ2yG5gF+JGdPJ/v183fo= - - - www/css/fonts/ionicons.eot - - hash - - YVMuieIS+N0WujHz6881wKczQDU= - - hash2 - - pIA9e960eKW5I4/nTYqqmNr+Lo5o/MvQ4/Tc7YI/J/A= - - - www/css/fonts/ionicons.svg - - hash - - Pxyij8sELSvMbuak492BflEy7uo= - - hash2 - - pifZBowSNdmzyVxAXrbstkopCxWc9ekmwNltibJM1fw= - - - www/css/fonts/ionicons.ttf - - hash - - GwoN4ISQWUaiAwDKjDVIZd7EZ2Q= - - hash2 - - K6fyCx2JkOF6R/49iOTHZmKKqiuvHdMPygoNtZg29fk= - - - www/css/fonts/ionicons.woff - - hash - - 5GgZ6GOkZ1HWIsEZDE6Kg+vCBhI= - - hash2 - - cJ8nidqv9ECCDruXXTrkCa9FEhvexH456DUjSQsbwPw= - - - www/css/fonts/pfdintextpro-bold-webfont.woff - - hash - - mDYay3ArKzHK+mu3l0GGL7AJYI8= - - hash2 - - Mr9MAjLLumdjs3kpKuEjOL20HLiXJZzLyNsL8wfwMlA= - - - www/css/fonts/pfdintextpro-italic-webfont.woff - - hash - - gtSnNX5Vtd1JOciHX7Q2IGnhYEk= - - hash2 - - DZtjhCJwbqDykQhUD7a2pXF4SuaAPaBDEPgkWudYe+s= - - - www/css/fonts/pfdintextpro-light-webfont.woff - - hash - - 2ZQAPshoOfFBipDEgccDh0IDokQ= - - hash2 - - F+hV+FwInuuHFMLsS4MZD1PdnQzw1vzXQVbCJFwlWsQ= - - - www/css/fonts/pfdintextpro-medium-webfont.woff - - hash - - KyUoyPHWVunK8heDhzHDUKbf1VA= - - hash2 - - zPyc85Aaq/qrdWWmXzB/97AZAv+K3DClUoTfft2s8fE= - - - www/css/fonts/pfdintextpro-regular-webfont.woff - - hash - - zn1xFRXWNWSV7oJEL0mt+0JLjNE= - - hash2 - - BPa4/HL0H3SjK3xPZ8/6nnn1s3soajNDFqHBlhuOJoo= - - - www/css/index.css - - hash - - sS5Z897GbFcFtJaWKk9Ft6T/Vtg= - - hash2 - - qLqkLu+A+Gm5um2jDESMTABAps+BlbF8PY/8VBk4hRs= - - - www/css/nav.css - - hash - - aCFlsZzgMtbv6Z6bkKwkakJFAdo= - - hash2 - - qtRpDWjlUFVBpfJ/bHYPC6ujK5kyXIQzmoEI/5hzj+Q= - - - www/css/products.css - - hash - - 8NxXmll+RoAdH9QSHGDD3UVZps8= - - hash2 - - NfTW2zn/9ToYPcLte6yY2T2nz09Y4aBNC3bM6FoRxy8= - - - www/css/vendor/flickity.css - - hash - - xW5wsn/T/+uaGvIT+Sl9WY/IM2k= - - hash2 - - T95IzwnM3icXTFFGjaoJ60KBvjBZRIGdOLBHp6g1odc= - - - www/img/Resources/CDVNotification.bundle/beep.wav - - hash - - /kSUVvLLJcbtfXnxFEolil3/NRk= - - hash2 - - KfYd4hFlyPwinBGKi4ruYae1MyeQ2TKrPJvIngKdC38= - - - www/img/Resources/splash/Default-568h@2x~iphone.png - - hash - - J8BakinXs4g2c3rjIlkaUKc1m3k= - - hash2 - - uvT5oIiijLZlJapbQ9RysTS/jK0BcBTE5WiVsg7Uy4A= - - - www/img/Resources/splash/Default-667h.png - - hash - - KeM+qh3e57f5eeltxETo6kNL/lk= - - hash2 - - TP25WIPiu3seh7We8uUKVM2XxyNxbYcSOIuPsC2/c8M= - - - www/img/Resources/splash/Default-736h.png - - hash - - 5egepTM4V7rMvBkpkxUc8RAcJaI= - - hash2 - - f0PPi0IKMgqz/hNWp+nerz3Sinndoa+Y3UfQ70+Bpxw= - - - www/img/Resources/splash/Default-Landscape-736h.png - - hash - - OakZWPocy5SHfGOIcwCCOoHVEqA= - - hash2 - - +25+atV9U37SxrS9VG7luxH2gf37etsNY9y41SPmRAg= - - - www/img/Resources/splash/Default-Landscape@2x~ipad.png - - hash - - q8VJZgMwFNZmWGD/Lf1/2KJt42c= - - hash2 - - u/2vuEKdgIS+PhWktUxa01LpDF1+oj0R2alV8U77uoU= - - - www/img/Resources/splash/Default-Landscape~ipad.png - - hash - - PhNiOU4rbDZLXNv3olAhvfd9XQk= - - hash2 - - k1DyhDTDnyEsp5CTBmXGFLb5GPUxtSz7DYuKH9VfPd4= - - - www/img/Resources/splash/Default-Portrait@2x~ipad.png - - hash - - CwZQXSzj9Gai0+MUt1mGzHuYO4U= - - hash2 - - IrqXTW8vE/sSWrxeHHh+ogEUfLLh9S6UAb9O/Cv0mqU= - - - www/img/Resources/splash/Default-Portrait~ipad.png - - hash - - ONniQfICjQTe8yPDO4mhWp9I2pM= - - hash2 - - VOUUyEtLaabk1zWFRoIpVJ2CT4HvyAAwJwP8PXCAoS8= - - - www/img/Resources/splash/Default@2x~iphone.png - - hash - - uMF7RsyJGko7JaycVJ1sdu4hN/A= - - hash2 - - 3M1zeVVJGsu8AbH7VOeCoqVk3NPIi2/P614XXBm4fzw= - - - www/img/Resources/splash/Default~iphone.png - - hash - - btYS0PqHlIXDTLPf+7ZkA8uadDw= - - hash2 - - cNB/ov2CcA7c5BelPGxHt5XRjwMhBMpvF+toOgTsuUE= - - - www/img/angle-down.png - - hash - - I9z7X0QqPVunkk2Pp6QVBfjF/Ug= - - hash2 - - XTqh7PVCqKrR9bHekJv7T1AKLcaV5XqNHsDyip5gOfo= - - - www/img/bottom-fade.png - - hash - - doxZCcQch8Yt0UXMMvPBppxacg0= - - hash2 - - Pff1Ybbi/LcFEr93RMVw5B9TNzY/InXaijmBXgbL8GM= - - - www/img/cart-box.png - - hash - - 76PMCjdfolbYk9wB0iPxqaLwpzk= - - hash2 - - EOY/TzuWeRD2XbpDFRhcadQUenAHRKJYyZZ1OmE9168= - - - www/img/cart-handle.png - - hash - - DIrmugvltD/RB0iy1latRCJGUec= - - hash2 - - CS+LvOUhp2HGJ6bbl2Em+uRul8MWYY+d8Q8O1S4Q/UA= - - - www/img/compass-logo.png - - hash - - hO/U4zzOyjwTppKJ9FKI73NPrGU= - - hash2 - - q+hTZPeR3ZlnfIlbmw3qFgGx3U4+Gqw0lB9A8B1pa+o= - - - www/img/compass-logo.png.old - - hash - - vwVmYayeHMzxccFD/TN328PqiVk= - - hash2 - - dL4FPsLS5KaresAAXchnvd8tLEGbseaQRSFPjwpKD6A= - - - www/img/fade-to-bottom-threshold.gif - - hash - - GR0zpcR8KMByQIz2FFd4chj4bGE= - - hash2 - - EhYFmqatsT26q8SuaY5acyYcyhrxoXVH74n6mqmbkx0= - - - www/img/fade-to-bottom.png - - hash - - doxZCcQch8Yt0UXMMvPBppxacg0= - - hash2 - - Pff1Ybbi/LcFEr93RMVw5B9TNzY/InXaijmBXgbL8GM= - - - www/img/left-arrow.png - - hash - - gJa/2uVfymH2Yxi4/cvGN+OdrWM= - - hash2 - - kxHzwZ36AHmQA6dWhC8QcWWRtHfCDiGSgoU8qx2s67Q= - - - www/img/right-arrow.png - - hash - - MSgmEvsEIKkviNZIWWCPJeKdJqY= - - hash2 - - 8Z+N/wNcrZ61JKyWhtE/lTCOTSB8l8ocMsRlVzjOltc= - - - www/img/small-cart-box.png - - hash - - DJxx7Sxv9HGOumgrHLmIk1YfW7c= - - hash2 - - QCLuWju4XnHojaJKdRIz7mc/W8rzM52K8bN0C+xodhQ= - - - www/img/small-cart-handle.png - - hash - - SlZeorPNUiYlNNv0UCnVXxyNZPc= - - hash2 - - Y0j22p39dCI1uo+wL9lRWYD93TqGGzY05TrYQ2+8mEQ= - - - www/img/small-logo.png - - hash - - FRbH5vLd9Z1i4k0dBsW+I5+g4qo= - - hash2 - - Nf3Hre2AEyspVkhMOs9DjkoxjyPS5Z2A0gLcGxw+bAg= - - - www/img/spinner.gif - - hash - - oEyz0SzCG90twGaMhPwiIjXakkg= - - hash2 - - UxUEYiPRNko3znL6nzrwY2Yb8GLH4ShsrH+my7nsPKU= - - - www/img/wide-logo.png - - hash - - WJ/FbJfrZcN2Pg0w6S5c202hwSs= - - hash2 - - JcHH+opfUENsrDllQYVp4Z803WLSOfIBKRsdqUFeqEg= - - - www/index.html - - hash - - cHaAaJFUHzkRsRxxXUYgbZ7bTU8= - - hash2 - - pJWVHt9kitUzlQntLVRfOSu+Yp/1humRGnrSxdxlqtk= - - - www/js/index.js - - hash - - lHrAnPULXf+uCnPUC5QOpNRZus0= - - hash2 - - pLxUUt5iEZSAwb/vTksmnBQ1o5E2VB8+LZ6VjZEWStI= - - - www/js/lib/_router.js - - hash - - kEgP1UyqTxv0qdxIM4py0YvbGI0= - - hash2 - - bB0wfGhmM3yeutz8u2ZWhynazXNLzvb06Bsk3RR92HE= - - - www/js/lib/account/AccountView.js - - hash - - W2IiMSfOb/ivtxm7golqGg9Dry4= - - hash2 - - NRw3YtnaS3Yin6mORGqZseU+zenMaosM4y/Qf78ARoI= - - - www/js/lib/account/OrdersView.js - - hash - - zEEbcESh8kYxm6fkztCPSUnjOLI= - - hash2 - - I66S9cwl0i9jb3niGM/5/M6lfKdz7nNlVHsKfvgq2TM= - - - www/js/lib/account/PaymentView.js - - hash - - vfzNv1bbaCT//rEXo75q9TiF8Pw= - - hash2 - - L59OgMcnfFnhbhxzDJ4fkqc93HMmGErB3hzEd1rdooo= - - - www/js/lib/account/ProfileView.js - - hash - - DgZUkAEKZ42L8/H/KVc/Q+/dfks= - - hash2 - - rb9Fm9xkT8K7wbz2AHkCQpAqUZgF9jiGenhmzT4u9BM= - - - www/js/lib/account/SettingsView.js - - hash - - 799oolaHYxeTXVS5OVo1GzkT8Vs= - - hash2 - - Q3JS+DOOh7Vq8/4nhcNpUkO2rG+CgO1a06ZD6H6S9Ao= - - - www/js/lib/account/ShippingView.js - - hash - - QpU4sBWoLqQix318vfnMz8Z/vwk= - - hash2 - - 1D2WizU6r/43ioWMkCdyx0fZohrmaiSZiVdi6EoYm6M= - - - www/js/lib/auth/LoginView.js - - hash - - Q8LTQvuQwncpnskoB44zgMeJlbU= - - hash2 - - slXULqRhYnmdAr64jm9kcqpCgR2NO11fq/5VuRHovmU= - - - www/js/lib/auth/LogoutView.js - - hash - - jhf/Pzr8A/yk68t3W15g32q4eQ4= - - hash2 - - WUOCYL3XOiQkxLTopAv/dlhluzFRrJM4HRU9NlkUw4Q= - - - www/js/lib/auth/SignupView.js - - hash - - BW47+iLRQW0R+VvYKbQMpjlMn9Y= - - hash2 - - 06v4K9l3EhWij48wBOlrA5+6BjN36i/hH6kTi/u1BoI= - - - www/js/lib/blogs/ArchiveView.js - - hash - - 0MoYu/cf89T9Yj3/GqkxVS5Kn0s= - - hash2 - - v3axxDFmZxOIUfaVfkbvZECsJNT7TIo2cw8PXjfm2P8= - - - www/js/lib/blogs/BlogView.js - - hash - - v8Sji53Jji6wQl1MUQtgg0B/ML8= - - hash2 - - TleNR88oXPBrIIfxl1ddXJY4TQMOT/zt/qCgMXrEopo= - - - www/js/lib/blogs/HubView.js - - hash - - 6DGehG89PP9aUQaW7PHtwuDnErE= - - hash2 - - rcxtXZd5Z78fUwcnKauYA7t++KokjPQAbZdZXD0+fk0= - - - www/js/lib/blogs/PageView.js - - hash - - fnTO0QKgJ08PPNTrTuT+hgmLtqc= - - hash2 - - VsXsi+sWVrMIqMfJaVbz1F8vRRBCjD2567f9s/CCY0o= - - - www/js/lib/blogs/StoryView.js - - hash - - 0uCBjGnwq8xsO5chZu/C1rGZ/SQ= - - hash2 - - P24JvyHX4Qjfs2Qa+rzt0M9SmSftEC6wuXzTPYoun9k= - - - www/js/lib/cart/CartConfirm.js - - hash - - jqryKPHj843xlpHaPq2On9mfaeM= - - hash2 - - hwM8ywf2UkBfn5K+v8iYkHBdURnsPGGwBs1vX47bskE= - - - www/js/lib/cart/CartError.js - - hash - - AeAnmVjk6HP4fhuICpuG8nHnFuI= - - hash2 - - URcrCrG0fi/wB6NRqqTlI8g3la+JFFbmRBD/LWhctFM= - - - www/js/lib/cart/CartPayment.js - - hash - - rDqDb4NQqfdMi2jqwjRebdL9ZPU= - - hash2 - - 3C4sLz9+RRmlNB5Ueo3TgqP5+6RXM3nDEdNhM38Arko= - - - www/js/lib/cart/CartShipping.js - - hash - - TNWriqY40wM6Yr9PTPmSjNqwxqs= - - hash2 - - iU0S3VtwSIZE+iiMVGbV2S3JaTeL5IswvnE3mKK2HTA= - - - www/js/lib/cart/CartSummary.js - - hash - - YYiOPlDBi/ESvBJZ+bBt5ElQ254= - - hash2 - - ctAGdJM1VwXGTVUdpT9sXBETsIAdWS5Rbl/NGP/Qkic= - - - www/js/lib/cart/CartThanks.js - - hash - - JOo957U9zyzfOkwPIJ7K0oMB5SA= - - hash2 - - l+oEvv8XpnQdQeuTutSxtdQZG0UBvlIjNvo8DtlPdec= - - - www/js/lib/cart/CartView.js - - hash - - +kmEZ9ukx0LiHKArz7oWZyBZr/4= - - hash2 - - FQeeZlPKs/Ma/jhjSRzHRtl4LTWr5JJMQAyutOIbmbo= - - - www/js/lib/etc/backup_db.js - - hash - - BwItWjWxRLRdqFFVUnLyB+Cz/94= - - hash2 - - u+pCXG0dSwwduDnQ1Y6+Q4SUrYXEK7os4mdREe0khzg= - - - www/js/lib/etc/deeplink.js - - hash - - Xjr3J9pMm16R4X4Ez0w2889N4Is= - - hash2 - - dwd1KWvpTJljBVWokg9OGGiAbSMHP2o5wW87A00AXLg= - - - www/js/lib/etc/geo.js - - hash - - xaQ5M8Pao+Ewh6usOyD5UV/49gc= - - hash2 - - oxNHfAVByZZMvhua5IaksimLkMzcuIPc+KfyEM6tQm8= - - - www/js/lib/etc/push.js - - hash - - hfTCoCCPYRemV3DKX6CQdpF9aok= - - hash2 - - pavwSpzpsYuW4ODwhYJB3xWddac+nE0iveMfjCAs3tc= - - - www/js/lib/nav/AddressView.js - - hash - - JFoETIdARQvI5GU6tc1YJhhttEc= - - hash2 - - tlqapPZSqJXPu1tVTEPiqafuJYdHnff/lCfnLeAzXrs= - - - www/js/lib/nav/CreditCardView.js - - hash - - uV1Y5XohZktnJXSKPs/gt/vhlzk= - - hash2 - - kTv/+Lvcpehdpd3a6ZDzFFKSBtfBm5D77mIZwNOusHE= - - - www/js/lib/nav/CurtainView.js - - hash - - VHa9pwxWtQ31RhBknlTCAqrKA7c= - - hash2 - - m1y+MtkztLia5cyx9E5WrAch10YftRlFUZnP0EtrmDs= - - - www/js/lib/nav/FooterView.js - - hash - - WaOKgFizQ3W8RPEhwga57tf3sLM= - - hash2 - - Z2+GeBAj/oHQ6m3AxNvY8tIeLbh2Kv4ScrteiHlFdm8= - - - www/js/lib/nav/HeaderView.js - - hash - - Ui2nti/7MEoaanRA/U1QuO6cVSQ= - - hash2 - - 6lCUODPVbVjct435xG/PZL/QEtmKxzMj702T2xVy5sU= - - - www/js/lib/nav/IntroView.js - - hash - - FSNPuiLwJs4MyLmkvAY6k3RPRF8= - - hash2 - - Ex044mlBP+DCpAFwCDbsYSIAPyFSB8owff1K4+5gNx4= - - - www/js/lib/nav/NavView.js - - hash - - vVy7+c8F2D+3VFixaG8D1GqdHL4= - - hash2 - - GZ1IlXF1CFdDOhLEAbLhaRC7+M6rji5WGXKoyWg0yS8= - - - www/js/lib/nav/SearchView.js - - hash - - b8Xg3rQZIafOl+uBceHrk6yVqYU= - - hash2 - - JDO4vy0leucXMPsoEpMJ2/hXdJ9gIkGmarDk9ev5ZsY= - - - www/js/lib/products/ClosedStoreView.js - - hash - - iDWe+pvx3vGBohpZ05biGudY71o= - - hash2 - - yQ+emjRXzZ9ubsvwSI6Uw3d8Msi7FA1HBrqOKErjK2g= - - - www/js/lib/products/CollectionView.js - - hash - - 4jUFxdjwhpGFj1x4zVhis4hY7Uw= - - hash2 - - LenKnMyS8MSesvN2WsopZD92r5vCiuIz7lN1YJuzX8Y= - - - www/js/lib/products/GalleryView.js - - hash - - CpqSBwnIKxV0wFGD8GdU82L9oqI= - - hash2 - - n3fH37jyJVsN6JkJvkx3OIotptVwo/xM41D0vs6EefY= - - - www/js/lib/products/ProductView.js - - hash - - au2e+E3AV/VQdK0dax41Y7Kzbrw= - - hash2 - - ZQl8BdyDH1mQRWbbx36YwSWVYK3hWqIQAkC+iR44a+c= - - - www/js/lib/products/Selector.js - - hash - - fVQwXy2n+BjjueoUiZNX5I2f//w= - - hash2 - - 3nlb09E7MPpmE2DbNSQ+nnZ8x3O2FZ3Lggk6vEEdV14= - - - www/js/lib/products/filters/CategoryFilter.js - - hash - - z8glR9hNUq3u4RpoKJRCV6oag8o= - - hash2 - - fi59s2GbjQHohiAgsq3FrGeWsxe0gKfBjOnPcCqi69o= - - - www/js/lib/products/filters/DepartmentFilter.js - - hash - - LueAI+hrodiC7/iu987ag8xkACw= - - hash2 - - pp0SDUmq2llYdhp2Fq5JCdXEQDAHQ25r0PjiRgV4PLs= - - - www/js/lib/view/Router.js - - hash - - nC19loTSWgo+YghXIQTdo2qViKw= - - hash2 - - 6Y3/Vpzh9KunOo/v0vAvMT8rf25acj/6OB74XRISu4s= - - - www/js/lib/view/Scrollable.js - - hash - - eUKMRV6KXM82cDq9rFnmFWP4QAQ= - - hash2 - - T2sjPDXHGqpklVYW4nnCST+Tn0iCkrFQok7f+NsAFYQ= - - - www/js/lib/view/Serializable.js - - hash - - 1axFnf92uYJ5GPvZdeKU+zPGLuw= - - hash2 - - IdU+9EOTCaklhVdIzqZGvDbO6IwPkIM/fYhJPYvUEHY= - - - www/js/lib/view/View.js - - hash - - 1vOGv/o4d073vpU6t8Dn08nZsnY= - - hash2 - - DHHSWtioHVLGu5C7QPQdLXBY5ufUvieTSsf2k19yLkw= - - - www/js/sdk/_sdk.js - - hash - - lQSwQ13C2sQbmhoFgz8BMYN/dIk= - - hash2 - - VWOtB3kM2Yzfu02wmbIUahBqI3AZB0W84D/I4sV+7Do= - - - www/js/sdk/account.js - - hash - - iFcyfpZSqqeP8RQ80FNBdRFrjNI= - - hash2 - - 3ENHjzZacCXTS8uC2zYOnkx2MidichrC10T67Ydgop0= - - - www/js/sdk/address.js - - hash - - 58zTcGuj9yQkjVJYaxboOYe+LiI= - - hash2 - - K0b2odCsO18fnoXffNL5d80Bcm3aZdP84y3cRjwDZIE= - - - www/js/sdk/auth.js - - hash - - GeG4SscTJbq+zn8HT+R3CEvfKc4= - - hash2 - - jgGbQWQJRBhW+pPXRBsCfLIjFq2kkhbxyozRRbbeZAI= - - - www/js/sdk/cart.js - - hash - - TWij8pn0/F4YBj04iBZzNX2NyuQ= - - hash2 - - V382WXrermJ4bUwIGFZPVpATsxPPKYP6wGf4eYf9D1M= - - - www/js/sdk/payment.js - - hash - - j3efOwLU577n/V2UAVxVHU/0NB8= - - hash2 - - H1YwKYswGAw+HMPtyd1wps5fQFx3NoXd9sGW7IZbsmU= - - - www/js/sdk/product.js - - hash - - ZYf0fQuZdLIS1ZXTJSingxo32Hs= - - hash2 - - 1pf0iSfyvVwyQgWo2RFIHGyYEGn/8ZszSzJ0MDZ4zNI= - - - www/js/sdk/shipping.js - - hash - - 04qsgSJ7isNdqyVfM1LQ7Q6wRwM= - - hash2 - - 580ij6TiPbA/d/1bB4nVY6ooXNZevcTCExA0YQ9vJxc= - - - www/js/vendor/fastclick.js - - hash - - GsPVekcRLSRd6GYRskvAbulostc= - - hash2 - - ZrSDQkfU6EtN7AI5A0E6m+oQPEubPVStTwGmPXfwGTk= - - - www/js/vendor/flickity.pkgd.js - - hash - - 7+L7DJW+IWJnI8uOkBFuyww3Bk0= - - hash2 - - vF2sYxgNn4r/4NnhBHz/44B9O8nWsxHRUd0Gf1FOK3w= - - - www/js/vendor/iscroll.js - - hash - - zmIJQRtMdsZHuPuHvHEe8K1HC7w= - - hash2 - - 9xQKJ2r3WFI2Tu+IDxNHP9R5FFW6LNZQt0RuZWJ0Kp0= - - - www/js/vendor/jquery-2.1.4.min.js - - hash - - Q9xVRgjfiFpZ3e7OFZjGrOQ010c= - - hash2 - - 8WqyJLuWKRBVhxXIL1jBDD7SDxU936oZkCnxQbWwJVw= - - - www/js/vendor/jquery.creditCardValidator.js - - hash - - Y27vkeRB6sxVVgVnzd82mRHab3g= - - hash2 - - FfTayl3QgyS4UvFgbGlNPSlDtkC28Q3RUhSVQV0CwKg= - - - www/js/vendor/loader.js - - hash - - rX3eSoXrP9KCszh6/7wYgtEAKIE= - - hash2 - - rGlRT+o5G/bTYjy5PSWSl4vl5znuwvBe/eqHeglBaG0= - - - www/js/vendor/lodash.min.js - - hash - - QH5J71GV/YmbKvW8dOzPWmIy2Js= - - hash2 - - v2PESRFA3ocCdVenwVx0H2XIPZgnQ0exBaBqIOBc540= - - - www/js/vendor/moment.js - - hash - - up6xZ/qvAr5h9VNpOTtzN9Jzv6Y= - - hash2 - - 9ZXOLpTlQ1GMKN+vOTmxc+Vm4sRw7L9QDtZ50hJI+sc= - - - www/js/vendor/oktween.js - - hash - - IbqDpG6Qitgu8bvKthKC6hJyb1g= - - hash2 - - 6y0dV3eCnszS6gNMOt5VQ7k92tajbtVRGERxEVEp8No= - - - www/js/vendor/prefixfree.js - - hash - - ImNOjml3qilBB3P2Q+D2oh0XZlo= - - hash2 - - mGlBZZ4/+6zoe8Imph39ztEQhANPhQDDew+fggkgXso= - - - www/js/vendor/promise.js - - hash - - c/6/xZdHlYR9yLjMoxE3Tk2wdgc= - - hash2 - - TPK5MrYxjIfzZUK1ZamFwPo26qfMm+jiEB2C9FoWMRQ= - - - www/js/vendor/util.js - - hash - - awGO8rHbB+UyNdCDbLXrp2nihQg= - - hash2 - - abyzwamkkJLDbsXnk/TE74wXjj9SlJX9kA+53MuezZA= - - - www/plugins/com.parse.cordova.core.pushplugin/www/cdv-plugin-parse.js - - hash - - AJEko/0+djDFCw9vjtZplT91zAQ= - - hash2 - - owecKsEpHPN//bW7iLOfzxFWFXUjNU/MLrP8oMpGYnU= - - - www/plugins/cordova-plugin-console/www/console-via-logger.js - - hash - - NyUkntRl9vFIiOC3onmXNsxpedU= - - hash2 - - cCcOHB0gfKqE6bS4NoAZMvlzcHaWDemJfOWOOw+cI/8= - - - www/plugins/cordova-plugin-console/www/logger.js - - hash - - tmAfmQQR8NZd7y+bTWuju4/TbY0= - - hash2 - - ESzk4H7ypO9esEfCCJl4Sw+BH3M31e0OkRdbsNe0Wcc= - - - www/plugins/cordova-plugin-customurlscheme/www/ios/LaunchMyApp.js - - hash - - 0NrlXTwBHUS5u9XaqkoSJ+waVDo= - - hash2 - - SbvHr9WKyz3ru8I7xjp3L/R4cE0LwxQb91YQEXPQIi4= - - - www/plugins/cordova-plugin-device/www/device.js - - hash - - DgD9WKGqlbNViEZBSi4Wenbl/uM= - - hash2 - - 75fkIus2+MF7kZSUTo0HFvPQWqyneMrHDoQXHcvK/fk= - - - www/plugins/cordova-plugin-dialogs/www/notification.js - - hash - - 7DTImwpj5B7VCelKiHdmmFLX6h0= - - hash2 - - OY9J4siJjz0x+SKUjBVqdprLf2olxAVAx0TuQi2zSHg= - - - www/plugins/cordova-plugin-geolocation/www/Coordinates.js - - hash - - B+vlNAwNL/8E91a2w8xN/QZtP9o= - - hash2 - - OMLyPkrlZ2a8QPIWTLVOYtPW/6JKdiOvR5V4pO/Covs= - - - www/plugins/cordova-plugin-geolocation/www/Position.js - - hash - - 1DZ/xrP/zFT+anCeCYYt+uuQIyU= - - hash2 - - bajmSfpMjHjoSzrL1TPI1J8K3SrZyVFPoU11T0if/Y8= - - - www/plugins/cordova-plugin-geolocation/www/PositionError.js - - hash - - NZQ0MpOiURNiYMJS79+bdtSDnzI= - - hash2 - - W7UeIudqey1Q4CAafAS1HMHib9BAeyvfD0Kj20Dx0m0= - - - www/plugins/cordova-plugin-geolocation/www/geolocation.js - - hash - - DBMSf1DRKjXfKMDgaSJHjnx+wgI= - - hash2 - - c0FvNwJUoj6DTFiJbDJ//4pUO/Nc0Pmmq+lh9eVocuE= - - - www/plugins/cordova-plugin-inappbrowser/www/inappbrowser.js - - hash - - EfUzmAcUagDDJeG2yHQTy4FngxU= - - hash2 - - CKuxAFfWQy3W36zfMt2eAc22BRQLnyWoCbuM+jlEBuk= - - - www/plugins/cordova-plugin-network-information/www/Connection.js - - hash - - QP5YzumNbUCPIZ96Xkpu5RegRY0= - - hash2 - - e+LNrLCJeaza8OmeupCA7JOSHM6BaBjmEt95Z5DDRZo= - - - www/plugins/cordova-plugin-network-information/www/network.js - - hash - - jxeuXL/JPk6C5eQC7iVThLg7NPc= - - hash2 - - 6BrhkQ/LskQvmM1rbhciH8KThNK7PeYwvje9PZsZIro= - - - www/plugins/cordova-plugin-splashscreen/www/splashscreen.js - - hash - - n2E0W8B/grOxM2ORx/haAYOWIcA= - - hash2 - - YSn19P0zRIG9MxdesT37iqYB1WqXVOFIXyjmnTn6foU= - - - www/plugins/cordova-plugin-x-socialsharing/www/SocialSharing.js - - hash - - p2ovf3IcCK49/GvqK+j7UmFu1zI= - - hash2 - - vaAJBb/wNtJKRgYT7sxU/Sv+fqB5bfWIw3SyBSUukCI= - - - www/plugins/ionic-plugin-keyboard/www/ios/keyboard.js - - hash - - gexyZjGUVvhbQiJbBzCrImXWv34= - - hash2 - - s8oy4VvWgJx67mjrcY9CWo7fZ0VqTuZEyLnykDMBTXs= - - - - rules - - ^ - - ^.*\.lproj/ - - optional - - weight - 1000 - - ^.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^ - - weight - 20 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^.*\.lproj/ - - optional - - weight - 1000 - - ^.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Base\.lproj/ - - weight - 1010 - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/archived-expanded-entitlements.xcent b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/archived-expanded-entitlements.xcent deleted file mode 100644 index 0c67376e..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/archived-expanded-entitlements.xcent +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/config.xml b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/config.xml deleted file mode 100755 index 0a31a9b5..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/config.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Stone Island - - Stone Island - - - OKFocus - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/embedded.mobileprovision b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/embedded.mobileprovision deleted file mode 100644 index 275b8509..00000000 Binary files a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/embedded.mobileprovision and /dev/null differ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/exec.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/exec.js deleted file mode 100644 index 3fb7fa19..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/exec.js +++ /dev/null @@ -1,262 +0,0 @@ -/* - * - * 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; diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/platform.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/platform.js deleted file mode 100644 index 36529ba5..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova-js-src/platform.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * 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() { - require('cordova/channel').onNativeReady.fire(); - } -}; - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova.js deleted file mode 100644 index 29be9099..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/cordova.js +++ /dev/null @@ -1,1938 +0,0 @@ -// Platform: ios -// a3732cb71d9b1dd590338e8cf44196f366d46da3 -/* - 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.3.1'; -// file: src/scripts/require.js - -/*jshint -W079 */ -/*jshint -W020 */ - -var require, - define; - -(function () { - var modules = {}, - // Stack of moduleIds currently being built. - requireStack = [], - // Map of module ID -> index into requireStack of modules currently being built. - inProgressModules = {}, - SEPARATOR = "."; - - - - function build(module) { - var factory = module.factory, - localRequire = function (id) { - var resultantId = id; - //Its a relative path, so lop off the last portion and add the id (minus "./") - if (id.charAt(0) === ".") { - resultantId = module.id.slice(0, module.id.lastIndexOf(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)) { - 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 = {}, - 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; -} - - -var cordova = { - define:define, - require:require, - version:PLATFORM_VERSION_BUILD_LABEL, - platformVersion:PLATFORM_VERSION_BUILD_LABEL, - platformId:platform.id, - /** - * Methods to add/remove your own addEventListener hijacking on document + window. - */ - addWindowEventHandler:function(event) { - return (windowEventHandlers[event] = channel.create(event)); - }, - addStickyDocumentEventHandler:function(event) { - return (documentEventHandlers[event] = channel.createSticky(event)); - }, - addDocumentEventHandler:function(event) { - return (documentEventHandlers[event] = channel.create(event)); - }, - removeWindowEventHandler:function(event) { - delete windowEventHandlers[event]; - }, - removeDocumentEventHandler:function(event) { - delete documentEventHandlers[event]; - }, - /** - * Retrieve original event handlers that were replaced by Cordova - * - * @return object - */ - getOriginalHandlers: function() { - return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener}, - 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}}; - }, - /** - * Method to fire event from native code - * bNoDetach is required for events which cause an exception which needs to be caught in native code - */ - fireDocumentEvent: function(type, data, bNoDetach) { - var evt = createEvent(type, data); - if (typeof documentEventHandlers[type] != 'undefined') { - if( bNoDetach ) { - documentEventHandlers[type].fire(evt); - } - else { - setTimeout(function() { - // Fire deviceready on listeners that were registered before cordova.js was loaded. - if (type == 'deviceready') { - document.dispatchEvent(evt); - } - documentEventHandlers[type].fire(evt); - }, 0); - } - } else { - document.dispatchEvent(evt); - } - }, - fireWindowEvent: function(type, data) { - var evt = createEvent(type,data); - if (typeof windowEventHandlers[type] != 'undefined') { - setTimeout(function() { - windowEventHandlers[type].fire(evt); - }, 0); - } else { - window.dispatchEvent(evt); - } - }, - - /** - * Plugin callback mechanism. - */ - // Randomize the starting callbackId to avoid collisions after refreshing or navigating. - // This way, it's very unlikely that any new callback would get the same callbackId as an old callback. - callbackId: Math.floor(Math.random() * 2000000000), - callbacks: {}, - callbackStatus: { - NO_RESULT: 0, - OK: 1, - CLASS_NOT_FOUND_EXCEPTION: 2, - ILLEGAL_ACCESS_EXCEPTION: 3, - INSTANTIATION_EXCEPTION: 4, - MALFORMED_URL_EXCEPTION: 5, - IO_EXCEPTION: 6, - INVALID_ACTION: 7, - JSON_EXCEPTION: 8, - ERROR: 9 - }, - - /** - * Called by native code when returning successful result from an action. - */ - callbackSuccess: function(callbackId, args) { - 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), - cUpper = c.toUpperCase(), - arg = args[i]; - // Asterix means allow anything. - if (c == '*') { - continue; - } - typeName = utils.typeName(arg); - if ((arg === null || arg === undefined) && c == cUpper) { - continue; - } - if (typeName != typeMap[cUpper]) { - errMsg = 'Expected ' + typeMap[cUpper]; - break; - } - } - if (errMsg) { - errMsg += ', but got ' + typeName + '.'; - errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg; - // Don't log when running unit tests. - if (typeof jasmine == 'undefined') { - console.error(errMsg); - } - throw TypeError(errMsg); - } -} - -function getValue(value, defaultValue) { - return value === undefined ? defaultValue : value; -} - -moduleExports.checkArgs = checkArgs; -moduleExports.getValue = getValue; -moduleExports.enableChecks = true; - - -}); - -// file: 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) : new Buffer(str,'base64').toString('binary'); - 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> 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'), - 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; -}, - channel = { - /** - * Calls the provided function only after all of the channels specified - * have been fired. All channels must be sticky channels. - */ - join: function(h, c) { - var len = c.length, - i = len, - f = function() { - if (!(--i)) h(); - }; - for (var j=0; jNative 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'), - moduleMap = define.moduleMap, - symbolList, - deprecationMap; - -exports.reset = function() { - symbolList = []; - deprecationMap = {}; -}; - -function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) { - if (!(moduleName in moduleMap)) { - throw new Error('Module ' + moduleName + ' does not exist.'); - } - symbolList.push(strategy, moduleName, symbolPath); - if (opt_deprecationMessage) { - deprecationMap[symbolPath] = opt_deprecationMessage; - } -} - -// Note: Android 2.3 does have Function.bind(). -exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) { - addEntry('c', moduleName, symbolPath, opt_deprecationMessage); -}; - -exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) { - addEntry('m', moduleName, symbolPath, opt_deprecationMessage); -}; - -exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) { - addEntry('d', moduleName, symbolPath, opt_deprecationMessage); -}; - -exports.runs = function(moduleName) { - addEntry('r', moduleName, null); -}; - -function prepareNamespace(symbolPath, context) { - if (!symbolPath) { - return context; - } - var parts = symbolPath.split('.'); - var cur = context; - for (var i = 0, part; part = parts[i]; ++i) { - cur = cur[part] = cur[part] || {}; - } - return cur; -} - -exports.mapModules = function(context) { - var origSymbols = {}; - context.CDV_origSymbols = origSymbols; - for (var i = 0, len = symbolList.length; i < len; i += 3) { - var strategy = symbolList[i]; - var moduleName = symbolList[i + 1]; - var module = require(moduleName); - // - 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'), - symbolList = [], - 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) { - 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); - // - 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/shazron/Documents/git/apache/cordova-ios/cordova-js-src/platform.js -define("cordova/platform", function(require, exports, module) { - -module.exports = { - id: 'ios', - bootstrap: function() { - require('cordova/channel').onNativeReady.fire(); - } -}; - - -}); - -// file: src/common/pluginloader.js -define("cordova/pluginloader", function(require, exports, module) { - -var modulemapper = require('cordova/modulemapper'); -var urlutil = require('cordova/urlutil'); - -// Helper function to inject a - - - - -
-
-

HUB

-
- -
-
-
-
- -
-
-
- - - -
-
- -
-

ARCHIVE

-
'982'015
-
-
- -
-
-

PRIVACY POLICY

-
-
-
-
-
-

TERMS AND CONDITIONS

-
-
-
-
-
-

RETURN POLICY

-
-
-
-
-
-

CUSTOMER CARE

-
-
-
- - - - -
-
-

LOADING...

-
-
- -
-
-
- - - -
-
-
- - - -
-
- - -
-
- - -
-
- -
- - -
-
- -
-
Fits Large
-
-
-
- Sizing: The products of this collaboration fit slightly larger than the classic Stone Island garments. -

- We suggest you choose a smaller size than yours. -
-
-
-
- -
-
-

- THIS STORE IS CURRENTLY CLOSED -

-

- WE WILL REOPEN FEBRUARY 1ST -

- -
-
- - - - -
-
-

LOGIN

-
-
-
- - -
-
-
-
New User?
-
Forgot Password?
-
-
- -
-
-
-
-
-
- -
-
-

LOGOUT

-
-
- - You are now logged out. - -
-
-
-
- -
-
-

NEW USER

-
-
-
- - - - -
- BIRTHDAY (MM/DD/YYYY) - -
- -

PASSWORD

- - -
- -
-
-
-
- - -
- -
-
-
- - -
- -
-
- Consult our PRIVACY POLICY for further information. -
-
-
-
-
-
-
- -
-
-

PROFILE

-
-
-
- - - -
- BIRTHDAY (MM/DD/YYYY) - -
- -

CHANGE PASSWORD

- - -
-
- - -
-
-
-
-
-
- - -
- -
-
-
- - -
- -
-
- Consult our PRIVACY POLICY for further information. -
-
-
-
-
-
-
-
- - -
-
-

SHIPPING

-
-
-
-
-
-
-
- - * Your personal and payment
- information will always remain private -
-
-
-
-
-
-
- -
-
-

PAYMENT

-
-
-
-
-
-
-
-
- - * Your personal and payment
- information will always remain private -
-
-
-
-
-
-
- -
-
-

NOTIFICATIONS

-
-
-
-
-

Store

- Receive notifications for Store -
-
- - -
-
-
-
-

Hub

- Receive notifications for Hub -
-
- - -
-
-
-
-
-
- -
-
-

ORDERS

-
-
-
You have no orders.
- -
- -
-
-

ORDER SUMMARY

- -
- -
-
-
- SUB TOTAL - -
-
- ESTIMATED SHIPPING & HANDLING - -
-
- TAX - -
-
- TOTAL - -
-
-
- -
-

SHIP TO

-
-
-
-
-
- -
-
-
- - - -
-

- - YOUR CART / - - - YOUR CART IS EMPTY - -

- -
- SUMMARY - SHIPPING - BILLING -
- -
-
-
-
-
-
- -
-
-
- SUB TOTAL - -
-
- ESTIMATED SHIPPING
& HANDLING
- -
-
- TAX - -
-
- TOTAL - -
-
-
-
-
-
- You have nothing in your cart. -
-
-
-
-
- -
-
-
- -
- -
-
- -

SHIPPING METHOD

- -
-
-
- - -
- -
-
-
- - -
- -
-
- -
-
-
- - * Your personal and payment
- information will always remain private -
-
-
-
- -
-
-
- -
-
-
- -
-
- -
-
-
- - -
- -
-
- -
- - -
- -
- -
- -
- - - -
- -
- -
- -
-

PLEASE ENTER YOUR SECURITY CODE TO CONFIRM

- -
-
- -
-
- - * Your personal and payment
- information will always remain private -
-
-
-
-



- -
-
-
- -
-
-

CONFIRM

- -
-

ORDER SUMMARY

- -
- -
-
-
- SUB TOTAL - -
-
- ESTIMATED SHIPPING
& HANDLING
- -
-
- TAX - -
-
- TOTAL - -
-
-
- -
-

SHIP TO

- -
-
-
- -
-

BILL TO

- -
-
-
- -
-
- -
-
- THANK YOU -

- Please check your inbox for your confirmation email. -

-
-
- -
-
- WE'RE SORRY -

-
-
- -
- -
-
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/index.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/index.js deleted file mode 100755 index 76a8af05..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/index.js +++ /dev/null @@ -1,135 +0,0 @@ -var app = (function(){ - var app = {} - - app.init = function(){ - console.log("init") - - sdk.init({ env: "production" }) - - app.bind() - app.build() - - app.iscroll_options = { - mouseWheel: true, - scrollbars: true, - } - - if (window.cordova) { - document.addEventListener('deviceready', app.ready, false) - } - else { - app.ready() - } - } - - app.bind = function(){ - document.addEventListener('touchmove', function(e){ e.preventDefault() }) - FastClick.attach(document.body) - } - - app.build = function(){ - app.blog = new BlogView () - app.archive = new ArchiveView () - app.hub = new HubView () - app.story = new StoryView () - app.cart = new CartView () - - app.intro = new IntroView () - app.header = new HeaderView () - app.footer = new FooterView () - app.curtain = new CurtainView () - app.nav = new NavView () - - app.account = new AccountView () - app.login = new LoginView () - app.logout = new LogoutView () - app.signup = new SignupView () - app.profile = new ProfileView () - app.payment = new PaymentView () - app.shipping = new ShippingView () - app.settings = new SettingsView () - app.orders = new OrdersView () - - app.terms = new PageView ({ page: "terms" }) - app.privacy = new PageView ({ page: "privacy" }) - app.returns = new PageView ({ page: "returns" }) - app.care = new PageView ({ page: "care" }) - - app.collection = new CollectionView () - app.product = new ProductView () - app.closed = new ClosedStoreView () - app.search = new SearchView () - - app.selector = new Selector () - } - - app.ready = function(){ - console.log(">> READY") - if (window.cordova) { - document.addEventListener('pause', app.paused, false) - document.addEventListener('resume', app.resumed, false) - document.addEventListener('online', app.online, false) - document.addEventListener('offline', app.offline, false) - cordova.plugins.Keyboard.disableScroll(true) - geo.fetch() - var image = new Image - image.src = "./img/compass-logo.png" - } - - app.view = null - app.router = new SiteRouter () - -// if (sdk.env == "test") { -// app.router.launch() -// } -// else { -// } - - if (navigator.onLine) { - app.account.connect() - app.blog.fetch(function(){ - app.router.initial_route = "/intro" - app.router.launch() - }) - } - else { - console.log(">> LAUNCHED WHILE OFFLINE") - app.router.go("intro") - app.finished_launching() - } - - push.init() - } - - app.finished_launching = function(){ - console.log(">> FINISHED LAUNCHING") - if (window.cordova) { - navigator.splashscreen.hide() - } - $("body").removeClass("loading") - } - - var refresh_time = +Date.now() - app.paused = function(){} - app.resumed = function(){ - console.log( "app is ready?", app.is_ready ) - - geo.fetch() - var now = +Date.now() - if (now - refresh_time > 60 * 60 * 1000) { - refresh_time = now - app.blog.refresh() - } - } - - app.online = function(){ - console.log(">> ONLINE") - } - app.offline = function(){ - console.log(">> OFFLINE") - } - - return app -})() - -app.init() diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/_router.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/_router.js deleted file mode 100755 index 9927712a..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/_router.js +++ /dev/null @@ -1,107 +0,0 @@ -var SiteRouter = Router.extend({ - - el: 'body', - routeByHash: true, - - routes: { - '/': 'intro', - '/intro': 'intro', - '/hub': 'hub', - '/story': 'story', - '/archive': 'archive', - - '/store': 'collection', - '/store/closed': 'closed', - '/store/:code': 'product', - - '/account/login': 'login', - '/account/logout': 'logout', - '/account/signup': 'signup', - '/account/profile': 'profile', - '/account/payment': 'payment', - '/account/shipping': 'shipping', - '/account/orders': 'orders', - '/account/settings': 'settings', - - '/page/terms': 'terms', - '/page/privacy': 'privacy', - '/page/returns': 'returns', - '/page/care': 'care', - - '/search': 'search', - - '/cart': 'cart.summary', - '/cart/summary': 'cart.summary', - '/cart/payment': 'cart.payment', - '/cart/shipping': 'cart.shipping', - '/cart/confirm': 'cart.confirm', - '/cart/thanks': 'cart.thanks', - '/cart/error': 'cart.error', - }, - - initialize: function(){ - var fn - for (var route in this.routes) { - fn = this.routes[route] - if (! this[fn]) { - this[fn] = this.default_view(fn) - } - } - }, - - initial_route: null, - launch: function(){ - if (this.initial_route) { - this.parseRoute( this.initial_route ) - } - else { - this.route() - } - this.initial_route = null - - app.finished_launching() - }, - - go: function(url){ - if (app.view && app.view.hide) { - app.view.hide() - } - window.location.href = "#/" + url - this.parseRoute(url) - }, - - default_view: function(name){ - var fn = function(){ - console.log(name) - if (app.view != app.login && app.view != app.signin) { - app.last_view = app.view - } - if (app.view && app.view.hide) { - app.view.hide() - } - if (name.match(/\./)) { - var n = name.split(".") - console.log(name, n) - app.view = app[n[0]][n[1]] - } - else { - app.view = app[name] - } - app.header.set_back( !! app.view.back ) - app.view.show() - }.bind(this) - return fn - }, - - product: function(code){ - if (app.view && app.view.hide) { - app.view.hide() - } - app.view = app.product - app.header.set_back( true ) - app.product.load(code) - app.product.show() - }, - -}) - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/AccountView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/AccountView.js deleted file mode 100755 index 9e6f1714..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/AccountView.js +++ /dev/null @@ -1,161 +0,0 @@ -var AccountView = View.extend({ - - initialize: function(){ - }, - - connect: function(cb){ - auth.init(this.ready.bind(this, cb)) - }, - - ready: function(cb){ - if (auth.logged_in()) { - this.logged_in(cb) - } - else { - this.logged_out(cb) - } - }, - - addresses: [], - addressLookup: {}, - ccs: [], - ccLookup: {}, - - listAddresses: function(opt){ - sdk.address.list({ - success: function(data){ - this.populateAddresses(data, opt.success) - }.bind(this), - error: function(data){ - console.log("error listing addresses!") - console.log(data.responseText) - opt.error && opt.error() - }.bind(this), - }) - }, - - populateAddresses: function(data, cb){ - console.log("populate addresses:", data.AddressBook.addressBookItem) - - if (! data.AddressBook) { - console.log("no addresses") - cb && cb() - return - } - - this.addresses = data.AddressBook.addressBookItem - this.addressLookup = {} - data.AddressBook.addressBookItem.forEach(function(item){ - this.addressLookup[ item.Id ] = item - if (item.IsDefault) { - console.log("SHIPPING ADDRESS", item) - app.shipping.populate(item) - } - if (item.IsBillingDefault) { - console.log("BILLING ADDRESS") - app.payment.populate(item) - } - }.bind(this)) - - app.cart.shipping.populate() - app.cart.payment.populate() - - cb && cb() - }, - - listCreditCards: function(cb){ - sdk.payment.list_credit_cards({ - success: function(data){ - this.populateCreditCards(data, cb) - }.bind(this) - }) - }, - - populateCreditCards: function(data, cb){ - console.log("populate ccs:", data.CreditCards) - this.ccs = data.CreditCards - this.ccLookup = {} - if (! data.CreditCards || ! data.CreditCards.length) { - } - else { - data.CreditCards.forEach(function(cc){ - this.ccLookup[cc.Id] = cc - }.bind(this)) - app.payment.populate( data.CreditCards[0] ) - app.cart.payment.populate() - } - cb && cb() - }, - - logged_in: function(cb){ - this.listAddresses() - this.listCreditCards() - $("#nav .login").hide() - $("#nav .account, #nav .logout").show() - if (! auth.deferred_product && app.last_view) { - if (app.last_view != app.login && app.last_view != app.signin && app.last_view != app.logout) { - app.view && app.view.hide && app.view.hide() - app.view = app.last_view - app.view.show() - } - } - else { - cb && cb() - } - if ( ! auth.has_cart() ) { - app.curtain.show("loading") - auth.create_cart({ - success: function(){ - if (auth.deferred_product) { - auth.add_deferred_product_to_cart({ - success: function(){ - app.router.go("cart") - setTimeout(function(){ - app.curtain.hide("loading") - }, 500) - }, - error: function(){ - // TODO: should not be called because cart was just created - console.log("ERROR ADDING PRODUCT TO NEW CART") - }, - }) - } - else { - app.router.go("account/profile") - app.curtain.hide("loading") - } - }, - error: function(){ - // error CREATING cart... - console.log("ERROR CREATING CART") - auth.log_out() - app.account.logged_out() - }, - }) - } - else { - if (auth.deferred_product) { - auth.add_deferred_product_to_cart({ - success: function(){ - app.router.go("cart") - }, - error: function(){ - // TODO: cart might be invalid.. - console.log("CALLED LOGGED_IN, HAD DEFERRED PRODUCT") - }, - }) - } - else { - app.cart.load() - } - } - }, - - logged_out: function(cb){ - $("#nav .login").show() - $("#nav .account, #nav .logout").hide() - $("#nav").removeClass("account") - cb && cb() - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/OrdersView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/OrdersView.js deleted file mode 100755 index b3ff3e7a..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/OrdersView.js +++ /dev/null @@ -1,194 +0,0 @@ -var OrdersView = ScrollableView.extend({ - - el: "#orders", - - loaded: false, - - list_template: $("#orders .list_template").html(), - item_template: $("#orders .item_template").html(), - - events: { - "click .back": "back", - "click .item": "load_single", - }, - - initialize: function(){ - this.$list = this.$(".list") - this.$empty = this.$(".empty") - this.$single_order = this.$("#single_order") - - this.$rows = this.$(".rows") - this.$subtotal = this.$(".subtotal") - this.$shipping = this.$(".shipping") - this.$tax = this.$(".tax") - this.$total = this.$(".total") - - this.$shipping_address = this.$(".shipping_address") - this.$shipping_method = this.$(".shipping_method") - - this.scroller = new IScroll('#orders', app.iscroll_options) - }, - - show: function(){ - if (! auth.logged_in()) { return app.router.go("intro") } - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO VIEW
YOUR ORDERS.", "") - return - } - app.header.set_back(false) - app.footer.hide() - document.body.className = "orders" - this.deferScrollToTop() - this.el.className = "" - - if (this.loaded) { - this.populate() - } - else { - this.fetch() - } - }, - - orders: null, - orderLookup: {}, - - fetch: function(){ - this.$list.empty() - this.$empty.hide() - this.loader = new Loader(this.ready.bind(this)) - app.curtain.show("loading") - sdk.account.fetch_orders({ - success: function(data){ - this.loader.register("orders") - this.orders = data.OrderDetails - data.OrderDetails.forEach(function(row){ - this.loader.register(row.OrderNumber) - sdk.account.fetch_single_order({ - id: row.OrderNumber, - success: function(row_data){ - this.orderLookup[ row.OrderNumber ] = row_data.OrderFullDetails - this.loader.ready(row.OrderNumber) - }.bind(this), - error: function(){ - this.orderLookup[ row.OrderNumber ] = null - this.loader.ready(row.OrderNumber) - }.bind(this), - }) - }.bind(this)) - this.loader.ready("orders") - }.bind(this), - error: function(){ - console.log("error fetching orders") - }.bind(this), - }) - }, - - ready: function(){ - this.populate() - app.curtain.hide("loading") - }, - - populate: function(){ - this.$list.empty() - - if (! this.orders.length) { - this.$empty.show() - return - } - else { - this.$empty.hide() - } - this.orders.forEach(function(row){ - var order = this.orderLookup[ row.OrderNumber ] - if (! order) { return } - var t = this.list_template.replace(/{{date}}/g, moment(order['Date']).format("ddd MM/DD/YYYY").toUpperCase()) - .replace(/{{id}}/g, row.OrderNumber) - .replace(/{{total}}/g, as_cash( order.TotalAmount )) - var $t = $(t), $images = $t.find(".images") - order.Items.forEach(function(item){ - var img = new Image () - img.src = sdk.image(item['Code10'], "11_f") - $images.append(img) - }.bind(this)) - this.$list.append($t) - }.bind(this)) - - this.refreshScroller() - }, - - load_single: function(e){ - var id = $(e.currentTarget).data("id") - var order = this.orderLookup[ id ] - if (! order) { return } - - console.log(order) - - this.$rows.empty() - - order.Items.forEach(function(item){ - var $el = $("
") - this.$rows.append($el) - var code_ten = item.Code10 - - var code = code_ten.substr(0, 8) - app.product.find(code, function(data, details){ - var descriptions = app.product.get_descriptions( details ) - - var name_partz = descriptions['ModelNames'].split(' ') - var num = name_partz.shift() - var title = name_partz.join(' ') - var type = title_case( descriptions['MicroCategory'] ) - - var color_name, size_name - - details.Item.ModelColors.some(function(color){ - if (color['Code10'] == code_ten) { - color_name = color['ColorDescription'] - return true - } - return false - }) - size_name = item.DefaultSize + " " + item.DefaultSizeClassFamily - - var t = this.item_template - .replace(/{{image}}/, sdk.image(item['Code10'], '11_f')) - .replace(/{{sku}}/, num) - .replace(/{{title}}/, title) - .replace(/{{type}}/, type) - .replace(/{{size}}/, size_name || "DEFAULT") - .replace(/{{color}}/, color_name || "DEFAULT") - .replace(/{{quantity}}/, 1) - .replace(/{{price}}/, as_cash(details.Item.Price.DiscountedPrice)) - $el.data("price", details.Item.Price.DiscountedPrice) - $el.html(t) - this.refreshScroller() - }.bind(this)) - }.bind(this)) - - var subtotal = order.ItemsTotalAmount - var shipping_cost = order.Delivery.Amount - var tax = order.SalesTaxAmount - var total = order.TotalToPay - - this.$subtotal.html( as_cash(subtotal) ) - this.$shipping.html( as_cash(shipping_cost) ) - this.$tax.html( as_cash(tax) ) - this.$total.html( as_cash(total) ) - - var street = order.Delivery.Address.replace(/\n$/,"").replace("\n","
") - var address = order.Delivery.Name + "
" + street + "
" + order.Delivery.City + " " + order.Delivery.ZipCode - this.$shipping_address.html(address) - this.$shipping_method.html(order.Delivery.Type + " - " + order.Delivery.Time) - - app.header.set_back(true) - this.$el.addClass("single") - }, - - back: function(){ - app.header.set_back(false) - this.el.className = "" - }, - -}) - diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/PaymentView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/PaymentView.js deleted file mode 100755 index f773c05b..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/PaymentView.js +++ /dev/null @@ -1,126 +0,0 @@ -var PaymentView = FormView.extend({ - - el: "#payment", - - action: sdk.payment.add_credit_card, - - events: { - }, - - test_data: { - "Name":"Name", - "Surname":"Surname", - "Address1":"address", - "Address2":"address2", - "City":"Ferrara", - "Province":"NY", - "HolderIsoCountry":"IT", - "CreditCardCountry": "US", - "ZipCode":"40200", - "Type":"Visa", - "Number":"4111111111111111", - "ExpirationMonth":"09", - "ExpirationYear":"2017", - "Cvv":"1233", - }, - - initialize: function(){ - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.address = new AddressView ({ parent: this, checkPhone: false }) - this.cc = new CreditCardView ({ parent: this }) - this.scroller = new IScroll('#payment', app.iscroll_options) - }, - - show: function(){ - if (! auth.logged_in()) { return app.router.go("intro") } - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO CHANGE
YOUR PAYMENT INFO.", "") - return - } - app.footer.show("SAVE") - document.body.className = "payment" - this.deferScrollToTop() - // this.preload() - }, - - populate: function(data){ - this.data = data || this.data - this.address.populate(data) - this.cc.populate(data) - }, - - finalize: function(data){ - if (this.cc.data && this.cc.data.Guid) { - sdk.payment.delete_credit_card({ - guid: this.cc.data.Guid, - success: function(){ console.log("deleted credit card") }, - error: function(){ console.log("error deleting credit card") }, - }) - } - - data.IsDefault = "true" // this.$isDefault.prop("checked") ? "true" : "false" - data.UserId = sdk.auth.user_id - data.HolderIsoCountry = "US" - data.CreditCardNumber = data.Number - data.IsPreferred = "true" - - console.log(data) - return data - }, - - success: function(data){ - app.curtain.show("loading") - app.account.listAddresses({ - success: function(){ - app.curtain.hide("loading") - }, - error: function(){ - app.curtain.hide("loading") - }, - }) - }, - - error: function(data){ - console.log("ERROR WITH PAYMENT") - console.log(data) - }, - - cancel: function(){ - app.router.go("intro") - }, - -}) - -/* - var new_card = { - "Name":"Name", - "Surname":"Surname", - "Address":"address", - "City":"Ferrara", - "Province":"FE", - "HolderIsoCountry":"IT", - "ZipCode":"40200", - "Type":"Visa", - "Number":"0000567890124285", - "ExpirationMonth":"02", - "ExpirationYear":"2017", - } - promise(sdk.payment.add_credit_card, { data: new_card }).then(function(data){ - last_guid = data['CreditCard']['Guid'] - assert(data.Header.StatusCode == 201) - assert(!! last_guid) - done() - }) - - promise(sdk.payment.list_credit_cards, { data: {} }).then(function(data){ - assert(data.Header.StatusCode == 201) - console.log(data) - done() - }) - - promise(sdk.payment.delete_credit_card, { guid: last_guid }).then(function(data){ - assert(data.Header.StatusCode == 200) - done() -*/ \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ProfileView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ProfileView.js deleted file mode 100755 index df6bc865..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ProfileView.js +++ /dev/null @@ -1,103 +0,0 @@ -var ProfileView = FormView.extend({ - - el: "#profile", - - events: { - }, - - action: sdk.account.update, - - initialize: function(){ - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.scroller = new IScroll('#profile', app.iscroll_options) - }, - - show: function(){ - if (! auth.logged_in()) { return app.router.go("intro") } - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO
EDIT YOUR PROFILE.", "") - return - } - app.footer.show("SAVE") - document.body.className = "profile" - if (auth.user.BirthDay.match(/T/)) { - auth.user.BirthDay = auth.user.BirthDay.split("T")[0] - } - if (auth.user.name && ! auth.user.Name) { - auth.user.Name = auth.user.name - } - if (auth.user.surname && ! auth.user.Surname) { - auth.user.Surname = auth.user.surname - } - if (auth.user.email && ! auth.user.Email) { - auth.user.Email = auth.user.email - } - console.log(auth.user) - this.preload(auth.user) - this.deferScrollToTop() - }, - - validate_presence: { - "Name": "Please enter your first name.", - "Surname": "Please enter your last name.", - "Email": "Please enter a valid email address.", - }, - - validate_fields: function(data, errors){ - if (! data.Email.match("@")) { errors.push([ "Email", "Email address is not valid." ]) } - if (! data.CurrentPassword && (data.NewPassword || data.Email !== auth.user.Email)) { errors.push([ "CurrentPassword", "Please enter your current password." ]) } - if (data.CurrentPassword && ! data.NewPassword) { errors.push([ "NewPassword", "Please enter your new password." ]) } - if (data.NewPassword && data.NewPassword.length < 7) { errors.push([ "CurrentPassword", "New password must be 7 characters or more." ]) } - // if (data.Gender === "NONE") { errors.push([ "Gender", "Please supply your gender." ]) } - }, - - finalize: function(data){ - if (data.CurrentPassword && (data.NewPassword || data.Email !== auth.user.Email)) { - data.NewPassword = data.NewPassword || data.CurrentPassword - data.NewEmail = data.NewEmail || auth.user.Email - - sdk.account.update_mail_and_password({ - data: { - Password: data.CurrentPassword, - NewPassword: data.NewPassword || data.CurrentPassword, - Email: auth.user, - NewEmail: data.NewEmail || auth.user.Email, - }, - success: function(){ console.log("updated password") }, - error: function(){ console.log("error updating password") }, - }) - } - - var submissible_data = _.pick(data, "Name Surname BirthDay YooxLetter".split(" ")) - submissible_data.Gender = "U" -// submissible_data.idUser = auth.user_id -// submissible_data.AccessToken = auth.access_token -// submissible_data.Premium = "false" -// submissible_data.LanguageId = "" -// submissible_data.SiteCode = "STONEISLAND_US" -// submissible_data.FuriganaName = "" -// submissible_data.FuriganaSurname = "" -// submissible_data.UserPromocode = "" - submissible_data.BirthDay += "T00:00:00Z" - submissible_data.YooxLetter = this.$("[name=YooxLetter]").prop("checked") - submissible_data.DataProfiling = this.$("[name=DataProfiling]").prop("checked") - - console.log(data.DataProfiling, submissible_data.DataProfiling) - console.log(submissible_data) - - return submissible_data - }, - - success: function(data){ - }, - - error: function(data){ - }, - - cancel: function(){ - app.router.go("intro") - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/SettingsView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/SettingsView.js deleted file mode 100755 index f6eae13c..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/SettingsView.js +++ /dev/null @@ -1,45 +0,0 @@ -var SettingsView = FormView.extend({ - - el: "#settings", - - events: { - "change [name=store]": "changeStore", - "change [name=hub]": "changeHub", - }, - - initialize: function(){ - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.$store = this.$("[name=store]") - this.$hub = this.$("[name=hub]") - this.scroller = new IScroll('#settings', app.iscroll_options) - }, - - show: function(){ - if (! auth.logged_in()) { return app.router.go("intro") } - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO CHANGE
YOUR NOTIFICATION SETTINGS.", "") - return - } - document.body.className = "settings" - this.deferScrollToTop() - - this.$store.prop("checked", !! push.settings.store) - this.$hub.prop("checked", !! push.settings.hub) - // push.subscribe("store") - // push.subscribe("hub") - }, - - changeStore: function(){ - var state = app.settings.$store.prop("checked") - if (state) { push.subscribe("store") } - else { push.unsubscribe('store') } - }, - changeHub: function(){ - var state = app.settings.$hub.prop("checked") - if (state) { push.subscribe("hub") } - else { push.unsubscribe('hub') } - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ShippingView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ShippingView.js deleted file mode 100755 index 71cd9eef..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/account/ShippingView.js +++ /dev/null @@ -1,87 +0,0 @@ -var ShippingView = FormView.extend({ - - el: "#shipping", - - action: sdk.address.add, - - events: { - }, - - test_data: { - "Name":"name", - "Surname":"surname", - "Address":"address1\naddress2", - "IsDefault":false, - "IsBillingDefault":false, - "IsOwner":false, - "ZipCode":"88040", - "City":"City", - "Province":"NY", - "Phone":"1234567890", - "Mobile":"Mobile", - "Mail":"Mail", - "UserId": sdk.auth.user_id, - }, - - initialize: function(){ - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.address = new AddressView ({ parent: this }) - this.scroller = new IScroll('#shipping', app.iscroll_options) - }, - - show: function(){ - if (! auth.logged_in()) { return app.router.go("intro") } - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO
EDIT YOUR SHIPPING INFO.", "") - return - } -// this.preload( this.data || this.test_data ) - app.footer.show("SAVE") - document.body.className = "shipping" - this.deferScrollToTop() - }, - - populate: function(data){ - this.data = data || this.data - this.address.populate(data) - }, - - finalize: function(data){ - if (this.address.data && this.address.data.Id) { - sdk.address.destroy({ - id: this.address.data.Id, - success: function(){}, - error: function(){}, - }) - } - - data.IsDefault = "true" // this.$isDefault.prop("checked") ? "true" : "false" - data.UserId = sdk.auth.user_id - - console.log(data) - return data - }, - - success: function(data){ - app.curtain.show("loading") - app.account.listAddresses({ - success: function(){ - app.curtain.hide("loading") - }, - error: function(){ - app.curtain.hide("loading") - }, - }) - }, - - error: function(data){ - console.log(data) - }, - - cancel: function(){ - app.router.go("intro") - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LoginView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LoginView.js deleted file mode 100755 index d7968c22..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LoginView.js +++ /dev/null @@ -1,60 +0,0 @@ -var LoginView = FormView.extend({ - - el: "#login", - - action: sdk.account.login, - - events: { - "click .newuser": "new_user", - "click .forgotpassword": "forgot_password", - "submit form": "save", - }, - - initialize: function(){ - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.scroller = new IScroll('#login', app.iscroll_options) - }, - - show: function(){ - if (auth.logged_in()) { - app.router.go("intro") - return - } - var msg = "* Your personal and payment
information will always remain private" - app.footer.show("SUBMIT") - this.$form.get(0).reset() - this.$msg.html(msg) - document.body.className = "login" - }, - - new_user: function(){ - app.router.go("account/signup") - }, - - forgot_password: function(){ - window.open("http://www.stoneisland.com/", '_system') - }, - - validate_presence: { - "Email": "Please enter a valid email address.", - "Password": "Please enter your password.", - }, - - success: function(data){ - console.log(data) - app.account.logged_in(function(){ - app.router.go("store") - }) - }, - - error: function(data){ - this.$msg.html("There was an error logging you in. Bad password?") - this.$msg.addClass('alert-notice') - }, - - cancel: function(){ - auth.deferred_product = null - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LogoutView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LogoutView.js deleted file mode 100755 index 481dcb8d..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/LogoutView.js +++ /dev/null @@ -1,16 +0,0 @@ -var LogoutView = View.extend({ - - el: "#logout", - - events: { - }, - - show: function(){ - document.body.className = "logout" - app.header.set_cart_count(0) - app.footer.hide() - auth.log_out() - app.account.logged_out() - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/SignupView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/SignupView.js deleted file mode 100755 index 8d9cf52d..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/auth/SignupView.js +++ /dev/null @@ -1,121 +0,0 @@ -var SignupView = FormView.extend({ - - el: "#signup", - - action: sdk.account.signup, - last_data: null, - -/* - test_data: { - "Email": "testit.account" + Math.floor(Math.random() * 10000000) + "@yoox.com", - "Password": "TestPassword", - "Password2": "TestPassword", - "Gender": "U", - "Name": "TestName", - "Surname": "TestSurname", - "BirthDay": "1978-11-12", - "DataProfiling": true, - }, -*/ - - events: { - "click .privacy-msg": "privacy_link", - "submit form": "save", - }, - - initialize: function(){ - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.scroller = new IScroll('#signup', app.iscroll_options) - }, - - show: function(){ - if (auth.logged_in()) { - app.router.go("intro") - return - } - var msg = "* Your personal and payment
information will always remain private" - app.footer.show("SUBMIT") - this.$form.get(0).reset() - this.$msg.html(msg) - document.body.className = "signup" - - this.preload() - this.deferScrollToTop() - }, - - validate_presence: { - "Name": "Please enter your first name.", - "Surname": "Please enter your last name.", - "Email": "Please enter a valid email address.", - "ConfirmEmail": "Please enter a valid email address.", - "BirthDay": "Please enter your birthday.", - "Password": "Please enter your password.", - "Password2": "Please enter your password again.", - "DataProfiling": "You must agree to data profiling.", - }, - - validate_fields: function(data, errors){ - if (data.Password.length < 7) { errors.push([ "Password", "Password must be 7 characters or more." ]) } - if (data.Password !== data.Password2) { errors.push([ "Password2", "Passwords don't match." ]) } - if (! data.Email.match("@")) { errors.push([ "Email", "Email address is not valid." ]) } - if (data.Email.toLowerCase() !== data.ConfirmEmail.toLowerCase()) { errors.push([ "ConfirmEmail", "Email addresses don't match." ]) } - // if (data.Gender === "NONE") { errors.push([ "Gender", "Please supply your gender." ]) } - if (data.DataProfiling !== "true") { errors.push([ "DataProfiling", "You must consent to use this service." ]) } - data.YooxLetter = this.$("[name=YooxLetter]").prop("checked") - }, - - finalize: function(data){ - delete data.ConfirmEmail - - data.Gender = "U" - data.BirthDay += "T00:00:00Z" - - this.last_data = data - console.log(data) - return data - }, - - privacy_link: function(){ - // rewrite app.privacy instance temporarily - app.privacy.back = function(){ - app.router.go("account/signup") - } - app.privacy.hide = function(){ - app.privacy.back = app.privacy.hide = null - } - app.router.go("page/privacy") - }, - - success: function(data){ - console.log('success', data) - auth.user = auth.user || {} - auth.user.Name = this.last_data.Name - auth.user.Surname = this.last_data.Surname - auth.user.Email = this.last_data.Email - auth.user.BirthDay = this.last_data.BirthDay - app.account.logged_in(function(){ app.router.go("store") }) - }, - - error: function(data){ - try { - data = JSON.parse(data.responseText) - app.signup.show_errors([[ 'Name', data['Error']['Description'] ]]) - } - catch (e) { - switch (data.status) { - case 409: - app.signup.show_errors([[ 'Email', "Email is already in use." ]]) - break - default: - app.signup.show_errors([[ 'Name', "There was an unknown error." ]]) - break - } - } - }, - - cancel: function(){ - auth.deferred_product = null - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/ArchiveView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/ArchiveView.js deleted file mode 100755 index 12aaf7de..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/ArchiveView.js +++ /dev/null @@ -1,235 +0,0 @@ -var ArchiveView = ScrollableView.extend({ - - el: "#archive", - menu_template: $("#archive .menu .template").html(), - row_template: $("#archive .scroll .template").html(), - - events: { - "click .item": "pick", - "mousedown .row": "mousedown", - "touchstart .row": "touchstart", - "mousemove .row": "mousemove", - "touchmove .row": "touchmove", - "mouseup .row": "mouseup", - "touchend .row": "touchend", - }, - - initialize: function(){ - this.$menu_items = this.$(".menu .items") - this.$content = this.$(".content") - this.$loader = this.$(".loader") - this.scroller = new IScroll('#archive .scroll', app.iscroll_options) - this.$subtitle = this.$('.subtitle') - this.subtitle_html = this.$subtitle.html() - - }, - - back: function(){ - this.$el.addClass("menu") - app.header.set_back(false) - this.$subtitle.html( this.subtitle_html ) - }, - - pick: function(e){ - this.$el.removeClass("menu") - app.header.set_back(true) - var index = $(e.currentTarget).data("index") - this.$subtitle.html( $(e.currentTarget).text() ) - this.populateDecade(index) - this.deferScrollToTop() - }, - - show: function(){ - this.deferScrollToTop() - app.footer.hide() - this.back() - document.body.className = "archive" - if (! this.populated) { - this.populate( BACKUP_DB.archive ) - } - }, - - populate: function(data){ - if (this.loaded) { return } - this.loaded = true - this.data = data - this.$loader.hide() - this.$content.empty() - - // id title images[ uri label code caption ] - this.data.forEach(function(row, index){ - - var t = this.menu_template.replace(/{{title}}/, row.title) - var $t = $(t) - $t.data("title", row.title) - $t.data("index", index) - this.$menu_items.append($t) - }.bind(this)) - - this.back() - this.populateDecade(0, 3) - this.deferScrollToTop() - }, - - populateDecade: function(index, count){ - this.$content.empty() - - var loader = new Loader() - - var row = this.data[index] - - count = count || row.images.length - - row.images.forEach(function(cell, i){ - if (count && i > count) { return } - var $t = $("
") - $t.addClass("row").addClass("loading") - var t = this.row_template.replace(/{{image}}/, cell.uri) - .replace(/{{label}}/, cell.label) - .replace(/{{code}}/, cell.code) - .replace(/{{caption}}/, cell.caption) - $t.html(t) - $t.data("flipped", false) - this.$content.append($t) - - var item = $t[0] - var aa = this.build_aa_item( item ) - aa.q = 0 - this.render( aa, 0 ) - aa.flipped = true - this.fix_z_index( aa ) - - var $text = $t.find(".text") - if ( ($text.height() % 2) == 1) { - $text.css("margin-bottom", "1px") - } - - loader.preloadImage(cell.uri, function(){ - aa.flipped = false - this.fix_z_index( aa ) - $t.removeClass('loading') - }.bind(this)) - }.bind(this)) - - this.deferRefresh() - setTimeout(function(){ - this.deferScrollToTop() - }.bind(this), 100) - }, - -// ['transformProp'] = "translateZ(0) translateX(-50%) translateY(-50%) "; -// .image, .text - - touchstart: function(e){ - app.archive.row = e.currentTarget - app.archive.mousedown(e.originalEvent.touches[0]) - }, - touchmove: function(e){ - app.archive.mousemove(e.originalEvent.touches[0]) - }, - touchend: function(e){ - app.archive.mouseup() - }, - - row: null, - image: null, - text: null, - flipped: false, - q: 0, - - mousedown: function(e){ - var aa = app.archive.item = app.archive.build_aa_item( app.archive.row || e.currentTarget ) - aa.mouse_x = e.pageX - aa.mouse_y = e.pageY - }, - - build_aa_item: function(el){ - var aa = {} - aa.row = el - aa.flipped = $(aa.row).data('flipped') - aa.image = $(aa.row).find(".image")[0] - aa.text = $(aa.row).find(".text")[0] - aa.q = 0 - return aa - }, - - mousemove: function(e){ - if (! app.archive.item) return - aa = app.archive.item - var dx = ( aa.mouse_x - e.pageX ) / window.innerWidth - var dy = ( aa.mouse_y - e.pageY ) / window.innerWidth - - var gray, opacity, q - - dx = Math.abs(dx) - dx *= 2 - q = clamp( dx, 0, 1 ) - - this.render(aa, q) - - aa.q = q -/* - aa.row.style['transformProp'] = [ - "translateZ(0)", - "translateX(-50%)", - "translateY(-50%)", - "rotateY(" + dx + "deg)", - ].join(" ") -*/ - }, - - render: function(aa, q){ - if ( aa.flipped ) { - gray = Math.round( (1-q) * 100 ) - opacity = lerp(q, 0.2, 1) - text_opacity = lerp(q, 1, 0.3) - } - else { - gray = Math.round( q * 100 ) - opacity = lerp(q, 1, 0.2) - text_opacity = lerp(q, 0.3, 1) - } - aa.image.style.WebkitFilter = "grayscale(" + gray + "%)" - aa.image.style.opacity = opacity - aa.text.style.opacity = text_opacity - }, - - margin: 0.3, - - mouseup: function(e){ - aa = app.archive.item - app.archive.row = null - app.archive.item = null - var was_flipped = aa.flipped - var flipped = aa.flipped ? (aa.q < app.archive.margin) : (aa.q > app.archive.margin) - var dest = was_flipped == flipped ? 0 : 1 - $(aa.row).data('flipped', flipped) - - oktween.add({ - obj: {q: aa.q}, - to: {q: dest}, - duration: 200 * Math.abs(aa.q-dest), - update: function(o, dt){ - app.archive.render(aa, o.q) - }, - }) - - this.fix_z_index(aa) - }, - - fix_z_index: function (aa) { - if ( aa.flipped ) { - console.log(aa.q) - z = aa.q > app.archive.margin ? 2 : 1 - zz = aa.q > app.archive.margin ? 1 : 2 - } - else { - z = aa.q < app.archive.margin ? 2 : 1 - zz = aa.q < app.archive.margin ? 1 : 2 - } - aa.image.style.zIndex = z - aa.text.style.zIndex = zz - - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/BlogView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/BlogView.js deleted file mode 100755 index 5ee7f641..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/BlogView.js +++ /dev/null @@ -1,87 +0,0 @@ -var BlogView = View.extend({ - - data: null, - loaded: false, - initialize: function(){ - this.loader = new Loader () - }, - - fetch: function(fn){ - $.ajax({ - method: "GET", -// url: sdk.env == 'test' ? '/db.json' : "https://stone.sup.land/db.json", - url: "https://stone.sup.land/db.json", - success: function(data){ - this.success(data) - fn && fn() - }.bind(this), - cache: true, - }) - }, - - refresh: function(){ - this.loaded = false - this.fetch() - }, - - success: function(data){ - - if (this.loaded) return - - this.loaded = true - this.data = data = typeof data == "string" ? JSON.parse(data) : data - - switch (data.store[0].DepartmentStoreStatus) { - case "open": - app.closed.storeIsClosed = false - break - case "closed": - app.closed.storeIsClosed = true - app.closed.storeClosedMessageOne = data.store[0].StoreClosedMessageOne - app.closed.storeClosedMessageTwo = data.store[0].StoreClosedMessageTwo - break - } - - if (app.closed.storeIsClosed) { - app.closed.populate(data.store[0].ClosedStoreImages) - } - else { - app.departments = data.store[0].Departments - app.department_id = data.store[0].Departments[0].uri - app.collection.setCollectionName( data.store[0].Departments[0].text ) - app.collection.loaded = false - app.collection.fetch() - } - - app.archive.populate(data.archive) - this.loader.preloadImage(data.hub[0].image[0].uri, function(img){ - app.hub.populate(data.hub) - }.bind(this)) - this.loader.preloadImage(data.story[0].image.uri, function(img){ - app.story.populate(data.story) - setTimeout(function(){ - this.loader.preloadImage(data.story[1].image.uri) - this.loader.preloadImage(data.story[2].image.uri) - }.bind(this), 2000) - }.bind(this)) - - data.page.forEach(function(page){ - app[page.tag].populate(page) - }) - - console.log(data.store[0].StoreStatus) - - app.product.fitLargeCodes = {} - if (data.store[0].FittingCodes.length) { - data.store[0].FittingCodes.split("\n").forEach(function(code){ - app.product.fitLargeCodes[code] = true - }) - } - - if (data.store[0].BackgroundIsGray === "true") { - app.collection.$el.addClass("gray") - app.product.gallery.$el.addClass("gray") - } - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/HubView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/HubView.js deleted file mode 100755 index 013c2b45..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/HubView.js +++ /dev/null @@ -1,174 +0,0 @@ -var HubView = ScrollableView.extend({ - - el: "#hub", - template: $("#hub .template").html(), - - events: { - "click .content-share": "share", - "click .store": "store_link", - "click .gallery-left": "gallery_left", - "click .gallery-right": "gallery_right", - "click .play": "play_video", - }, - - initialize: function(){ - this.$content = this.$(".content") - this.$loader = this.$(".loader") - this.scroller = new IScroll('#hub', app.iscroll_options) - HubLoader.init(this) - }, - - show: function(){ - this.deferScrollToTop() - app.footer.hide() - document.body.className = "hub" - if (! this.populated) { - this.populate( BACKUP_DB.hub ) - } - }, - - galleries: {}, - populated: false, - populate: function(data){ - // sort posts by date, reversed - this.populated = true - this.data = data.map(function(s){ - return [ +moment(s.date), s ] - }).sort(function(a,b){ - return a[0] > b[0] ? -1 : a[0] == b[0] ? 0 : 1 - }).map(function(pair){ - // console.log(pair[1]) - return pair[1] - }) - this.$loader.hide() - this.$content.empty() - this.galleries = {} - HubLoader.add(this.data) - - this.deferScrollToTop() - }, - - append: function(row){ - // id date subtitle body link store image[uri caption] - // console.log(row) - // console.log(moment(row.date)) - var t = this.template.replace(/{{id}}/g, row.id) - .replace(/{{date}}/, moment(row.date).format("MM.DD.YYYY")) - .replace(/{{title}}/, row.title) - .replace(/{{subtitle}}/, row.subtitle) - .replace(/{{link}}/, row.link) - .replace(/{{body}}/, row.body.replace(/\n/g, "
")) - var $t = $(t) - if (row.store != "true") { - $t.find(".store").remove() - } - this.$content.append($t) - - if (row.image && row.image.length > 1) { - // image gallery - var $gallery = $(".gallery-" + row.id) - row.image.forEach(function(img){ - var el = document.createElement("div") - el.style.backgroundImage = "url(" + img.uri + ")" - el.className = "item" - $gallery.append(el) - }) - this.galleries[row.id] = new Flickity( ".gallery-" + row.id, { - selector: '.item', - cellAlign: 'center', - autoPlay: false, - freeScroll: false, - wrapAround: true, - imagesLoaded: true, - prevNextButtons: false, - pageDots: false, - contain: true, - draggable: true, - }) - } - else { - // single image - var el = document.createElement("div") - if (row.image && row.image.length) { - el.style.backgroundImage = "url(" + row.image[0].uri + ")" - } - el.className = "item" - $(".gallery-" + row.id).append(el) - $(".gallery-" + row.id).data("row", row) - - // video, append play button - if (row.link.match(/youtube|youtu.be|vimeo/)) { - var play = document.createElement("div") - play.className = "play" - $(".gallery-" + row.id).append(play) - $(".gallery-" + row.id).addClass("gallery-video-post") - if (! row.image) { - var url = row.link - var ytid = (url.match(/v=([-_a-zA-Z0-9]{11})/i) || url.match(/youtu.be\/([-_a-zA-Z0-9]{11})/i) || url.match(/embed\/([-_a-zA-Z0-9]{11})/i))[1].split('&')[0]; - e.style.backgroundImage = "url(https://i.ytimg.com/vi/" + ytid + "/maxresdefault.jpg" - } - } - $t.find(".gallery-left").remove() - $t.find(".gallery-right").remove() - } - }, - - store_link: function(){ - app.router.go("store") - }, - play_video: function(e){ - var row = $(e.currentTarget).closest('.gallery-video-post').data("row") - window.open(row.link, '_system') - }, - - gallery_left: function(e){ - var id = $(e.currentTarget).closest(".hub_item").data('id') - this.galleries[id].previous() - }, - gallery_right: function(e){ - var id = $(e.currentTarget).closest(".hub_item").data('id') - this.galleries[id].next() - }, - - share: function(e){ - var title = $(e.currentTarget).parent().find(".title").text() - console.log("share", title) - window.plugins.socialsharing.share(title, null, null, "http://deeplink.me/www.stoneisland.com/hub" ) - }, - -}) - -var HubLoader = (function(){ - var queue, view, item, loader - var HubLoader = {} - var loader - HubLoader.init = function(v){ - view = v - } - HubLoader.add = function(items){ - queue = items - this.load() - } - HubLoader.load = function(){ - item = queue.shift() - if (! item) return - if (item.image && item.image.length) { - loader = new Loader (HubLoader.build) - images = item.image.map(function(img){ - return img.uri.replace("http:","https:") - }).filter(function(img){ - return img.uri - }) - loader.preloadImages(images) - } - else { - HubLoader.build() - } - } - HubLoader.build = function(){ - view.append(item) - view.scroller.refresh() - setTimeout(HubLoader.load, 20) - } - return HubLoader -})() diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/PageView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/PageView.js deleted file mode 100755 index f5f8ab2e..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/PageView.js +++ /dev/null @@ -1,41 +0,0 @@ -var PageView = ScrollableView.extend({ - - events: { - "click a": "follow_link" - }, - - initialize: function(opt){ - this.page = opt.page - this.setElement("#" + opt.page) - this.$content = this.$(".content") - this.$loader = this.$(".loader") - this.scroller = new IScroll('#' + this.page, app.iscroll_options) - }, - - show: function(){ - this.deferScrollToTop() - app.footer.hide() - document.body.className = this.page - }, - - populate: function(data){ - this.$content.html(data.body.replace(/\n/g, "
")) - this.$content.find("a").each(function(){ - var href = $(this).attr("href") // .substr(1, "fuck".length-2) - if (href.indexOf("“")) { - href = href.substr(1, href.length-2) - $(this).attr("href", href) - } - $(this).attr("target", "_system") - }) - }, - - follow_link: function(e){ - e.stopPropagation() - e.preventDefault() - var href = $(e.currentTarget).attr("href") - console.log(href) - window.open(href, '_system') - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/StoryView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/StoryView.js deleted file mode 100755 index 5a7a56d1..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/blogs/StoryView.js +++ /dev/null @@ -1,76 +0,0 @@ -var StoryView = ScrollableView.extend({ - - loaded: false, - - el: "#story", - template: $("#story .template").html(), - - events: { - "click .links li": "pick", - }, - - initialize: function(){ - this.sections = {} - this.$img = this.$("img") - this.$content = this.$(".content") - this.$links = this.$(".links") - this.$loader = this.$(".loader") - this.loader = new Loader () - this.scroller = new IScroll('#story', app.iscroll_options) - }, - - show: function(){ - this.deferScrollToTop() - app.footer.hide() - document.body.className = "story" - if (! this.loaded) { - this.populate( BACKUP_DB.story ) - } - }, - - populate: function(data){ - if (this.loaded) { return } - this.loaded = true - this.data = data - this.$loader.hide() - this.$content.empty() - // id title image[uri caption] body - this.data.forEach(function(row){ - var t = this.template.replace(/{{id}}/, row.id) - .replace(/{{body}}/, row.body.replace(/\n/g, "
")) - var li = document.createElement("li") - li.dataset.id = row.id - li.innerHTML = row.title - this.sections[row.id] = row - this.$links.append(li) - this.$content.append(t) - }.bind(this)) - - this.set_active( this.data[0].id ) - }, - - pick: function(e){ - var id = e.currentTarget.dataset.id - this.set_active(id) - }, - - set_active: function(id){ - this.$(".active").removeClass("active") - - this.$links.find("[data-id=" + id + "]").addClass("active") - this.$content.find("[data-id=" + id + "]").addClass("active") - - var section = this.sections[id] - - if (navigator.onLine) { - var $replace = this.$img - - this.$img.stop().fadeTo(110,0.65, function() { - $replace.attr("src", section.image.uri) - }).fadeTo(130,1) - } - - this.deferScrollToTop() - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartConfirm.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartConfirm.js deleted file mode 100755 index a82509af..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartConfirm.js +++ /dev/null @@ -1,178 +0,0 @@ -var CartConfirm = FormView.extend({ - - el: "#cart_confirm", - - template: $("#cart_confirm .template").html(), - - events: { - }, - - initialize: function(opt){ - this.parent = opt.parent - this.$rows = this.$(".rows") - this.$subtotal = this.$(".subtotal") - this.$shipping = this.$(".shipping") - this.$tax = this.$(".tax") - this.$total = this.$(".total") - - this.$shipping_address = this.$(".shipping_address") - this.$shipping_method = this.$(".shipping_method") - - this.$payment_name = this.$(".payment_name") - this.$payment_method = this.$(".payment_method") - this.$payment_address = this.$(".payment_address") - - this.scroller = new IScroll('#cart_confirm', app.iscroll_options) - }, - - show: function(){ - document.body.className = "cart" - app.cart.el.className = "confirm" - app.footer.show("PLACE ORDER") - window.location.hash = "#/cart/confirm" - this.deferScrollToTop() - - app.view = this - app.curtain.show("loading") - promise(sdk.cart.get_status).then( this.populate.bind(this) ) - }, - - populate: function(data){ - console.log(data) - - data = data.Cart - - this.$rows.empty() - - data.Items.forEach(function(item){ - var $el = $("
") - this.$rows.append($el) - var code_ten = item.Code10 - var size_id = item.Size - - var code = code_ten.substr(0, 8) - app.product.find(code, function(data, details){ - var descriptions = app.product.get_descriptions( details ) - - var name_partz = descriptions['ModelNames'].split(' ') - var num = name_partz.shift() - var title = name_partz.join(' ') - var type = title_case( descriptions['MicroCategory'] ) - - var color_name, size_name - - details.Item.ModelColors.some(function(color){ - if (color['Code10'] == code_ten) { - color_name = color['ColorDescription'] - return true - } - return false - }) - - details.Item.ModelSizes.some(function(size){ - if (size['SizeId'] == size_id) { - // console.log(size) - size_name = size['Default']['Text'] - size_name = SIZE_LOOKUP[ size_name ] || size_name - if (! size_name && ! size['Default']['Labeled']) { - size_name = size['Default']['Text'] + " " + size['Default']['ClassFamily'] - } - - return true - } - return false - }) - -// size_name = item.DefaultSize + " " + item.DefaultSizeClassFamily - - var t = this.template - .replace(/{{image}}/, sdk.image(item['Code10'], '11_f')) - .replace(/{{sku}}/, num) - .replace(/{{title}}/, title) - .replace(/{{type}}/, type) - .replace(/{{size}}/, size_name || "DEFAULT") - .replace(/{{color}}/, color_name || "DEFAULT") - .replace(/{{quantity}}/, 1) - .replace(/{{price}}/, as_cash(details.Item.Price.DiscountedPrice)) - $el.data("price", details.Item.Price.DiscountedPrice) - $el.html(t) - this.refreshScroller() - }.bind(this)) - }.bind(this)) - - var subtotal = data.Totals.TotalWithoutPromotions - var shipping_cost = data.DeliveryMethod.Selected.Amount.Total - var tax = data.Totals.TotalSalesTax - var total = data.Totals.TotalToPay - - this.$subtotal.html( as_cash(subtotal) ) - this.$shipping.html( as_cash(shipping_cost) ) - this.$tax.html( as_cash(tax) ) - this.$total.html( as_cash(total) ) - - var street = data.Receiver.StreetWithNumber.replace(/\n$/,"").replace("\n", ", ") - var address = data.Receiver.Name.toUpperCase() + " " + data.Receiver.Surname.toUpperCase() + "
" + street + ", " - address += data.Receiver.City + ", " + data.Receiver.Region + " " + data.Receiver.PostalCode - - this.$shipping_address.html(address) - this.$shipping_method.html(data.DeliveryMethod.Selected.Type == 1 ? "* STANDARD SHIPPING" : "* EXPRESS SHIPPING") - - var cc = data.Payment.CreditCard - var cc_street = cc.HolderAddress.replace(/\n$/,"").replace("\n", ", ") - var cc_type = cc.Type == "AmericanExpress" ? "American Express" : cc.Type - - this.$payment_name.html( cc.HolderName.toUpperCase() + " " + cc.HolderSurname.toUpperCase() ) - this.$payment_method.html( cc_type.toUpperCase() + " XXXX-XXXX-XXXX-" + cc.Last4 ) - - app.curtain.hide("loading") - }, - - save: function(){ - app.curtain.show("loading") - promise(sdk.cart.finalize, {}).then(function(){ - app.curtain.hide("loading") - app.router.go('cart/thanks') - }.bind(this)).error(function(data){ - app.curtain.hide("loading") - // {"Header":{"StatusCode":403,"Description":"403 Forbidden"},"Error":{"Description":"GenericApiError:CartAlreadyClosed"}} - // {"Header":{"StatusCode":409,"Description":"304 NotModified"},"Error":{"Description":"FinalizationError:\\"Item has been removed from cart because it is no longer available.\\"\\n235"}}' - // {"Header":{"StatusCode":409,"Description":"304 NotModified"},"Error":{"Description":"FinalizationError:\"The cart cannot be empty.\"\n233"}} - // {"Header":{"StatusCode":409,"Description":"304 NotModified"},"Error":{"Description":"FinalizationError:\"The reciever validation fails."}} - // {"Header":{"StatusCode":440,"Description":"304 NotModified"},"Error":{"Description":"GenericApiError:CartFinalizationNotYetCompleted"}} - // {"Header":{"StatusCode":441,"Description":"304 NotModified"},"Error":{"Description":"GenericApiError:EmptyCreditCard"}} - switch (data.StatusCode) { - case 403: // cart already closed - auth.clear_cart(auth.create_cart) - app.router.go('thanks') - break - case 409: // finalization error - this.finalization_error(data) - break - case 440: // genericapierror (credit card error!) - case 441: // genericapierror (credit card empty) - app.router.go('cart/payment') - app.cart.payment.show_errors([["Number","There was a problem with your credit card."]]) - break - } - }.bind(this)) - }, - - finalization_error: function(data){ - if (data['Error']['Description'].match(/receiver validation fails/)) { - app.router.go('cart/shipping') - app.cart.payment.show_errors([["Number","There was a problem with your credit card."]]) - } - else if (data['Error']['Description'].match(/cart cannot be empty/)) { - app.router.go('cart/summary') - } - else if (data['Error']['Description'].match(/Item has been removed/)) { - app.router.go('cart/error') - app.cart.error.show_error("We're sorry, but one or more items was out of stock. Please check your cart and try again.") - } - }, - - cancel: function(){ - app.router.go('cart/payment') - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartError.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartError.js deleted file mode 100755 index f9a1963e..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartError.js +++ /dev/null @@ -1,28 +0,0 @@ -var CartError = View.extend({ - - el: "#cart_error", - - events: { - }, - - initialize: function(opt){ - this.parent = opt.parent - this.$error = this.$(".errrrrrrrrrrrrrrr") - }, - - show: function(){ - document.body.className = "cart" - app.cart.el.className = "error" - app.footer.show("< BACK TO CART") - app.footer.hide() - }, - - show_error: function(msg){ - this.$error.html(msg) - }, - - ok: function(){ - app.router.go("cart/summary") - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartPayment.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartPayment.js deleted file mode 100755 index a19e69a5..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartPayment.js +++ /dev/null @@ -1,188 +0,0 @@ -var CartPayment = FormView.extend({ - - el: "#cart_payment", - - address_template: $("#cart_payment .address_row_template").html(), - cc_template: $("#cart_payment .cc_template").html(), - - action: sdk.cart.set_credit_card, - - address_list_mode: false, - cc_list_mode: false, - data: {}, - - events: { - "change [name=SameAsShipping]": "toggle_shipping", - "click .address_dropdown": "toggle_address", - "click .cc_dropdown": "toggle_cc", - }, - - initialize: function(opt){ - this.parent = opt.parent - this.$form = this.$("form") - this.$msg = this.$(".msg") - this.$same_as_shipping = this.$("[name=SameAsShipping]") - this.$billing_address_rapper = this.$(".billing_address_rapper") - this.$address_list = this.$(".address_list") - this.$address_form = this.$(".address") - this.$address_dropdown = this.$(".address_dropdown") - this.$cc_list = this.$(".cc_list") - this.$cc_form = this.$(".cc") - this.$cc_dropdown = this.$(".cc_dropdown") - this.$cc_confirm = this.$(".cc_confirm") - - this.address = new AddressView ({ parent: this, checkPhone: false }) - this.cc = new CreditCardView ({ parent: this }) - this.scroller = new IScroll('#cart_payment', app.iscroll_options) - this.address.disabled = true - this.cc.disabled = true - }, - - show: function(){ - document.body.className = "cart" - app.cart.el.className = "payment" - app.footer.show("CONFIRM >") - window.location.hash = "#/cart/payment" - - app.view = this - this.populate() - this.deferScrollToTop() - }, - - toggle_shipping: function(){ - setTimeout(function(){ - var state = this.$same_as_shipping.prop("checked") - this.$billing_address_rapper.toggle( ! state ) - this.address.disabled = state - }.bind(this)) - }, - - toggle_address: function(state){ - if (! app.account.ccs.length) { - state = false - } - // this.$address_dropdown.toggle( !! app.account.ccs.length ) - - this.address_list_mode = typeof state == "boolean" ? state : ! this.list_mode - this.address.disabled = this.address_list_mode - this.$address_form.toggle(! this.address_list_mode) - this.$address_list.toggle(this.address_list_mode) - }, - - toggle_cc: function(state){ - if (! app.account.ccs.length) { - state = false - } - // this.$cc_dropdown.toggle( !! app.account.ccs.length ) - - this.cc_list_mode = typeof state == "boolean" ? state : ! this.cc_list_mode - this.cc.disabled = this.cc_list_mode - this.$cc_form.toggle(! this.cc_list_mode) - this.$cc_list.toggle(this.cc_list_mode) - this.$cc_confirm.toggle(this.cc_list_mode) - }, - - populate: function(){ - this.$(".save_as_default").show() - this.$address_list.empty() - this.$cc_list.empty() - this.toggle_address( !! app.account.ccs.length ) - this.toggle_cc( !! app.account.ccs.length ) - - app.account.ccs.forEach(function(cc){ - var address_t = this.address_template.replace(/{{id}}/g, cc.Id) - .replace(/{{checked}}/g, cc.IsDefault ? "checked" : "") - .replace(/{{name}}/g, (cc.Name + " " + cc.Surname).toUpperCase()) - .replace(/{{address}}/g, cc.Address.replace(/\n$/,"").replace("\n", ", ")) - .replace(/{{city}}/g, cc.City) - .replace(/{{state}}/g, cc.Province) - .replace(/{{zip}}/g, cc.ZipCode) - - var cc_t = this.cc_template.replace(/{{id}}/g, cc.Id) - .replace(/{{checked}}/g, cc.IsDefault ? "checked" : "") - .replace(/{{number}}/g, cc['Number']) - .replace(/{{type}}/g, cc.Type.toUpperCase()) - .replace(/{{exp}}/g, cc.ExpirationMonth + "/" + cc.ExpirationYear) - - this.$address_list.append(address_t) - this.$cc_list.append(cc_t) - }.bind(this)) - }, - - finalize: function(data){ - var shipping_info = {}, address_data, address_id, cc_info = {}, cc_data, cc_id - var shipping_type = $("[name=ShippingType]").filter(function(){ return $(this).prop("checked") }).val() - - if (this.$same_as_shipping.prop("checked")) { - address_data = app.cart.shipping.data - } - else if (this.address_list_mode) { - address_id = this.$("[name=AddressId]").filter(function(){ return $(this).prop("checked") }).val() - address_data = app.account.addressLookup[ address_id ] - } - else { - address_data = data - } - - if (this.cc_list_mode) { - cc_id = this.$("[name=CCId]").filter(function(){ return $(this).prop("checked") }).val() - cc_data = app.account.ccLookup[ cc_id ] - - var card_on_file = { - "guid": cc_data.Guid, - "cvv": this.$("[name=CvvConfirm]"), - } - - app.curtain.show("loading") - promise(sdk.cart.use_stored_credit_card, { data: card_on_file }).then(function(data){ - app.curtain.hide("loading") - this.success() - }.bind(this)).error(function(data){ - app.curtain.hide("loading") - console.log("card payment error") - console.log(data) - app.cart.payment.show_errors([["","There was a problem with your credit card."]]) - }.bind(this)) - - return - } - else { - cc_data = data - } - - var credit_info = { - "HolderName": address_data.Name, - "HolderSurname": address_data.Surname, - "HolderAddress": address_data.Address || address_data.StreetWithNumber, - "HolderCity": address_data.City, - "HolderProvince": address_data.Province, - "HolderZip": address_data.PostalCode || address_data.ZipCode, - "HolderISOCountry": CANADIAN_LOOKUP[ address_data.Province ] ? "CA" : "US", - "HolderEmail": auth.user.Email, - "CardNumber": cc_data['Number'], - "Type": cc_data.Type, - "ExpirationMonth": cc_data.ExpirationMonth, - "ExpirationYear": cc_data.ExpirationYear.substr(2,3), - "Cvv": cc_data.Cvv, - } - - console.log( credit_info ) - - return credit_info - }, - - success: function(){ - app.router.go('cart/confirm') - }, - - error: function(data){ - console.log("card payment error") - console.log(data) - app.cart.payment.show_errors([["Number","There was a problem with your credit card."]]) - }, - - cancel: function(){ - app.router.go('cart/shipping') - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartShipping.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartShipping.js deleted file mode 100755 index fd227324..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartShipping.js +++ /dev/null @@ -1,137 +0,0 @@ -var CartShipping = FormView.extend({ - - el: "#cart_shipping", - - action: sdk.cart.set_shipping_address, - - list_mode: true, - data: {}, - - template: $("#cart_shipping .template").html(), - - events: { - "click .dropdown-wrapper": "toggle_dropdown", - }, - - initialize: function(opt){ - this.parent = opt.parent - this.$form = this.$("form") - this.$dropdown_wrapper = this.$(".dropdown-wrapper") - this.$address_list = this.$(".address_list") - this.$address_form = this.$(".address") - this.$msg = this.$(".msg") - this.address = new AddressView ({ parent: this }) - this.scroller = new IScroll('#cart_shipping', app.iscroll_options) - this.address.disabled = true - }, - - show: function(){ - document.body.className = "cart" - app.cart.el.className = "shipping" - app.footer.show("PAYMENT >") - window.location.hash = "#/cart/shipping" - app.view = this - this.populate() - this.deferScrollToTop() - }, - - populate: function(){ - // id checked name address city state zip - this.$(".save_as_default").show() - this.$address_list.empty() - if (! app.account.addresses.length) { - this.toggle_dropdown(false) - return - } - app.account.addresses.forEach(function(address){ - var t = this.template.replace(/{{id}}/g, address.Id) - .replace(/{{checked}}/g, address.IsDefault ? "checked" : "") - .replace(/{{name}}/g, (address.Name + " " + address.Surname).toUpperCase()) - .replace(/{{address}}/g, address.Address.replace(/\n$/,"").replace("\n", ", ")) - .replace(/{{city}}/g, address.City) - .replace(/{{state}}/g, address.Province) - .replace(/{{zip}}/g, address.ZipCode) - this.$address_list.append(t) - }.bind(this)) - }, - - load_form: function(cart_data){ - var data = cart_data.Cart.Receiver - var addy = data.StreetWithNumber.split("\n") - data.Address1 = addy[0] || "" - data.Address2 = addy[1] || "" - data.ZipCode = data.PostalCode - data.Province = data.Region - this.load_data(data) - - this.data = data - if (cart_data.Cart.DeliveryMethod && cart_data.Cart.DeliveryMethod.Selected && cart_data.Cart.DeliveryMethod.Type) { - $("#standard-shipping").prop("checked", cart_data.Cart.DeliveryMethod.Type == 1) - $("#express-shipping").prop("checked", cart_data.Cart.DeliveryMethod.Type == 2) - } - }, - - toggle_dropdown: function(state){ - if (! app.account.addresses.length) { - state = false - } - this.list_mode = typeof state == "boolean" ? state : ! this.list_mode - this.$dropdown_wrapper.toggle( !! app.account.addresses.length ) - this.address.disabled = this.list_mode - this.$address_form.toggle(! this.list_mode) - this.$address_list.toggle(this.list_mode) - }, - - // sdk.cart.set_shipping_address - // sdk.shipping.get_delivery_types - // sdk.shipping.set_delivery_type - - shipping_types: { - Standard: 1, - Express: 2, - }, - - finalize: function(data){ - var shipping_info = {}, address_data, address_id - var shipping_type = $("[name=ShippingType]").filter(function(){ return $(this).prop("checked") }).val() - - sdk.shipping.set_delivery_type({ - id: this.shipping_types[shipping_type], - success: function(data){ console.log("set shipping type", data) }, - error: function(data){ console.log("didnt set shipping type", data) }, - }) - - if (this.list_mode) { - address_id = this.$("[name=AddressId]").filter(function(){ return $(this).prop("checked") }).val() - address_data = app.account.addressLookup[ address_id ] - } - else { - address_data = data - } - - shipping_info.Name = address_data.Name - shipping_info.Surname = address_data.Surname - shipping_info.Email = auth.user.Email - shipping_info.Phone = address_data.Phone - shipping_info.Mobile = address_data.Phone - shipping_info.StreetWithNumber = address_data.Address - shipping_info.PostalCode = address_data.ZipCode - shipping_info.City = address_data.City - shipping_info.Province = address_data.Province - shipping_info.Region = address_data.Province - shipping_info.CountryCode = CANADIAN_LOOKUP[ address_data.Province ] ? "CA" : "US" - - this.data = shipping_info - - return shipping_info - }, - - success: function(){ - app.router.go('cart/payment') - }, - - cancel: function(){ - app.router.go('cart/summary') - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartSummary.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartSummary.js deleted file mode 100755 index 9b5da7b7..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartSummary.js +++ /dev/null @@ -1,212 +0,0 @@ -var CartSummary = ScrollableView.extend({ - - el: "#cart_summary", - - template: $("#cart_summary .template").html(), - - events: { - "click .remove": "remove_item", - }, - - data: null, - - initialize: function(opt){ - this.parent = opt.parent - this.$loader = this.$(".loader") - this.$cart_body = this.$(".cart_body") - this.$cart_empty = this.$(".cart_empty") - this.scroller = new IScroll('#cart_summary', app.iscroll_options) - - this.$rows = this.$(".rows") - this.$subtotal = this.$(".subtotal") - this.$shipping = this.$(".shipping") - this.$tax = this.$(".tax") - this.$total = this.$(".total") - }, - - show: function(){ - document.body.className = "cart" - app.cart.el.className = "summary" - window.location.hash = "#/cart/summary" - app.view = this - if (auth.has_cart()) { - this.load() - } - else { - this.empty() - } - }, - - load: function(){ - this.el.className = "loading" - app.footer.show("SHIPPING >") - app.curtain.show("loading") - sdk.cart.get_status({ - success: this.populate.bind(this), - error: this.empty.bind(this), - }) - }, - - populate: function(data){ - this.data = data - - console.log("CART", data) - - if (! data.Cart.Items || data.Cart.Items.length == 0) { - return this.empty() - } - - this.parent.$steps.show() - this.updateCounts() - - this.$rows.empty() - - data.Cart.Items.forEach(function(item){ - var code_ten = item['Code10'] - var code = code_ten.substr(0, 8) - var size_id = item['Size'] - - var $el = $("
").addClass("cart_item_row") - $el.html("") - $el.data({ - code: code_ten, - size: size_id, - }) - this.$rows.append($el) - app.product.find(code, function(data, details){ - // console.log(data, details) - - var descriptions = app.product.get_descriptions( details ) - // console.log(descriptions) - - var name_partz = descriptions['ModelNames'].split(' ') - var num = name_partz.shift() - var title = name_partz.join(' ') - var type = title_case( descriptions['MicroCategory'] ) - - var color_name, size_name - // console.log(code) - details.Item.ModelColors.some(function(color){ - if (color['Code10'] == code_ten) { - color_name = color['ColorDescription'] - // console.log(color) - return true - } - return false - }) - details.Item.ModelSizes.some(function(size){ - if (size['SizeId'] == size_id) { - // console.log(size) - size_name = size['Default']['Text'] - size_name = SIZE_LOOKUP[ size_name ] || size_name - if (! size_name && ! size['Default']['Labeled']) { - size_name = size['Default']['Text'] + " " + size['Default']['ClassFamily'] - } - - return true - } - return false - }) - - var t = this.template - .replace(/{{image}}/, sdk.image(item['Code10'], '11_f')) - .replace(/{{sku}}/, num) - .replace(/{{title}}/, title) - .replace(/{{type}}/, type) - .replace(/{{size}}/, size_name) - .replace(/{{color}}/, color_name) - .replace(/{{quantity}}/, 1) - .replace(/{{price}}/, as_cash(details.Item.Price.DiscountedPrice)) - $el.html(t) - this.refreshScroller() - }.bind(this)) - }.bind(this)) - - if (data.Cart.Receiver && data.Cart.Receiver.City) { - app.cart.shipping.load_form( data ) - } - - this.updateTotals() - - this.el.className = "full" - this.refreshScroller() - app.curtain.hide("loading") - }, - - updateCounts: function(){ - app.header.set_cart_count( this.data.Cart.Items.length ) - this.parent.setHeaderCount( this.data.Cart.Items.length ) - }, - - updateTotals: function(){ - var subtotal = this.data.Cart.Totals.TotalWithoutPromotions - var shipping_cost = this.data.Cart.DeliveryMethod.Selected.Amount.Total - var tax = this.data.Cart.Totals.TotalSalesTax - var total = this.data.Cart.Totals.TotalToPay - - this.$subtotal.html( as_cash(subtotal) ) - this.$shipping.html( as_cash(shipping_cost) ) - this.$tax.html( as_cash(tax) ) - this.$total.html( as_cash(total) ) - }, - - empty: function(){ - app.footer.hide() - app.header.set_cart_count(0) - this.parent.setHeaderCount( 0 ) - this.parent.$itemcount.html("0 ITEMS") - this.el.className = "empty" - this.parent.$steps.hide() - app.curtain.hide("loading") - }, - - save: function(){ - app.router.go('cart/shipping') - }, - - cancel: function(){ - app.router.go('intro') - }, - - remove_item: function(e){ - var $el = $( e.currentTarget ).closest(".cart_item_row") - var data = $el.data() - - console.log("REMOVE FROM CART") - console.log(data.size + " " + data.code) - - console.log(this.data.Cart) - - this.data.Cart.Totals.TotalWithoutPromotions -= data.price - this.data.Cart.Totals.TotalToPay -= data.price - this.data.Cart.Items = this.data.Cart.Items.filter(function(item){ - return ( item['Code10'] !== data.code || item['Size'] !== data.size) - }) - - this.updateTotals() - this.updateCounts() - $el.remove() - this.refreshScroller() - - if (this.data.Cart.Items.length == 0) { - this.empty() - } - - app.curtain.show("loading") - console.log("loading") - sdk.cart.delete_item({ - data: { - Code10: data.code, - Size: data.size, - }, - success: function(){ - console.log("success") - app.curtain.hide("loading") - }, - error: function(){ - app.curtain.hide("loading") - }, - }) - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartThanks.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartThanks.js deleted file mode 100755 index 03a45d4d..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartThanks.js +++ /dev/null @@ -1,28 +0,0 @@ -var CartThanks = View.extend({ - - el: "#cart_thanks", - - events: { - }, - - initialize: function(opt){ - this.parent = opt.parent - }, - - show: function(){ - document.body.className = "cart" - app.cart.el.className = "thanks" - app.header.set_cart_count(0) - app.footer.show("< BACK TO COLLECTION") - app.footer.hide() - - app.orders.loaded = false - - sdk.auth.clear_cart() - }, - - ok: function(){ - app.router.go("store") - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartView.js deleted file mode 100755 index 6ed8238f..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/cart/CartView.js +++ /dev/null @@ -1,72 +0,0 @@ -var CartView = View.extend({ - - el: "#cart", - - events: { - "click .summary_step": "show_summary", - "click .shipping_step": "show_shipping", - "click .payment_step": "show_payment", - }, - - initialize: function(){ - this.summary = new CartSummary ({ parent: this }) - this.payment = new CartPayment ({ parent: this }) - this.shipping = new CartShipping ({ parent: this }) - this.confirm = new CartConfirm ({ parent: this }) - this.thanks = new CartThanks ({ parent: this }) - this.error = new CartError ({ parent: this }) - - this.$steps = this.$(".steps") - this.$full_msg = this.$(".full_msg") - this.$empty_msg = this.$(".empty_msg") - this.$itemcount = this.$(".itemcount") - }, - - load: function(){ - sdk.cart.get_status({ - success: function(data){ - this.summary.data = data - this.summary.updateCounts() - }.bind(this), - error: function(data){ - console.log(data) - auth.clear_cart() - }, - }) - }, - - show: function(){ - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO
VIEW YOUR CART.", "") - return - } - document.body.className = "cart" - this.show_summary() - }, - - show_summary: function(){ - this.summary.show() - }, - - show_shipping: function(){ - this.shipping.show() - }, - - show_payment: function(){ - this.payment.show() - }, - - setHeaderCount: function(n){ - if (n) { - this.$itemcount.html(pluralize(n, "ITEM", "S")) - this.$full_msg.show() - this.$empty_msg.hide() - } - else { - this.$full_msg.hide() - this.$empty_msg.show() - } - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/backup_db.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/backup_db.js deleted file mode 100755 index eec5c415..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/backup_db.js +++ /dev/null @@ -1,551 +0,0 @@ -var BACKUP_DB = { - "story": [ - { - "id": "philosophy", - "title": "Philosophy", - "image": { - "uri": "http://cdn3.yoox.biz/stoneisland/wp-content/uploads/2013/11/philosophy1.jpg", - "caption": "" - }, - "body": "A culture of research, experimentation, function and use are the matrixes that have always defined Stone Island: the sportswear brand established in 1982, designed to become a symbol of extreme research on fibers and textiles, applied to an innovative design. Season after season, it is through the study of form and the “manipulation” of the matter that Stone Island has found its own language with the aim of establishing new boundaries in the world of garment making. \r\n\r\nThe study of uniforms and of work wear, its evolution according to new requirements of use, has become Stone Island’s observation post for defining a project in which the clothing item’s function is never just aesthetic.\r\n\r\nAn ongoing investigation, thorough and without frontiers, on the processing and ennobling of fibers and textiles, leading to discover materials and production techniques never used before in the clothing industry.\r\n\r\nJackets constructed in nylon monofilament, deriving from the water filtering technology. Highly reflective or thermo-sensitive fabrics, changing color with the variation of temperature. Featherweight polyester cloth vacuum- coated with a 100% stainless steel film used in aviation technology to protect the on-board computers. Non-woven materials, Kevlar® and polyester felt, rhomboidal nets in polyester used in the construction industry and coated in polyurethane. These are some examples of materials conceived by Stone Island philosophy.\r\n\r\nStone Island’s strength is also based on the unique ability to intervene on the finished item, through the continuous tests on dyeing and treatments carried out in the Sportswear Company’s laboratory of color. A department able to combine advanced technology, experience and human capacity and that has developed more than 60,000 different recipes of dyes throughout the years.\r\n\r\nAll the accumulated knowledge and experience, an inalienable heritage, on which great part of Stone Island’s know-how is based, is kept in the historical archive that collects the trial tests, and the recipes for textile dyeing and handling that have been developed by all those people who have worked on this project with passion.", - "__index": "0", - "dateCreated": "Thu, 05 Nov 2015 00:24:44 GMT" - }, - { - "id": "history", - "title": "History", - "image": { - "uri": "https://ltho.s3.amazonaws.com/ce68408c-34b3-40ca-8ddf-c10cd1412c5f.jpg", - "caption": "" - }, - "body": "Stone Island, the Italian brand that reinvented the concept of casual wear, was founded in 1982 out of the passion and brilliant research into textile finishing performed by its creator and art director, intellectual from Bologna, Massimo Osti. It was Osti, in the mid-Seventies, who researched thousands of uniforms and pieces of work clothing and catalogued their functional characteristics. In Ravarino, in the province of Modena, he created a company whose hub was a full-scale center of research into materials and treatments became a sophisticated laboratory for garment and experimental dyeing.\r\n\r\nThe story of Stone Island began, almost by chance, with research into a special material, a thick truck tarpaulin, the outstanding feature of which was that it had been resin-treated in red on one side and blue on the other. The first prototype was too stiff, so it was washed for a long period in water with pumice stones to break down the structure of the material. The result was surprising, a worn-look garment with great appeal. It was therefore decided to create seven jackets in that unique fabric called Tela Stella, and to give this product a name. The strong identity of the project called for an important name, which was identified by analyzing the most commonly occurring words in Joseph Conrad’s novels: the words Stone and Island were chosen.\r\n\r\nStone Island has a marine feel, conjuring up old oilskins corroded by the sea and a military feel, which is drawn from the fund of research completed until that time. The name also evokes a love of the sea and that first treatment selected to “process” the garments. The badge, the detachable fabric label that has distinguished Stone Island garments since the first season, showed a Compass Rose, displayed like a military badge.\r\n\r\nThe reaction is immediate. Stone Island became a success phenomenon, with no set plan or marketing research behind it: a uniquely Italian mix of creativity, intuition and entrepreneurial spirit. A star was born.", - "__index": "1", - "dateCreated": "Thu, 05 Nov 2015 00:27:25 GMT" - }, - { - "id": "carlo-rivetti", - "title": "Carlo Rivetti", - "image": { - "uri": "https://ltho.s3.amazonaws.com/2fe16d85-e85f-4f12-ae55-72622c8efafd.jpg", - "caption": "" - }, - "body": "My family has deep roots within the clothing industry. In the 19th century, Giuseppe Rivetti – son of Giovanni Battista, Italy’s first carding machine operator, inherited his father’s passion and in order to fund his own wool factory he secretly sold cows from the family farms to buy looms. By 1872 he had his own wool factory: “Giuseppe Rivetti e Figli”, which later merged with the Turin based GFT group (Gruppo Finanziario Tessile). There, my uncle Pinot had the unique idea of rubberizing wool fabrics to increase their performance.
This fondness for research also drove my father, Silvio. In the immediate post-war period, he set off for the United States where he found the Palm Beach Incorporated company, who produced something that didn’t yet exist in Europe: clothing constructed on theoretical measurements; what we now know as sizes.
My father was stunned, working for six months as a laborer, before returning and convincing his brothers to give up their shares in the wool factories in order to buy out GFT. \r\n\r\nIn the early 1950’s GFT measured more than 25,000 Italians, which allowed them to effectively dress the whole nation for the first time with non-tailored garments. \r\n\r\nThe 1973 oil crisis brought severe yet swift recession, and something had to be done to recover sales. My cousin, Marco Rivetti, noticed a French couturier working in a women’s outerwear firm we’d acquired one year earlier. He would design and fit the garments, write orders in Paris and then use our company to manufacture them. He was Emanuel Ungaro. This led us to realize that in order to re-launch the sector we needed to add a fundamental ingredient to the clothing industry: fashion.
As a result, GFT became a licensee of the rising stars of Italian fashion, including Giorgio Armani and Valentino. The rise of Italian-made Prêt à Porter was due to the ability to combine entrepreneurial ability with creativity.\r\n\r\nI joined GFT in 1975. Towards the end of that decade, I had the idea to start a new area within the group; to generate something more timeless: sportswear. In the early 1980’s, I discovered C.P. Company, a firm known for being innovative and cutting edge in this field. The company was owned by Trabaldo Togna and Massimo Osti, a graphic artist by profession and the firm’s designer and art director. We bought first 50% in 1983 and later on the entire company.
That was the beginning of my journey. In 1993 I left GFT and, together with my sister Cristina, acquired 100% of the firm which is known today as Sportswear Company.
\r\n\r\nIt was in 1983 that I got to know Massimo Osti, who had brought Stone Island into existence almost by chance, a year earlier. A special fabric named ‘Tela Stella’ had arrived in the company: a cloth that had a different color on each side, used to make truck tarpaulins. The effect was very interesting but had little to do with the existing C.P. Company line. Osti decided to do something special with that fabric and created a collection of just seven jackets. The collection strongly referenced military style with the now iconic badge inspired by military insignia. The compass symbolized love for the sea and an aim for constant research.\r\n\r\nMassimo was at least ten years ahead of others in his field. He saw himself as a producer rather than a fashion designer.
His achievement establishing Stone Island was not only appealing and saleable, but also true to his core belief in informal wear. His ideas were drawn from military and work wear, accompanying them with endless textile research.\r\n\r\nIn the mid-nineties, Massimo our paths eventually came apart, and I found myself with the difficult task of finding someone to design Stone Island.
In 1994 as I wandered through a Munich trade fair I came across the work of designer Paul Harvey, an English designer who lived in Sant’Arcangelo di Romagna, Italy. I was struck by a strange feeling of familiarity and cried out: “so here’s the Stone of the 21st Century!”. From 1996, with Paul, we embarked on the second era of our brand.\r\n\r\nPaul designed 24 collections, each consistent in the evolution and research that has always set Stone Island apart.
He is another extraordinary character. After graduating Central Saint Martins, he decided fashion was not his career path and worked as a truck driver! Only after marrying a fantastic Italian lady and moving to Italy did he start designing clothes.
His approach to design has functionality in its blood, which allowed him to interpret Stone Island perfectly. He led the brand masterfully into the new century. \r\n\r\nAfter 12 marvelous years, Paul needed to leave the fashion world to “do something for the Planet”. With such a noble ambition, I could only accept and support his decision.
In that moment, facing another crucial decision, I came to the conclusion the era of “one man at the helm” was over.
Times had changed. It was necessary to be multicultural in order to be truly contemporary.
I built a design team. I felt that in this era it is this possible to face all aspects of a world only with several minds and several visions: and this has been Stone Island from 2008 to today.
\r\n\r\nI feel like the coach. I choose which men to send onto the pitch, depending upon who we have to play: We need to be more sensitive, faster, and ready to grasp the signs of strength and weakness.
As a result, we need multi-cultural people that travel the world and observe it from different viewpoints: people of different ages and from different cultures.\r\n\r\nThis, in short, is my story. I like to think there’s a common thread that binds us all. A desire for continual experimentation and research, not without a touch of healthy insanity: that special something that makes our Stone Island much more than a just a clothing brand.\r\n\r\nCarlo Rivetti,\r\nPresident and Creative Director, Stone Island", - "__index": "2", - "dateCreated": "Thu, 05 Nov 2015 00:27:38 GMT" - } - ], - "archive": [ - { - "id": "-010-015", - "title": "'010'015", - "images": [ - { - "uri": "https://ltho.s3.amazonaws.com/2bafd7a2-fbbb-4904-8e64-ff394888fd24.png", - "label": "LIQUID REFLECTIVE", - "code": "5315 42944", - "caption": "Fabric that is highly reflective owing to its coating made up\r\nof thousands of glass microspheres. Each finished garment\r\nis hand sprayed individually and individually baked dry.\r\nThe varying intensity of the reflective element and varying\r\nintensity of color, the dribbling and speckled effect, are\r\nowing to the high level of craftsmanship involved in the\r\nprocess, making each garment unique and unrepeatable.\r\nLining in quilted microfiber with polyester padding.\r\nStone Island badge with white embroidery, reserved for\r\ngarments that are made using advanced research into\r\nfabrics or processes." - }, - { - "uri": "https://ltho.s3.amazonaws.com/a0714935-2800-425f-9b34-63fdc4a7fc78.png", - "label": "30/30 JACKET", - "code": "5715 4TTY2", - "caption": "The 30/30 jacket is a cross section of the state of the art of Stone Island. A testament to three decades of exploration and development, it has been designed to embody the spirit of Stone Island’s endless creativity. Linked by the signature looped rigging system, both the jacket shell and jacket liner are reversible. These can be worn, either together or alone, in a total of 10 different ways. The transformative\r\nproperties of the fabrics mean that these 10 ways can each be worn in 3 different modes: Ice, Reflective,\r\nand Normal; resulting in a total of 30 different jacket states.\r\nThis piece features is our 30th anniversary special edition badge.\r\nJACKET /SHELL _ RASO GOMMATO PRISMATIC COVER.\r\nSatin weave cotton of military origin bonded on the inside to a a shiny transparent fine-grained polyurethane film reflecting the light, magnifying the color effects and bestowing the surface with a three-dimensional and ‘liquid’ appearance.\r\nJACKET/ LINER_ THERMO REFLECTIVE / ENGINEERED WOOL\r\nThis material merges two of Stone Island’s most avant-garde research paths. It explores the interaction between light refraction and thermosensitivity technologies. The resins used to coat the nylon substrate host both the glass microspheres allowing fabric refraction and the micro-encapsulated pigments modifying the passage of light and thus enabling color changes in relation to temperature. The final effect is an organic and dynamic interaction of light and color. On the reverse side, an engineered wool face made with a double knit machine." - }, - { - "uri": "https://ltho.s3.amazonaws.com/d51dce63-d467-45ea-88a6-5b077ffe3c3c.png", - "label": "REFLECTIVE KNIT WITH WINDSTOPPER® 3L", - "code": "5715 587Y5", - "caption": "To celebrate the thirtieth anniversary of Stone Island, a yarn has been engineered that represents the\r\nheight of our tireless research. The President’S Knit 5715 has been created in Reflective yarn, made\r\nup of micro plates coated with glass microspheres trapped inside a polyester mesh. The structure of\r\nthe jumper has been made double, reflective on the outside and wool on the inside. The outer face\r\nhas then been printed in a darker shade using heat and pressure sublimation printing to amalgamate\r\nthe fibers, obtain an even surface and reduce the strong reflective appearance.\r\nThe detachable padded and quilted lining has been created in a polyester jersey laminated with a\r\nWindstopper® membrane, which provides an unbeatable balance between protection and comfort.\r\nThis piece features is our 30th anniversary special edition badge." - }, - { - "uri": "https://ltho.s3.amazonaws.com/5883b275-a2eb-4a34-890f-69b30250a62b.png", - "label": "RASO HAND PAINTED TORTOISE SHELL", - "code": "6115 70565", - "caption": "Trench coat in a satin-weave cotton fabric of military origin. The garment has been dyed and then faded in selected areas with a corrosive paste. The bleached parts have then been hand-painted with a tortoiseshell-inspired motif also appearing on the Stone Island badge on the left sleeve. This extraordinary manual process makes each piece unique and unrepeatable. Detachable hood in garment-dyed padded iridescent nylon. Detachable lining in GARMENT-DYED DOWN_26 GR X SQM_N, an ultra-light nylon weighing only 26 grams per square meter, filled with the finest down specially treated to bear the stress of the garment dyeing procedure. Garment-dyed with special dye recipes. It is secured to the outer garment by the iconic Stone Island fastening system." - }, - { - "uri": "https://ltho.s3.amazonaws.com/a25cc013-5c2c-4221-974a-987b8fd00ab4.png", - "label": "HAND PAINTED SHEEPSKIN", - "code": "6115 00379", - "caption": "Sheepskin parka. The finished piece has been hand-sprayed on the outer face with a resin based product and then hand waxed to achieve a softer feel. Hood edged by fur trim. " - }, - { - "uri": "https://ltho.s3.amazonaws.com/fa5ed231-8b04-4ecc-b126-7a5543d5614a.png", - "label": "ICE JACKET THERMO-SENSITIVE FABRIC", - "code": "6115 43098", - "caption": "Hooded jacket in thermo sensitive fabric. A water- and wind-resistant polyurethane film is embedded with micro-encapsulated pigments. The molecules of these pigments modify the path of light and change color according to the temperature. The garment is then padded with the finest down.Two chest patch pockets, with snap-flap fastening and second pocket with vertical zip fastening. Adjustable elastic at cuffs. Cotton terry lined hood. Hidden zip and button fastening." - }, - { - "uri": "https://ltho.s3.amazonaws.com/bfd9defc-a1ef-4322-9e53-9505ec606ed9.png", - "label": "RASO GOMMATO REVERSE COLOR PROCESS", - "code": "6215 42338", - "caption": "Jacket in Raso Gommato -rubberized satin- a mil. spec. cotton satin bonded with a polyurethane cover making the fabric wind and water resistant. In this version, the transparent cover is bonded to a previously piece dyed and printed the cotton satin. The finished garment undergoes an exclusive procedure named Reverse Color Process, a fading technique followed by an overdyeing process on the finished garment, owing to the piece unparalleled shaded print effects, resist print areas and residual color deposits, unique to each single item." - }, - { - "uri": "https://ltho.s3.amazonaws.com/390b68f3-7f9a-41af-a09c-bd15ac7008a3.png", - "label": "POLYPROPYLENE TELA", - "code": "6315 40534", - "caption": "Down filled parka in polypropylene tela treated with an anti-drop agent. Polypropylene, a material with antibacterial properties, is the lightest man-made fibre. Even very bulky garments astonish for their specific lightness. The paste colored yarn is texturized to obtain a cotton looking opaque aspect. " - }, - { - "uri": "https://ltho.s3.amazonaws.com/cc9f8c72-bbac-4d34-9762-4eae85374abf.png", - "label": "HIDDEN REFLECTIVE", - "code": "6315 G0598", - "caption": "Vest in a reflective, water and wind resistant polyester fabric owing its features to a coating made of thousands of glass microspheres. An opaque black plating totally covers the refraction of the material which is unveiled when photographed in flash mode. The reflective features will be revealed through usage, with diverse effects and intensities from piece to piece, depending on its wearer usage. Stone Island logo on the back obtained through laser printing. Filled with the finest down. Sheepskin over collar. " - }, - { - "uri": "https://ltho.s3.amazonaws.com/512029b0-f4a3-469a-9d7d-1cd7fc15c1c8.png", - "label": "POLY COVER COMPOSITE + POLY FUR SILVER DETACHABLE LINING", - "code": "6315 491Y1", - "caption": "Hooded jacket in Poly Cover Composite, a matte, colorless and opaque two-component water and wind resistant film. The garment dyeing technique colors the film without affecting its transparency. Completely heat sealed seams.\r\nDetachable hooded lining in Poly Fur, a synthetic fur with external silver colored coating. Snap fastening on nylon tape." - } - ], - "__index": "4", - "dateCreated": "Thu, 05 Nov 2015 01:48:39 GMT" - }, - { - "id": "-000-009", - "title": "'000'009", - "images": [ - { - "uri": "https://ltho.s3.amazonaws.com/725e1b3f-58ee-49f6-8413-0a7e3dc9890f.png", - "label": "KEVLAR®", - "code": "3315 4031", - "caption": "Kevlar® felt. Five times more robust than steel given the same weight, Kevlar® is lightweight and\r\nhighly insulating. It is resistant to even extreme changes in temperature and to both fresh and salt\r\nwater. Owing to its qualities, it is used in the aerospace field, in competitive sailing and for Formula\r\n1 racing. With its soft yellow color, dyeing this material is usually impossible, but with Stone Island\r\ngarment dyeing expertise, laminating the hydro-cohered Kevlar® fibers to an invisible nylon mesh and\r\na polyurethane coating on the outer side and a simple polyurethane coating on the inside this has been\r\nmade possible.\r\nDetachable lining in triple woven fabric, two nylon honeycomb patterns have been machine raised\r\nwith a further nylon yarn. The detachable lining is attached to the outer garment using a system of ties,\r\nadapted from those used in the sailing world. Stone Island badge with white embroidery, reserved for\r\ngarments that are made using advanced research into fabrics or processes." - }, - { - "uri": "https://ltho.s3.amazonaws.com/c1c9db4f-5aa9-4698-9fe3-04a58a631653.png", - "label": "MONOFILAMENT-S", - "code": "3715 4316", - "caption": "Nylon twill monofilament mesh. On the inside, a cotton muslin\r\nlayer is laminated on the outer face with a black breathable\r\nand water resistant membrane, with the application of\r\nwhite polyester taped seams. The monofilament mesh has\r\na protecting function for the inner membrane. From the\r\naesthetic point of view, its transparency is designed to reveal\r\nthe internal construction of the garment. The piece is lined in\r\na brushed cotton fabric quilted with polyester padding. The\r\nfinished garment is over-dyed with a double cotton and nylon\r\nrecipe." - }, - { - "uri": "https://ltho.s3.amazonaws.com/4f1783c2-1ff7-4054-9d18-faebbd617305.png", - "label": "LIGHT", - "code": "3715 4Q30", - "caption": "Stone Island anticipated the use of light in clothing. Also for safety purposes in cases of\r\ndiminished visibility. The beginning of the Nineties, saw the introduction of the Reflective\r\nJacket - the first reflective garment ever - and in ‘002, to mark its twentieth anniversary,\r\nthe use of light went from being passive to active and self-generated with the use of optical\r\nfibres.\r\nThe fabric’s cotton warp is woven with polyester yarns as well as with optical fibre\r\nfilaments forming a band of light along the front fastening and around the edge of the hood.\r\nThe light is switched on using a small battery hidden inside the garment.\r\nHooded detachable lining in microfiber quilted to a polyester padding, attached to the\r\nouter garment using a system of ties, adapted from those used in the sailing world." - }, - { - "uri": "https://ltho.s3.amazonaws.com/c62f3de3-a639-4818-988c-3aba9db057e5.png", - "label": "COMPACT", - "code": "3915 4N40", - "caption": "Compact treated linen felt. The Compact process is the transfer to finished garments of a textile process that is usually used to cleanse the natural fibers of their impurities. The garments are boiled at 130°C under pressure, with special additives. In the finished garments the material shrinks approximately 50%, the material becomes extraordinarily compact, the hand of the fabrics becomes dryer and naturally elastic. The fabrics take on an uneven, hand crafted appearance, as if they had been woven on antique looms. The fabric volume reduction involved with the Compact treatment creates very important pattern making complexities. The garment can be fitted to the body with a strings and loops system on the sides, front and hood. This system is inspired by anti-G suits of military aviators. Garment dyed; Compact pieces are very receptive to the garment dyeing recipes, the colors result far more intense than those of untreated garments.\r\nDetachable lining in peached microfiber, quilted with polyester padding. The detachable lining is attached to the outer garment using a system of ties, adapted from those used in the sailing world." - }, - { - "uri": "https://ltho.s3.amazonaws.com/ba287902-7b92-4128-867f-69d6b1e40cc0.png", - "label": "OPAQUE NYLON TELA", - "code": "4315 4C24 30GR", - "caption": "Japanese featherweight nylon canvas, weighing just 30 grams per square\r\nmeter. The Stone Island badge is ultra light, in embroidered nylon mesh in\r\norder to avoid weighing down the sleeve. The garment is padded with the\r\nfinest down. The lightweight construction of the down bags and the direct\r\ninjection of feathers heightens the lightness of the garments." - }, - { - "uri": "https://ltho.s3.amazonaws.com/320c3a59-c8ae-4dec-b863-15b15ccc368a.png", - "label": "OPAQUE NYLON CANVAS", - "code": "4515 4H24", - "caption": "Japanese featherweight nylon canvas, weighing just 37 grams\r\nper square meter. The Stone Island badge is ultra light, in\r\nembroidered nylon mesh in order to avoid weighing down the\r\nsleeve. The garment is padded with direct injection finest down.\r\nApart from highlighting the lightness of the fabric, the black\r\nedging under the fabric underscores the removal of the feather\r\nbags to increase the lightness of the garment. The yoke on the\r\nchest is disguised by the horizontal quilting motive. Inside the\r\nhood of the garment, an extra fabric hood with external coating\r\nand PVC print may be laced up by loops." - }, - { - "uri": "https://ltho.s3.amazonaws.com/35f9ec2a-fc52-42e5-b015-899e40ae9e89.png", - "label": "DAVID-TC SUBLIMATION PRINT", - "code": "4615 4C44", - "caption": "Reversible garment. Star-shaped cross-section polyester / polyamide\r\nJapanese microfiber. During garment dyeing under pressure at 130°C,\r\nthe heat transforms the structure and hand of the material radically.\r\nBeyond the depth of color and despite maintaining an industrial\r\nappearance, the David-TC garments take on an appearance and\r\nhand that grant a unique tactile experience, similar to both chamois\r\nleather and non-woven coagulated fabric. One of the two faces has\r\nbeen over printed on the finished garment with a dark color, using\r\na hot sublimation / pressure printing technique that reveals the\r\nconstruction details of both sides of the garment." - }, - { - "uri": "https://ltho.s3.amazonaws.com/03785345-d63c-4c18-addf-fb7461949cec.png", - "label": "ANTIQUED REFLECTIVE", - "code": "4715 7423", - "caption": "Cotton Batavia with a coating made up of thousands of glass microspheres. Antiqued Reflective fabric\r\nhas a strong capacity to reflect even the weakest light sources and is enhanced by a color patina that is\r\nparticularly evident in the folds of the garment, granting to the piece a three-dimensional appearance.\r\nThe shape and details of the garment have been deliberately designed with a retro style in order to\r\ncreate a contrast with the modernity of the reflective face. The hood is lined in a khaki colored wool\r\nwith parallel stripes, reminiscent of military blankets.\r\nDetachable lining in microfiber quilted to a thin polyester padding. The lining is attached to the outer\r\ngarment using a system of ties, adapted from those used in the sailing world.\r\nStone Island badge with white embroidery, reserved for garments that are made using advanced\r\nresearch into fabrics or processes." - }, - { - "uri": "https://ltho.s3.amazonaws.com/b7b6db65-3688-4472-839d-38852b074790.png", - "label": "RASO GOMMATO - HAND PAINTED CAMOUFLAGE", - "code": "4915 4C43", - "caption": "Drawing inspiration from the actions of soldiers during the First World War, who\r\nused earth from the trenches to make their uniforms dirty, thus inventing the\r\nconcept of camouflage, the fabric base in black satin weave cotton of military\r\norigin bonded to a black polyurethane cover on the inner face, has been faded\r\nwith a corrosive paste and then hand painted on the finished garment to create\r\na camouflage effect. By means of this manual process, each garment is rendered\r\nunique and unrepeatable.\r\nThe detachable quilted nylon lining with polyester padding, with front edging\r\nand collar in felted wool, is attached to the outer garment using a system of ties,\r\nadapted from those used in the sailing world." - }, - { - "uri": "https://ltho.s3.amazonaws.com/9a25ed8c-2293-4d6e-b63a-c17580113d63.png", - "label": "WAXED ICE - THERMO SENSITIVE FABRIC", - "code": "5115 7498", - "caption": "Cotton moleskin with a resin treatment containing thermo sensitive\r\nquartz. The color of the garment ranges from bright yellow at\r\nroom temperature to a deeper and deeper shade of olive green as\r\nthe temperature drops. The garment is washed and then waxed.\r\nThe detachable black woolen lining with Stone Island logo in the\r\ncentre is attached to the outer garment using a system of ties,\r\nadapted from those used in the sailing world.\r\nStone Island badge with white embroidery, reserved for garments\r\nthat are made using advanced research into fabrics or processes." - } - ], - "__index": "3", - "dateCreated": "Thu, 05 Nov 2015 01:49:03 GMT" - }, - { - "id": "-990-999", - "title": "'990'999", - "images": [ - { - "uri": "https://ltho.s3.amazonaws.com/f58db57f-a469-4c7b-b248-6cab5a927c8a.png", - "label": "RASO GOMMATO COLORED COVER", - "code": "05 4001", - "caption": "Satin weave cotton of military origin bonded to a\r\nmustard yellow polyurethane cover on the outside\r\nand white on the hood. The inner fabric face takes its\r\ncoloring from garment dyeing. Double parallel row\r\nof snap fasteners mounted on small rubber disks\r\nallow the garment to be tightened or loosened to fit." - }, - { - "uri": "https://ltho.s3.amazonaws.com/56189889-630b-4293-95e9-2c747d1209fe.png", - "label": "ICE JACKET CAMOUFLAGE THERMO-SENSITIVE FABRIC", - "code": "05 4N06", - "caption": "Cotton poplin with a camouflage print in a thermo-sensitive\r\ncoating with liquid crystals that change color based on\r\nthe temperature. Over dyed on the finished garment. As the\r\ntemperature drops, the fabric print gradually disappears\r\nas it takes on the same shade as the solid color of the\r\ngarment dye." - }, - { - "uri": "https://ltho.s3.amazonaws.com/d46fc981-d51c-4001-a72a-7d5bc3bedc15.png", - "label": "RUBBERISED SATIN SILVER COVER", - "code": "35 4405", - "caption": "Satin weave cotton of military origin bonded to a silver\r\npolyurethane cover on the outside. Padded with goose down.\r\nDouble parallel row of snap fasteners mounted on small rubber\r\ndisks allow the garment to be tightened or loosened to fit.\r\nLining in colored peached polyester microfiber. Hood in the\r\nRaso Gommato Silver Cover garment dyed, with detachable wolf\r\nfur edging." - }, - { - "uri": "https://ltho.s3.amazonaws.com/65a6a008-a634-4155-8dba-0e2f22e1dc74.png", - "label": "REFLECTIVE JACKET", - "code": "1815 4N02", - "caption": "Owing to a coating made up of thousands of glass\r\nmicrospheres on a polyester base, the Reflective\r\nfabric has a strong capacity to reflect even the\r\nweakest light sources. It reflects and intensifies\r\nthe brightness of the color of the fabric itself,\r\nparticularly if placed in the dark. If it is photographed\r\nusing a flash, it detracts light from the other\r\ncomponents in the shot, which show up as black.\r\nPocket linings in cotton mesh." - }, - { - "uri": "https://ltho.s3.amazonaws.com/7011fe4a-22de-4bf0-bd4d-4440c49d8409.png", - "label": "WQR WATER RESISTANT QUILTING", - "code": "2515 6L51", - "caption": "Nylon jersey quilted with polyester padding,\r\nwith a special external coating used to close\r\nall the needle holes produced in the quilting\r\nprocess, rendering the garment totally\r\nwaterproof. The garment takes its final\r\ncoloring from garment dyeing." - }, - { - "uri": "https://ltho.s3.amazonaws.com/ca0447d1-3bd3-4702-a7d5-f1da98764ffb.png", - "label": "LINO GOMMATO REVERSE COLOR PROCESS", - "code": "2815 4P49", - "caption": "Black linen canvas bonded to a transparent polyurethane\r\ncover on the outside. By means of an exclusive process\r\ncarried out on the finished garment, the original color of\r\nthe fabric is corroded, with the exclusion of the Stone Island\r\nlettering, of the two parallel stripes and of the name of the\r\nprocess on the left sleeve. The collar, placket, pocket flaps,\r\ncuffs and bottom hem are less faded owing to the double\r\nlayer of fabric and the seams. Light garment over dye." - }, - { - "uri": "https://ltho.s3.amazonaws.com/23b746d9-311b-4f9f-b356-d1f49046bda9.png", - "label": "THE PRESIDENT’S KNIT", - "code": "2915 5784", - "caption": "The President’s Knit is the name of a knitted garment introduced in the autumn winter ‘998-’999\r\nseason and then retaken with different processes in the years that followed. It is an innovative knitted\r\ngarment that takes on the functions of a jacket owing to its detachable lining.\r\nThe first of these garments was created in a double face knit, nylon chenille on the outside, cotton on\r\nthe inside. Three black nylon parallel stripes on the cuff. Ends of the sleeves and bottom hem as well\r\nin black nylon. The garment takes its final coloring from garment dyeing.\r\nDetachable lightweight nylon fabric lining with water resistant polyurethane resin finish, quilted\r\nwith polyester padding. The detachable lining is attached to the outer garment using a system of ties,\r\nadapted from those used in the sailing world." - }, - { - "uri": "https://ltho.s3.amazonaws.com/ebaf6ae8-f465-4a8d-b6d0-ff45a93f0350.png", - "label": "LAMINATE - NOC 1", - "code": "3015 4C41", - "caption": "Two ultra light cotton gauzes laminated by means of a\r\nmatte colored resin. This slightly stretch fabric provides\r\ntechnical features owing to its light lamination. This fabric\r\nhas a natural appearance but high-tech performance and\r\nis waterproof, windproof and breathable. Fully thermotaped\r\nseams on the inside.\r\nInjection moulded PVC NOC 1 hood. The shape of the\r\nhood is taken by the shape of gas masks. A research by\r\nStone Island into the making of non-fabric components." - }, - { - "uri": "https://ltho.s3.amazonaws.com/a39caa9e-4dbe-4c31-8bda-41ebc2a508b4.png", - "label": "PURE METAL SHELL – BRONZE", - "code": "3115 4T43", - "caption": "100% bronze mesh applied to a black nylon jersey base. The polyurethane adhesive\r\nprovides a light protection for the mesh. A Teflon® treatment makes the garment water\r\nresistant. The metal mesh is a living material with the features of metallic materials when\r\nused untreated, and therefore they are subject to oxidation over time, losing its shine.\r\nThe worn look, creases and breaks that form on the surface are features that make each\r\ngarment different from the next.\r\nDetachable woolen lining with raw cut edging, attached to the outer garment using a\r\nsystem of ties adapted from those used in the sailing world.\r\nThe Autumn Winter ´999-´000 collection saw the introduction of the Stone Island badge\r\nwith white embroidery, dedicated to garments created using advanced research into\r\nfabrics or processes." - }, - { - "uri": "https://ltho.s3.amazonaws.com/f221b596-7cc0-493c-9cea-6755f64d1641.png", - "label": "PURE METAL SHELL - SILVER SPRAY", - "code": "3115 4U39", - "caption": "Ultra light polyester fabric with the application, through\r\na patented procedure, of a micro stainless steel film in a\r\nvacuum and sterile environment. This Japanese fabric,\r\nused in airplanes to shield the on-board computers from\r\nelectromagnetic radiation. Cotton canvas lining. The garment is\r\npadded with goose down.\r\nThe Autumn Winter ´999-´000 collection saw the introduction\r\nof the Stone Island badge with white embroidery for pieces\r\ninvolving advanced research." - } - ], - "__index": "2", - "dateCreated": "Thu, 05 Nov 2015 01:49:20 GMT" - }, - { - "id": "-982-989", - "title": "'982'989", - "__index": "1", - "dateCreated": "Wed, 02 Dec 2015 05:15:20 GMT", - "images": [ - { - "uri": "https://ltho.s3.amazonaws.com/e486c7c7-798e-4bf7-9e67-973f2cb02368.png", - "label": "TELA STELLA", - "code": "45 4NN", - "caption": "Stone Island was founded on this fabric. Tela Stella was born out of the study\r\nof the technical and functional characteristics of military truck tarpaulins. It\r\nis a cotton canvas impregnated on both sides with special pigmented resins\r\nin contrasting colors. The finished garment then undergoes an extended\r\nenzyme wash in order to give it a faded look and to break down the density of\r\nthe material. The result is a windproof garment that has an air of old oilskins\r\ncorroded by the sea, which, at the same time, has a marked military feel." - }, - { - "uri": "https://ltho.s3.amazonaws.com/757164f9-0699-482a-9187-e7d097f84319.png", - "label": "TELA STELA DUAL COATED", - "code": "65 404", - "caption": "Cotton canvas impregnated on both sides with special pigmented resins in contrasting colors.\r\nWhite outside, sand colored inside. Garment dyed midnight blue; a mélange effect is obtained with\r\ndifferent textured depths of color on the outside and inside of the garment. Appliqués in reflective\r\nfabric and stretch cotton tape on the pockets. Metal buckles on the bottom hem. Long cotton strap\r\nsewn under the collar label and attached to one of the buckles by means of a snap hook to allow the\r\ngarment to be worn over the shoulders." - }, - { - "uri": "https://ltho.s3.amazonaws.com/eb9cadb6-9712-41cf-9984-086518c7c391.png", - "label": "TELA STELLA DUAL COATED", - "code": "65 410", - "caption": "Cotton canvas impregnated on both sides with special pigmented resins in\r\ncontrasting colors. White outside, sand colored inside. Neither washed,\r\nnor garment dyed, it maintains the body and intensity of the coating.\r\nAppliqués in reflective fabric and stretch cotton tape. Adjustable straps at\r\nthe sides." - }, - { - "uri": "https://ltho.s3.amazonaws.com/8237f317-5272-4760-a6ab-b56c475b50d3.png", - "label": "JOCK-23", - "code": "75 436", - "caption": "Cotton canvas with thick matte PVC coating. Appliqués in the same fabric\r\nwith contrasting color coating. On the back, appliqué in mélange felted wool\r\npolyester on the collar. On the inside the neckline and shoulders are lined\r\nin cotton jersey. Rubber buttons created from a mould. Detachable lining in\r\ngarment dyed cotton fleece, attached with snap fasteners." - }, - { - "uri": "https://ltho.s3.amazonaws.com/c790cbf7-0a92-449e-8557-f6174946ab68.png", - "label": "JOCK-23", - "code": "75 460", - "caption": "Cotton canvas with thick matte PVC coating. Hood and buckled inserts at the cuff, with\r\ncontrasting color coating. Appliqué in latex right around the edge. Metal eyelets.\r\nRubber buttons created from a mould." - }, - { - "uri": "https://ltho.s3.amazonaws.com/1062f397-c1d7-4012-ae8d-9ddf13363743.png", - "label": "JOCK-23", - "code": "75 409", - "caption": "Cotton canvas with thick matte PVC coating. Inner flap in a contrasting\r\ncolor. Collar in felted wool polyester, lined with latex. Latex band at cuffs.\r\nRubber buttons created from a mould. Detachable lining in garment dyed\r\ncotton fleece, attached with snap fasteners." - }, - { - "uri": "https://ltho.s3.amazonaws.com/5f315b73-1572-460c-abfe-cda498886abe.png", - "label": "RASO GOMMATO BLACK COVER", - "code": "35 4NN", - "caption": "Satin weave cotton of military origin bonded to a black\r\npolyurethane cover on the inside. The garment takes its\r\nfinal coloring from garment dyeing. Detachable hood in Silk\r\nLight, an ultra light, slightly resin treated shiny trilobate nylon\r\nfabric, quilted with polyester padding.\r\nDetachable lining in Silk Light, quilted with polyester padding.\r\nThe detachable lining is attached to the outer garment using\r\na system of ties, adapted from those used in the sailing world.\r\nThe hood and detachable lining are also garment dyed." - }, - { - "uri": "https://ltho.s3.amazonaws.com/cd370f63-4fab-41e1-bbb6-d9e4955d068e.png", - "label": "GLAZED SILK LIGHT", - "code": "55 4910", - "caption": "Fine shiny trilobate nylon with thick, glazed effect\r\nPVC coating, creating a translucent, semi-transparent\r\nappearance. Hood part lined in a layer of PVC and with a\r\nstrip of honeycomb pattern non-woven fabric in microfibre.\r\nPVC windproof cuffs inside the sleeves. Lining made with\r\na layer of heat-sealed PVC, with interlining in polyester\r\nmesh quilted with polyester padding. The piece takes its\r\nfinal color from a double cotton and nylon garment dyeing\r\nrecipe, to obtain different shades on the finished garment." - }, - { - "uri": "https://ltho.s3.amazonaws.com/417e64df-f318-4500-977b-2eaed1668bc4.png", - "label": "RASO GOMMATO BLACK COVER", - "code": "65 4A10", - "caption": "Satin weave cotton of military origin bonded to a\r\nblack polyurethane cover on the inside. Removable\r\neye mask in the hood, which folds away in the\r\ncollar. The garment takes its final coloring from\r\ngarment dyeing." - }, - { - "uri": "https://ltho.s3.amazonaws.com/93d8d8fa-ad6e-4fe5-9182-c9e45c7e4ff5.png", - "label": "NYLON RIP-STOP COVER", - "code": "75 4503", - "caption": "Khaki iridescent nylon with rip-stop twill, laminated on the\r\noutside with a transparent amber polyurethane film. The\r\ndepth of color is obtained by adding together the color of\r\nthe textile base and that of the coating. Lined in iridescent\r\nnylon rip-stop quilted with polyester padding." - } - ] - } - ], - "hub": [ - { - "id": "ss_-016-collection-preview", - "date": "Tue, 12 Jan 2016 12:00:00 GMT", - "title": "SS_'016 COLLECTION PREVIEW", - "subtitle": "Stone Island App exclusive 1/12-1/19", - "body": "The unrelenting research by Stone Island results in a collection full of textiles evolutions, finishing and dyeing, featuring pop colors and extraordinary visual effects.\r\n\r\n44447 NYLON METAL WATRO\r\nHooded blouson in Nylon Metal. Hood with half lining in cotton and half in nylon mesh. Slanting hand pockets with windproof entrance and zip fastening. Adjustable strap at cuffs. Drawstring in bottom hem. Zip fastening. \r\nNYLON METAL WATRO: The trilobate structure of the nylon yarn, with its grey weft and white ready to dye warp colors, is the grounds of the distinctive metallic and tonic sheen of Nylon Metal, one of the most versatile fabrics born of Stone Island’s textile research. The fabric is resin treated inside to achieve a mild wind and water resistance The finished piece undergoes an elaborate double dye procedure providing different tones, intensities and colors to the fibers and textile accessories of the garment. The addition of a special agent to the dye formula makes the piece anti-drop.\r\n\r\n10544 NYLON METAL \r\nOver shirt in Nylon Metal. Garment dyed. Hook fastening collar. On seam pocket along central placket, with snaps fastening. Snap-fastened cuffs. Hidden zip and snap fastening.\r\nNYLON METAL: The trilobate structure of the nylon yarn, with its grey weft and white ready to dye warp colors, is the grounds of the distinctive metallic and tonic sheen of Nylon Metal, one of the most versatile fabrics born of Stone Island’s textile research. The finished piece undergoes an elaborate double dye procedure providing different tones, intensities and colors to the fibers and textile accessories of the garment. The addition of a special agent to the dye formula makes the piece anti-drop.\r\n\r\n70532 POLYESTER SHANTUNG\r\nParka in an organic looking polyester. Hood with visor and chin strap adjustable with Velcro. Two bellows pockets on chest with flap closed by hidden snaps. Two welt pockets closed by a zip with a second snap opening that holds a cotton tape belt. Snap fasteners at cuffs. Zip and hidden button fastening.\r\nPOLYESTER SHANTUNG: organic looking polyester material with a shantung effect. The organic look is given by the highly technological spinning of the raw material and by its super tight weaving. The pieces are sewn and then garment dyed under pressure at 130°C with the addition of an anti-drop agent. The high pressure dye process compacts the material and induces the high absorption of the color recipe.\r\n\r\n41923 MEMBRANA 3L TC\r\nHooded jacket in a light 3 layers fabric. Garment dyed. Adjustable straps on hood with elasticated gathering on back. Patch pockets with zip fastening. Adjustable straps at cuffs. Elasticated adjustable drawstring on bottom edge. Zip fastening. \r\nMEMBRANA 3L TC: 3 layer light performance fabric made from an opaque nylon outer face laminated to a breathable, water resistant, windproof membrane, protected by an impalpable polyester base. Stone Island’s expertise in garment dyeing gives an outstanding color to the outer face while preserving the performance features of the inner membrane. The addition of a special agent to the dye formula makes the piece anti-drop.\r\n\r\n65260 T.CO+OLD\r\nHooded full zip sweatshirt in malfilé cotton, garment dyed to create the OLD effect, an exclusive dyeing treatment and subsequent fading on the finished garment to create a slightly worn and three-dimensional appearance. Hood drawstring in contrasting color. Pouch pockets. Ribbed side band, cuffs and bottom band. Zip fastening.\r\n\r\n530B0\r\nCardigan knit in plain stitching cotton nylon. Raised collar with concealed hood in Nylon Metal. Garment dyed. On seam pockets. Plain cuffs and bottom band with inner ribbing. Zip fastening.\r\nNYLON METAL: The trilobate structure of the nylon yarn, with its grey weft and white ready to dye warp colors, is the grounds of the distinctive metallic and tonic sheen of Nylon Metal, one of the most versatile fabrics born of Stone Island’s textile research. ", - "link": "", - "store": "true", - "image": [ - { - "uri": "https://ltho.s3.amazonaws.com/1ee6abef-0677-41a6-91eb-029303995073.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/8cc1876a-10c7-4dc5-af66-18f5d1a30727.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/f83bf094-ddee-4d26-938e-d98eef0cb0eb.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/095b2d00-cda6-4275-a475-cf2b27965c29.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/b7b299c4-0f24-4d27-91c3-b2a0856e49f0.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/cb2378dd-2eff-4d92-a942-63da8f3afcea.png", - "caption": "" - } - ], - "__index": 1, - "dateCreated": "Tue, 12 Jan 2016 15:55:24 GMT" - }, - { - "id": "nikelab-x-stone-island-windrunner", - "date": "Wed, 09 Dec 2015 12:00:00 GMT", - "title": "NikeLab x Stone Island Windrunner", - "subtitle": "", - "body": "NikeLab partners with Stone Island to deliver a unique interpretation of its foremost apparel icon, to celebrate the beginning of  “The Year of Windrunner.\r\n\r\n “An exciting co-lab. Stone Island loves challenges. We source our strength from challenges. It’s a great satisfaction to share our knowhow and expertise with Nike”.\r\nCarlo Rivetti – Stone Island President and Creative Director\r\n \r\nThe Nike Windrunner was born during a time of firsts. Created by Nike’s first apparel designer in 1978 and revolutionary for its raglan sleeves and 26-degree chevron yoke, the jacket became the first piece of Nike apparel worn by athletes at track and field trials before and after competition. Today, to commemorate this running icon, the Nike Windrunner experiences another first, the fabric innovation, the engineering and garment dyeing techniques of Stone Island.\r\n \r\nIn 2016 Nike is celebrating its foremost apparel icon: the Nike Windrunner Jacket. Designed in the late ‘70s, the silhouette has been a fixture on medal stands and city streets ever since. In the launch edition of this yearlong celebration Nike and Stone Island merge the distinctiveness of two brands to create a unique garment.\r\n \r\nThe chevron and hood of the NikeLab x Stone Island Windrunner are constructed with water and wind-resistant Mussola Gommata fabric, formed by bonding lightweight cotton muslin to an opaque polyurethane film. Nylon Metal, a proprietary Stone Island fabric with a metallic sheen, is featured on the body of the garment, which is lined with PrimaLoft®.\r\n \r\nWhile the exterior of the jacket is monochromatic, it mimics the traditional Nike Windrunner color blocking through Stone Island’s garment dyeing process. The result is a subtle distinction between the shades of the Mussola Gommata and Nylon Metal fabrics. The silver PrimaLoft® lining provides a stunning contrast to the monochromatic exterior, while the oversized trims contribute to a rugged look.\r\n \r\nThe NikeLab x Stone Island Windrunner will be available on December 17th at 10am PST from the Stone Island App and selected NikeLab retailers and on nike.com/nikelab.", - "link": "http://www.stoneisland.com/experience/us/nikelab-x-stone-island/", - "store": "true", - "image": [ - { - "uri": "https://ltho.s3.amazonaws.com/de454e51-59d6-4442-9faa-70d95203f6dd.jpg", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/faeb5522-8793-4a81-882f-3c378cef3192.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/1c7b2292-f4c9-4d4e-869a-4d4cad2a3820.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/0444066e-e3e7-484f-b932-43c855e2fa96.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/d5577c40-4e42-4738-be8b-12066f7a4301.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/540f859f-9684-412d-a012-bb1c2bd45bf6.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/a92f9dd6-09d2-48fb-8858-7c12693c302e.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/a46824b3-90ad-466d-97ab-090022363fa7.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/e234f3cb-38d8-442a-9bb9-95a90b166d20.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/607814ee-1435-42f5-b52d-fb7fe2001b6d.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/21475b14-e216-438a-8673-106d9322bf3e.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/131e1276-aed1-4790-8ab9-333393c3885a.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/e2808d55-7d9a-4c99-842d-16a0a300c93d.png", - "caption": "" - } - ], - "__index": 4, - "dateCreated": "Tue, 12 Jan 2016 16:02:48 GMT" - }, - { - "id": "nikelab-x-stone-island-koth-ultra-mid-si", - "date": "Wed, 09 Dec 2015 12:00:00 GMT", - "title": "NikeLab x Stone Island Koth Ultra Mid SI", - "subtitle": "", - "body": "Inspired by the Nike Air Mowabb, the revolutionary 1991 sneaker-hiker hybrid, this all-weather Nike Koth Ultra Mid SI Shoe is made in Nike water resistant materials, real leather, and in Mussola Gommata, a fabric issued from the Stone Island research and treatment research, an exclusive panel dyed material made by bonding an extremely light cotton muslin to an opaque polyurethane film. The shoe features aggressive traction and flexible ankle support. Unitsole foam midsole for cushioning and durable support. Waffle rubber lugs for rugged traction and durability. Flex grooves allow for natural range of motion. Heel loop for easier on and off. Heel overlay for enhanced support. The shoe dust bag is made in 2 Stone Island fabrics, Nylon Metal, nylon canvas with a distinctive metallic and iridescent sheen, 50 Fili, a cotton/nylon canvas, both panel dyed.\r\n\r\nThe NikeLab x Stone Island Koth Ultra Mid SI will be available on December 17th at 10am PST from the Stone Island App and selected NikeLab retailers and on nike.com/nikelab.\r\n", - "link": "http://www.stoneisland.com/experience/us/nikelab-x-stone-island/", - "store": "true", - "image": [ - { - "uri": "https://ltho.s3.amazonaws.com/dd5f611f-3800-49ed-a6b1-9f6dd06cc103.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/34185ef2-1658-4472-bc3a-4d3f0c23ba2f.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/4767f114-1e8e-4ed3-856c-74f6c4342f0f.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/ed510070-9f60-45a6-aebf-2e7684b67cb3.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/c32af490-4ae5-4040-9327-02ce8808ee71.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/b913fc7d-d5d8-4047-b252-c2f404d9cb3e.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/3bea1cd4-2529-4a06-99ec-ec55c5a9f8d5.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/e29264fd-4236-4d16-938f-7dbe264c9b88.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/9c445717-dc18-4e0f-95f4-f695b13547a2.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/63cb328c-2624-4ed1-9d1e-113649be7f26.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/8ef50cce-c89d-4642-98b9-3be6ff798727.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/46f320b1-b908-42b5-9cad-20689c4d0d23.png", - "caption": "" - } - ], - "__index": 5, - "dateCreated": "Tue, 12 Jan 2016 16:03:00 GMT" - } - ], - "page": [ - { - "id": "terms-and-conditions", - "title": "Terms and Conditions", - "image": { - "uri": "", - "caption": "" - }, - "body": "
TERMS AND CONDITIONS OF USE
\r\nWelcome to www.stoneisland.com. These terms and conditions (the “General Terms and Conditions of Use”) govern your use of, access to, and purchase of products from the United States section of www.stoneisland.com (the \"US Site\"). By using the US Site, you agree to comply with and be bound by these General Terms and Conditions of Use. If you do not agree to these General Terms and Conditions of Use, please do not use the US Site.\r\n\r\n1. GENERAL\r\nwww.stoneisland.com is the property of SPORTSWEAR COMPANY, a company having an address at Galleria Cavour 4, 40124 Bologna, Italy (\"STONE ISLAND and STONE ISLAND DENIMS\") and is operated under license by YOOX Corporation, a Delaware corporation having an address at 148 Lafayette Street, 10th Floor, New York, NY, 10013, United States of America (the \"Provider\"). \r\n\r\n2. OTHER SITE POLICIES\r\nPlease review our General Terms and Conditions of Sale, Return Policy and Privacy Policy (collectively, the “Site Policies\"). All Site Policies are incorporated in these General Terms and Conditions of Use by this reference and, therefore, apply to your access to, use of and purchase of products from the US Site. If you do not agree to our Site Policies, please do not use the US Site. We reserve the right to make changes to the US Site, the Site Policies, and these General Terms and Conditions of Use at any time. If any of these conditions shall be deemed invalid, void, or for any reason unenforceable, that condition shall be deemed severable and shall not affect the validity and enforceability of any remaining condition. \r\n\r\n3. PURCHASE FOR PERSONAL USE ONLY\r\nYou may purchase products on the US Site only for personal use and not for resale. By placing your order, you certify that you are purchasing products for personal use only and not for resale and you accept our General Terms and Conditions of Sale. WE RESERVE THE RIGHT TO REFUSE ORDERS FOR ANY REASON WITHOUT EXPLANATION. \r\n\r\n4. USER'S SUBMISSIONS\r\nWe welcome your comments and feedback regarding the US Site, our products and our services. We do not, however, accept confidential or proprietary information. Accordingly, all comments, feedback, reviews, ideas, suggestions, materials, images, information and other submissions (collectively, the “Submissions”) disclosed, submitted or offered to the Provider via the US Site, or otherwise, are not confidential. You represent and warrant that any Submissions that you submit to the Provider are made in compliance with applicable laws, do not violate any right of any third party, including privacy and intellectual property rights. By disclosing, submitting or offering any Submissions to the Provider, you grant the Provider and STONE ISLAND and STONE ISLAND DENIMS a nonexclusive, royalty-free, perpetual, irrevocable, and fully sublicensable right to use, reproduce, modify, adapt, publish, translate, create derivative work from, distribute, display such Material throughout the world in any media. You are and shall remain solely responsible for any Submissions you disclose, submit or offer to the Provider or STONE ISLAND and STONE ISLAND DENIMS. \r\n\r\n5. PRIVACY\r\nWe recommend that you read our Privacy Policy, which explains our online privacy practices. \r\n\r\n6. COPYRIGHT\r\nAll content included on www.stoneisland.com US Site, such as works, images, pictures, dialogues, music, sounds, videos, documents, drawings, figures, logos, menus, web pages, graphics, colors, schemes, tools, fonts, designs, diagrams, layouts, methods, processes, functions and software (collectively, the \"Content\"), is the property of STONE ISLAND and STONE ISLAND DENIMS or its content suppliers and is protected by national and international copyright and other intellectual property laws. You may not reproduce, publish, distribute, display, modify, create derivative work from, or exploit in any way, in whole or in part, the Content without the prior express written consent of STONE ISLAND and STONE ISLAND DENIMS, or its content suppliers, as the case may be. STONE ISLAND and STONE ISLAND DENIMS and its content suppliers shall have the exclusive right to authorize or prohibit in their sole discretion any reproduction, publication, distribution, display, modification, creation of derivative work from, or exploitation in any way of, in whole or in part, the Content. STONE ISLAND and STONE ISLAND DENIMS and its content suppliers shall have the right, at any time, to claim the authorship of any Content posted on the US Site and to object to any use, distortion or other modification of such Content. Any reproduction, publication, distribution, display, modification, creation of derivative work from, or exploitation in any way of, the Content expressly authorized in writing by STONE ISLAND and STONE ISLAND DENIMS or its content suppliers shall be carried out by you for lawful purposes only and in compliance with all applicable laws. \r\n\r\n7. LICENSE AND SITE ACCESS\r\nThe viewing, printing or downloading of any Content from the US Site grants you only a limited, nonexclusive and nontransferable license for use solely by you for your own personal use and not for republication, distribution, assignment, sublicense, sale, preparation of derivative works or other use. No part of any Content may be reproduced in any form or incorporated into any information system, electronic or mechanical, other than for your personal use (but not for resale or redistribution). Any unauthorized use of the US Site and the Content immediately terminates the license granted by the Provider. \r\nYou will be solely responsible for all damages and other harm resulting from your use of the US Site and the Content. STONE ISLAND and STONE ISLAND DENIMS and the Provider shall not be deemed liable for any use of the US Site and the Content made by you in violation of any applicable laws and regulations and these General Terms and Conditions of Use. \r\n\r\n8. COPYRIGHT COMPLAINTS\r\nWe respect the intellectual property of others. If you believe that your work has been copied in a way that constitutes copyright infringement, please contact a STONE ISLAND and STONE ISLAND DENIMS copyright representative for further information at privacy@mail.stoneisland.com. \r\n\r\n9. LINKS TO OTHER WEB SITES\r\nThe US Site may provide hyperlinks to third party websites (“Third Party Websites\"). The Provider and STONE ISLAND and STONE ISLAND DENIMS do not operate, control, endorse or guarantee any Third Party Websites. You agree that the Provider and STONE ISLAND and STONE ISLAND DENIMS are not responsible for any content, services and/or products provided by any Third Party Website, nor are the Provider and STONE ISLAND and STONE ISLAND DENIMS responsible for any practice followed by such Third Party Website with respect to the collection and processing of personal data of their users. When you access any Third Party Website through a hyperlink posted on the US Site, please carefully read the terms and conditions of use, privacy policy and other policies of such Third Party Website. Our policies do not apply to any Third Party Website. \r\nYou The Provider provides hyperlinks to Third Party Websites only for the convenience of its users. By providing hyperlinks to Third Party Websites, the Provider does not recommend that its users access such Third Party Websites. \r\n\r\nYOU AGREE THAT YOUR USE OF ANY THIRD PARTY WEBSITE IS AT YOUR SOLE RISK AND WITHOUT WARRANTIES OF ANY KIND BY THE PROVIDER, EXPRESSED, IMPLIED OR OTHERWISE, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY OR NONINFRINGEMENT. UNDER NO CIRCUMSTANCES ARE THE PROVIDER AND/OR STONE ISLAND and STONE ISLAND DENIMS LIABLE FOR DAMAGES ARISING FROM ANY TRANSACTION BETWEEN YOU AND ANY THIRD PARTY WEBSITE OR FOR ANY INFORMATION APPEARING ON THIRD PARTY WEBSITES. \r\n\r\n10. GOVERNING LAW AND CHOICE OF FORUM\r\nThe laws of the State of New York (without giving effect to its conflicts of law principles) govern all matters arising out of or relating to these General Terms and Conditions of Sale, including, without limitation, their validity, interpretation, construction, performance, and enforcement. All legal proceedings arising out of or in connection with these General Terms and Conditions of Sale shall be brought solely in the City of New York, State of New York. \r\n\r\n11. DISCLAIMER OF WARRANTIES AND LIMITATION OF LIABILITY\r\nTHE US SITE AND ALL INFORMATION, CONTENT, MATERIALS, PRODUCTS (INCLUDING SOFTWARE) AND SERVICES INCLUDED ON OR OTHERWISE MADE AVAILABLE TO YOU THROUGH THIS SITE ARE PROVIDED BY THE PROVIDER ON AN \"AS IS\" AND \"AS AVAILABLE\" BASIS, UNLESS OTHERWISE SPECIFIED IN WRITING. THE PROVIDER MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, AS TO THE OPERATION OF THIS SITE OR THE INFORMATION, CONTENT, MATERIALS, PRODUCTS (INCLUDING SOFTWARE) OR SERVICES INCLUDED ON OR OTHERWISE MADE AVAILABLE TO YOU THROUGH THIS SITE, UNLESS OTHERWISE SPECIFIED IN WRITING. YOU EXPRESSLY AGREE THAT YOUR USE OF THIS SITE IS AT YOUR SOLE RISK. \r\n\r\nTO THE FULL EXTENT PERMISSIBLE BY APPLICABLE LAW, THE PROVIDER DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE PROVIDER DOES NOT WARRANT THAT THIS SITE; INFORMATION, CONTENT, MATERIALS, PRODUCTS (INCLUDING SOFTWARE) OR SERVICES INCLUDED ON OR OTHERWISE MADE AVAILABLE TO YOU THROUGH THIS SITE; THEIR SERVERS; OR E-MAIL SENT FROM THE PROVIDER ARE FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. THE PROVIDER WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING FROM THE USE OF THIS SITE OR FROM ANY INFORMATION, CONTENT, MATERIALS, PRODUCTS (INCLUDING SOFTWARE) OR SERVICES INCLUDED ON OR OTHERWISE MADE AVAILABLE TO YOU THROUGH THIS SITE, INCLUDING, BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, PUNITIVE, AND CONSEQUENTIAL DAMAGES, UNLESS OTHERWISE SPECIFIED IN WRITING. \r\n\r\nCERTAIN STATE LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS, EXCLUSIONS, OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MIGHT HAVE ADDITIONAL RIGHTS.\r\n\r\n
TERMS AND CONDITIONS OF SALE
\r\nThe following General Terms and Conditions of Sale govern the sale of merchandise by YOOX Corporation, an affiliate of YOOX NET-A-PORTER GROUP S.p.A. (the \"Provider\" or \"we\") to you through the US section of www.stoneisland.com (\"US Site\"). The US Site is available only for purchases made and delivered within the United States. Your use of the US Site to purchase merchandise indicates your agreement to follow and to be bound by these General Terms and Conditions of Sale.\r\n\r\n1. ORDERS & PRODUCTS\r\nAll orders are subject to e-mail confirmation by us. Please note that the products displayed on the US Site may be out-of-stock or discontinued, and availability is not guaranteed. Please note that while we have tried to accurately display the colors of products, the actual colors you see will depend on your monitor and may not be accurate. \r\n\r\n2. PRICES\r\nAll prices are in US Dollars. Prices may change without notice from time to time. The total amount due is inclusive of sales tax applied in accordance with applicable state and local regulations based on your shipping address. The applicable sales tax amount is indicated on the payment page of the cart.\r\n\r\nThe amount of sales tax charged on your order will depend upon various factors, including type of item purchased, sales price and destination of the shipment. Sales tax regulations may change between the time you place an order and the time of credit card charge authorization and this may affect the calculation of sales taxes. The amount appearing on your payment page of the cart may differ from the sales taxes ultimately charged as indicated in the invoice you will receive with the shipping confirmation e-mail.\r\n\r\nAll prices are inclusive of customs and import duties.\r\n\r\n3. SHIPPING COSTS\r\nYou are responsible for the shipping costs associated with the delivery of the products you purchase on the US Site as specified on your order confirmation. \r\n\r\n4. SHIPMENTS AND DELIVERY\r\nYou bear all risks of loss and damage to the products from the time the same have cleared our fulfillment house. Delivery is deemed complete and title to the products passes to you upon acceptance of shipment by a common carrier.\r\n\r\n5. RETURNS AND REFUNDS\r\nPlease refer to our Return and Refund Policy, which forms an integral part of these General Terms and Conditions of Sale. \r\n\r\n6. BINDING AGREEMENT\r\nOur order confirmation, these General Terms and Conditions of Sale and our other Site Policies shall be deemed the final and integrated agreement between you and us on the matters contained in these General Terms and Conditions of Sale. \r\n\r\n7. GOVERNING LAW AND CHOICE OF FORUM\r\nThe laws of the State of New York (without giving effect to its conflicts of law principles) govern all matters arising out of or relating to these General Terms and Conditions of Sale, including, without limitation, their validity, interpretation, construction, performance, and enforcement. All legal proceedings arising out of or in connection with these General Terms and Conditions of Sale shall be brought solely in the City of New York, State of New York. \r\n\r\n8. DISCLAIMERS AND LIMITATIONS OF LIABILITY\r\nTHE PROVIDER MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, AS TO THE PRODUCTS INCLUDED IN THE www.stoneisland.com US SITE NOR AS TO THE MERCHANDISE BEING SOLD TO YOU. TO THE FULLEST EXTENT PERMISSIBLE BY APPLICABLE LAW, THE PROVIDER DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, AND THERE ARE NO WARRANTIES, EXPRESS OR IMPLIED, WHICH EXTEND BEYOND THE DESCRIPTION OF THE MERCHANDISE CONTAINED ON OUR ORDER CONFIRMATION. THE PROVIDER WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING FROM THE USE OF THE US SITE, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, PUNITIVE AND CONSEQUENTIAL DAMAGES \r\nCERTAIN STATE LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS, EXCLUSIONS, OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MIGHT HAVE ADDITIONAL RIGHTS.\r\n\r\n9. SEVERABILITY\r\nIf any provision of these General Terms and Conditions of Sale is determined to be invalid, illegal or unenforceable, the remaining provisions of these General Terms and Conditions of Sale remain in full force to the extent permitted by law.\r\n\r\n10. PRIVACY\r\nThe terms and conditions of the our Privacy Policy govern the processing of all personal data collected from you in connection with your purchase of products through the US Site.\r\n\r\n11. FORCE MAJEURE\r\nProvider shall not be liable for any delay or failure in performance caused by circumstances beyond its reasonable control.\r\n\r\n12. ERRORS AND INACCURACIES\r\nOur goal is to provide complete, accurate, and up-to-date information on our website. Unfortunately, it is not possible to ensure that any website is completely free of human or technological errors. This website may contain typographical mistakes, inaccuracies, or omissions, some of which may relate to pricing and availability, and product information. We reserve the right to correct any errors, inaccuracies or omissions, including after an order has been submitted, and to change or update information at any time without prior notice.\r\n", - "__index": "1", - "dateCreated": "Tue, 17 Nov 2015 20:31:52 GMT", - "tag": "terms" - }, - { - "id": "privacy-policy", - "title": "Privacy Policy", - "image": { - "uri": "", - "caption": "" - }, - "body": "Welcome to www.stoneisland.com. Please read our Privacy Policy carefully. This Privacy Policy applies when you visit and surf the United States section of www.stoneisland.com (the \"www.stoneisland.com US Site\") regardless of whether you purchase products or not, when you register with the www.stoneisland.com US Site, and when you use our services. By using the www.stoneisland.com US Site, you accept the practices described in this Privacy Policy. If you do not want to accept the practices described in this Privacy Policy, please do not use the www.stoneisland.com US Site. \r\nThe www.stoneisland.com US Site is operated under license by , a Delaware corporation having an address at 148 Lafayette Street, 10th Floor, New York, NY, 10013, United States of America (\"YOOX USA\"). YOOX USA is a subsidiary of YOOX NET-A-PORTER GROUP S.p.A., an Italian company having its registered address at via Morimondo, 17 – Milano 20143 (\"YOOX\") and controls the personal data of users and customers of the www.stoneisland.com US Site together with SPORTSWEAR COMPANY, having address at Galleria Cavour 4, 40124 Bologna, Italy, Italy, VAT, 01046470371 (jointly referred to as \"YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY\"). \r\nSince personal data of users and customers of the www.stoneisland.com US Site may be processed in Italy, any such processing of personal data will be conducted in compliance with applicable US law as well as the Italian Data Protection Code (Legislative Decree no. 196 dated June 30, 2003). Pursuant to the Italian Data Protection Code, YOOX USA is the controller of personal data of users and customers of the www.stoneisland.com US Site. As controller of personal data, YOOX USA independently determines the purposes and means by which your personal data are processed, including all security measures. As required by the Italian Data Protection Code, YOOX USA has appointed YOOX NET-A-PORTER GROUP as its data protection representative in Italy. As our data protection representative in Italy, YOOX, together with SPORTSWEAR COMPANY, independently ensures that personal data are processed in Italy in a correct and lawful manner and in accordance with good practice.\r\n\r\n1. OUR POLICY\r\nEveryone has the right to the protection of his/her personal data. YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY respect our users' right to be informed about the collection and processing of their personal data. The www.stoneisland.com US Site has been designed in such a way that the use of your personal data will be minimal and will not exceed the original purpose for which your personal data are collected and/or processed. In particular, we do not disclose your identity when the purpose for which your personal data are being processed can be achieved by using anonymous aggregate information. This Privacy Policy is intended to provide you with all the information you need in order to understand our privacy practices.\r\nHowever, if you have any questions regarding our privacy practices and this Privacy Policy, please contact us at the following e-mail address:privacy@mail.stoneisland.com.\r\nThe www.stoneisland.com US Site is not directed at, nor do we knowingly collect personally identifiable information from children under the age of 13, although we may sell children's products or services for purchase by adults. If you are under 18, you may use the www.stoneisland.com US Site only with the involvement of a parent or guardian. \r\n\r\n2. WHO PROCESSES YOUR PERSONAL DATA\r\nFor organizational and operational purposes only, YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY have appointed certain entities that will also process personal data of users and customers of the www.stoneisland.com US Site. Such purposes are strictly connected to the performance of services provided on the www.stoneisland.com US Site by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY, including the sale of products.\r\nThe above-mentioned data processors have been chosen by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY because of their experience in processing personal data, their sufficient guarantees with respect to compliance with applicable laws and regulations, including the Italian Data Protection Code (Legislative Decree no. 196 of 30 June 2003) as well as the technical security measures adopted by them in connection with the processing of personal data. In processing personal data of the users of the www.stoneisland.com US Site, our processors will act only in accordance with instructions provided by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY. We regularly verify that our processors comply with our instructions and that they provide sufficient guarantees with respect to their compliance with applicable laws and regulations. The following is a list of the companies primarily involved in the processing of personal data of users and customers of the www.stoneisland.com US Site:\r\n\t•\tUnited Parcel Service S.p.A.(“UPS\"). We provide UPS, by electronic means, with customers' addresses and other personal data for the purpose of shipping, delivering and returning products purchased on the www.stoneisland.com US Site;\r\n\t•\tBT Italia S.p.A., for purposes related to the maintenance of YOOX NET-A-PORTER GROUP servers;\r\n\t•\tYOOX NET-A-PORTER GROUP Italy. We provide YOOX NET-A-PORTER GROUP Italy with personal data of users and customers for purposes related to direct marketing services of YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY and in connection with other services provided by YOOX NET-A-PORTER GROUP Italy to YOOX USA, such as call center and help desk services.\r\nPlease contact our Customer Care or send us an e-mail at privacy@mail.stoneisland.com if you would like to receive a full list of our data processors.\r\n\r\n3. HOW DO WE USE PERSONAL DATA AND FOR WHAT PURPOSES\r\nYour personal data are collected and processed by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY for purposes which are strictly connected to the use of the www.stoneisland.com US Site, its services and the purchase of products on the www.stoneisland.com US Site. However, your personal data may also be used for other processing operations within the limits of such purposes. In particular, your personal data may be processed for the following purposes:\r\n\t•\twhen you register with the www.stoneisland.com US Site we collect your personal data (for example, your personal information, e-mail address, gender) through the relevant registration form (My Account) in order to provide you with services in reserved access areas of the www.stoneisland.com US Site and in order to send you our Newsletter, when specifically requested;\r\n\t•\twhen you request Customer Care services, we collect your personal data (for example, your password) for purposes strictly necessary to provide you with customer care services relevant to the US Site and to the purchase of products on the US Site;\r\n\t•\twhen you request Customer Service assistance, we collect your personal data (for example, your first and last names, e-mail address and password) for purposes strictly necessary to provide you with Customer Service relevant to the www.stoneisland.com US Site and to the purchase of products on the www.stoneisland.com US Site;\r\n\t•\twhen you are executing purchasing procedures for products sold on the www.stoneisland.com US Site, including conclusion of an agreement for the purchase of products, we collect your personal data (for example, personal information, e-mail address, address, Credit Card numbers, bank account number and telephone number) on your order form only for the purpose of selling the products ordered by you;\r\n\t•\twhen you request technical assistance, we collect your personal data in order to provide you with information on net-surfing, Internet browsing or viewing and downloading web pages;\r\n\t•\twhen creating your Wish List, we process your personal data in order to customize our services for the purchase of products on the www.stoneisland.com US Site.\r\nYour personal data are generally processed by electronic means; however, in certain circumstances, paper-based means may be used (for example, when the processing of your personal data is required for the prevention of fraud against us). Your personal data are stored in a way which allows YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY to identify you for the period that is strictly necessary for the original purposes for which such personal data are collected and subsequently processed, all in accordance with applicable laws.\r\nPlease report any changes to your personal data to the e-mail address privacy@mail.stoneisland.com in order to ensure that your personal data are always accurate and kept up-to-date.\r\nYour personal data will not be disclosed to third parties for purposes not permitted by law or without your explicit consent. Your personal data may only be disclosed to third parties when it is necessary to process an order placed by you. For example, your personal data are disclosed to Banca Sella S.p.A. for the performance electronic payment services, through Credit/Debit Cards. Moreover, your personal data may be disclosed to the police or to judicial authorities, in compliance with applicable laws and regulations and upon a formal request by such authorities for the purposes of preventing a fraud against us (anti-fraud services). Data processors will also have access to your personal data, as stated in Section 2 of this Privacy Policy, for the specific purposes stated in that Section. In all the above circumstances, your consent for data processing will not be specifically requested.\r\nYour personal data will not be transferred to any countries outside the United States and Italy if such countries do not provide for an adequate level of protection of the privacy of individuals. Should the above be necessary in order to supply services to you or to execute contracts for the purchase of products, the transfer of your personal data to any such countries will be carried out only after the execution of specific contracts between YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY and all parties involved, in accordance with applicable laws and regulations.\r\nWe wish to inform you that YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY process users' personal data for purposes that are strictly connected to the supply of services through the www.stoneisland.com US Site, the execution of contracts related to the sale and purchase of products on the www.stoneisland.com US Site and, after receiving your consent, in order to send you information on new commercial initiatives which are strictly related to the www.stoneisland.com US Site's activities and services. YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY process your personal data for direct marketing purposes, including by e-mail, only after receiving your consent.\r\nYOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY may have access to third parties' personal data which is directly disclosed by their users to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY, for instance when the user buys a product to be sent to a friend, when the user who pays the purchase price for a product is different from the recipient of such product, or when a user wishes to recommend to a friend a service provided through the www.stoneisland.com US Site or the sale of a particular product posted on the www.stoneisland.com US Site.\r\nIn all cases involving the disclosure of information of a third party, you must obtain the consent of such individuals before disclosing their personal data to YOOX USA, YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY and have informed said individuals about this Privacy Policy. You will be the only person liable in connection with the disclosure of information and data relevant to such third parties and with any other incompatible and unlawful use of such data if they have not provided you with their consent. You agree to indemnify, defend and hold each of YOOX USA, YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY harmless from any liability, claims and expenses, including reasonable attorneys' fees, arising from or related to any unauthorized disclosure of personally identifiable information of third parties.\r\n\r\n4. WHAT HAPPENS IF YOU DO NOT DISCLOSE YOUR PERSONAL DATA\r\nThe personal data we request you to provide to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY, including your e-mail address, your address, your Credit/Debit Card numbers, bank account number and your telephone number, is necessary for the processing of your order for the purchase of products on the www.stoneisland.com US Site, to supply other services provided on the www.stoneisland.com US Site upon your request, or to carry out obligations arising out of applicable laws and regulations.\r\nYour refusal to provide certain personal data to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY may prevent YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY from processing your order for the purchase of products sold on the www.stoneisland.com US Site or from providing other services through the www.stoneisland.com US Site, such as Customer Services, sending the Newsletter, use of the Wish List, recommending a product to a friend.\r\nYour failure to provide personal data to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY may prevent the processing of your order for the purchase of products sold or to provide services through the www.stoneisland.com US Site. \r\nThe disclosure of personal data to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY other than that required in order to fulfill legal or contractual obligations or to provide the services requested by you is optional and does not have any effect on the use of the www.stoneisland.com US Site and its services or on the purchase of products on the www.stoneisland.com US Site. We will inform you if the personal data we ask you to provide is necessary or optional by marking with an asterisk (*) the information that is necessary. Your failure to disclose optional personal data will not pose any obligation or disadvantage to you, except to the extent that we may no be able to offer you some of our optional, personalized features of the www.stoneisland.com US Site. \r\n\r\n5. TO WHOM YOUR PERSONAL DATA WILL BE DISCLOSED \r\nYour personal data may be disclosed to third parties who provide specific services as Data Processors on behalf of YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY or who autonomously process personal data collected by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY in connection with the performance of a contract for the purchase of products on the www.stoneisland.com US Site (for example, Banca Sella, S.p.A.). \r\nAny such disclosure will be conducted, in each instance, without exceeding the original purposes for which your personal data were collected and subsequently processed. In addition, your personal data may be disclosed to third parties in order to (1) comply with applicable laws, (2) respond to governmental and judiciary inquiries, (3) comply with valid legal process, and (4) protect the rights or property of YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY. \r\nAny third party information disclosed to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY in accordance with this Privacy Policy will not be used for any purpose other than as required to technically operate the service, to complete a transaction, or as otherwise required by law. \r\nIn the event there is a change in the corporate structure of YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY including, without limitation, by merger, consolidation, sale, liquidation, or transfer of substantial assets, YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY may, in their sole discretion, transfer, sell or assign personal data collected on and through the www.stoneisland.com US Site, including, without limitation, personally identifiable information and aggregate information concerning users and customers, to one or more affiliated or unaffiliated third parties. \r\nIn any event, your personal data will not be disclosed to third parties without you being informed or without your consent, when such consent is required by law.\r\n\r\n6. HOW DO WE COLLECT YOUR DATA ON www.stoneisland.com \r\nCookies\r\nWhen you are using the www.stoneisland.com US Site, some personal data may be collected automatically through so-called \"cookies\". A cookie is a device transmitted to the hard drive of an Internet user. While cookies do not contain intelligible information, they allow us to link an Internet user to personal information provided by such user through the www.stoneisland.com US Site. YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY process information collected by cookies in a collective and anonymous way, in order to optimize our services and the www.stoneisland.com US Site for the needs and preferences of its users. We use cookies to collect users' IP addresses and other information regarding users' data traffic or preferences in the choice of services provided and products purchased through the www.stoneisland.com US Site.\r\nWe disseminate cookies in connection with functions such as browsing the catalogue, purchasing products on-line and supplying \"My Account\" services.\r\nAs you may know, each Internet browser allows the deletion of cookies after each session. Your Internet browser contains instructions on how to carry out these procedures of deletion. Please access the appropriate instructions section on your Internet browser if you wish to delete cookies. \r\nYour acceptance of our automatic procedures of collection of data and the use of cookies is necessary to take advantage of many features and services offered by the www.stoneisland.com US Site, including the purchase of products. If you set your browser to block or delete cookies, we cannot guarantee that you will have access to all the features and services offered by the US Site (for example, your computer may not be able to display the image of the product you are in the process of purchasing).\r\nOther Methods of Collecting User Information. \r\nYOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY directly collect personal data and information from users when they register on-line with the www.stoneisland.com US Site or when they send purchase orders for products sold on the www.stoneisland.com US Site in order to finalize their transactions.\r\n\r\n7. SECURITY MEASURES\r\nWe have adopted security measures to protect personal data against accidental or unlawful destruction, loss, alteration, unauthorized disclosure or access and against other unlawful forms of data processing, as provided in our Privacy Policy. \r\nNevertheless, YYOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY cannot guarantee that the security measures adopted for the protection of the www.stoneisland.com US Site and the transmission of data and information through the www.stoneisland.com US Site will prevent or exclude any risk of unauthorized access to or loss of data. It is advisable that your computer be equipped with software devices for the protection of network data transmission and receipt (such as, updated antivirus systems) and that your Internet service provider take appropriate measures for the security of network data transmission (such as, firewalls and anti-spam filtering).\r\n\r\n8. OPT-IN/OPT OUT Advertising material and direct marketing or other commercial communications which are not specifically requested by you or necessary to provide a service you requested, including the purchase of products on the US Site, will be sent to you only after we receive your consent. Please note that each time your consent is required, we will inform you in advance and we will give you the option to either provide or refuse your consent by selecting the appropriate box.\r\nYOOX and STONE ISLAND and STONE ISLAND DENIMS may process your personal data without your consent when such processing is necessary to comply with applicable laws and regulations or to provide you with services you requested, including the purchase of products on the US Site.\r\nEven when your prior consent is not necessary, you may exercise, at any time, your right not to receive future communications regarding services you requested, such as the Newsletter.\r\n\r\n9. YOUR RIGHT TO ACCESS PERSONAL DATA AND FURTHER RIGHTS\r\nYou are entitled to obtain, at any time, confirmation from YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY as to whether or not data relating to you is being processed, even if not yet registered, and the communication of any such data in an intelligible form. \r\nMoreover, you are entitled to receive from YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY information on the source from which we received your personal data; the purposes and means of processing your personal data; the logic involved in any electronic data processing; information regarding the data controller and the data processors and the names of subjects and categories of subjects to whom your personal data may be disclosed or who may access your personal data (for example, the names of data processors). You can also find the above information in our Privacy Policy. \r\nYou are entitled to obtain at any time from YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY:\r\n\t•\tthe updating, rectification or integration of your personal data;\r\n\t•\tthe deletion, transformation into anonymous form or blocking of your personal data, which are processed in violation of the law, including when the storage of data is not necessary for the purposes for which it has been collected and subsequently processed;\r\n\t•\tthe confirmation that the operations under letters a) and b) have been reported to whom the data were disclosed or disseminated, except when it becomes impossible to do so or if it means exceeding the protection of the right you are claiming.\r\nYou are entitled to object, in all or in part:\r\n\t•\tfor legitimate reasons, to the processing of your personal data, even if it is related to the purposes for which it was collected;\r\n\t•\tto the processing of your personal data for advertising or direct marketing purposes or in order to carry out marketing research or commercial communications.\r\nYou may freely and at any time exercise your rights, provided that you do so in compliance with applicable laws and regulations, by sending your request to YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY at the following e-mail address: privacy@mail.stoneisland.com.\r\n\r\n10. LINKS TO OTHER WEB SITES\r\nThe www.stoneisland.com US Site may provide hyperlinks to third party websites (the \"Third Party Websites\"). YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY do not operate, control, endorse or guarantee any Third Party Websites. You agree that and SPORTSWEAR COMPANY are not responsible for any content, services and/or products provided by any Third Party Website, nor are YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY responsible for any practice followed by such Third Party Website with respect to the collection and processing of personal data of their users. When you access any Third Party Website through a hyperlink posted on the www.stoneisland.com US Site, please carefully read the Privacy Policy and other policies of such Third Party Website.\r\nOur Privacy Policy and other policies do not apply to any Third Party Website. YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY provide hyperlinks to Third Party Websites only for the convenience of our users. By providing hyperlinks to Third Party Websites, YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY do not recommend that users access such Third Party Websites.\r\nYOU AGREE THAT YOUR USE OF ANY THIRD PARTY WEBSITE IS AT YOUR SOLE RISK AND WITHOUT WARRANTIES OF ANY KIND BY YOOX, YOOX USA, AND/OR SPORTSWEAR COMPANY, EXPRESSED, IMPLIED OR OTHERWISE, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY OR NONINFRINGEMENT. UNDER NO CIRCUMSTANCES ARE YOOX, YOOX USA, AND/OR SPORTSWEAR COMPANY LIABLE FOR DAMAGES ARISING FROM ANY TRANSACTION BETWEEN YOU AND ANY THIRD PARTY WEBSITE OR FOR ANY INFORMATION APPEARING ON THIRD PARTY WEBSITES. \r\n\r\n11. CONTACTS\r\nIf you wish to receive further information regarding our privacy practices, please contact us at the following e-mail address: privacy@mail.stoneisland.com. For more information regarding your rights under the Italian Data Protection Code, please go to the web site of the Italian Data Protection Authority at www.garanteprivacy.it. \r\n\r\n12. GOVERNING LAW\r\nThe processing of personal data by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY will be conducted in compliance with applicable US laws. The laws of Italy, including the Italian Personal Data Protection Code (Legislative Decree no. 196 dated June 30, 2003), also apply to the processing of personal data carried out by YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY (see the Companies of YOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY Group). The Italian Personal Data Protection Code guarantees that the processing of your personal data will be carried out in compliance with the fundamental rights and freedoms of individuals and their dignity, with particular reference to confidentiality, identity and the right to personal data protection. \r\n\r\n13. MODIFICATION AND UPDATING\r\nYOOX NET-A-PORTER GROUP and SPORTSWEAR COMPANY may amend or update from time to time all or any part of this Privacy Policy, whether or not required by a change in the applicable laws and regulation. Our users will be notified of any amendment to or update of our Privacy Policy on our homepage. All amendments and updates will become effective upon publication on this section of the www.stoneisland.com US Site. You should regularly access this section of the www.stoneisland.com US Site in order to review the most recent and updated version of our Privacy Policy.", - "__index": "2", - "dateCreated": "Tue, 17 Nov 2015 20:32:07 GMT", - "tag": "privacy" - }, - { - "id": "returns-policy", - "title": "Returns Policy", - "image": { - "uri": "", - "caption": "" - }, - "body": "We want to make sure that you are completely satisfied with your purchases on this Site. If, for any reason, you are not satisfied with your order, you may return any UNUSED products within twenty (20) days from the date of delivery. Before sending any products back to us, please make sure that all of the following conditions have been correctly satisfied. \r\nThe product you wish to return:\r\n
  • can be sent back to us only after you have completed and submitted the online Return Form available on the www.stoneisland.com US Site within twenty (20) days of delivery; by completing and submitting our online return form you will receive your Return Number, which you must include on your return shipping label;
  • \r\n
  • must be unused, unworn, unwashed and in the same condition in which it was received by you;
  • \r\n
  • must have all disposable seals still attached with the disposable seal that must still be intact;
  • \r\n
  • must be returned complete with all of its parts and accessories;
  • \r\n
  • must be sent in its original packaging;
  • \r\n
  • must be shipped back to our fulfillment house within twenty (20) days of the date of delivery;
  • \r\n
  • must be sent in one single shipment; products that belong to the same order must be returned to us at the same time; and
  • \r\n
  • must be shipped from the United States.
  • \r\nIf all of these conditions are satisfied, we will refund the value of the returned product(s), Sales Tax included, less any original shipping costs. If you send the package with UPS, return shipping costs charged to the customer will correspond to $6.00. If you prefer you can send the return at your expense, with a courier of your choice. We will not issue any refunds for returns that do not satisfy all of the conditions indicated above; provided, however, that you will have the option to request within thirty (30) days of being notified that you are not entitled to a refund that your merchandise be shipped back to you, at your own cost, in the condition in which it was received by Provider’s fulfillment house.\r\nIf you do not request the return of your merchandise within said thirty-day period, you authorize Provider, and any of its affiliates or agents, to dispose of such merchandise as it sees fit. \r\n\r\nSALES OF BEACHWEAR AND UNDERWEAR ARE FINAL. WE RESERVE THE RIGHT TO DESIGNATE ON THE SITE OTHER NON-RETURNABLE MERCHANDISE. ANY SUCH DESIGNATION WILL BE NOTED ON THE DETAIL PAGE OF THE MERCHANDISE WHICH IS NON-RETURNABLE. \r\n\r\nREFUND POLICY\r\nRefunds are processed within approximately three (3) business days of our receipt of your merchandise. Your refund will be credited back to the same payment method used to make the original purchase on the US Site. If you paid by credit card, refund times will depend on the credit or debit card company’s policies. Be aware that the refund date for the credit will coincide with the date of the original payment, therefore you will not be charged any interest fees. If you paid by PayPal (where available), refunds will be credited to your PayPal account and will be visible immediately. The date of reimbursement to the credit card associated with your PayPal account depends on the company that issued the card. WE OFFER NO REFUNDS ON ANY PRODUCTS DESIGNATED ON THIS SITE AS NON-RETURNABLE. \r\n\r\nIDENTIFICATION TAG\r\nAll of our products come with an identification tag with a disposable seal. Please try your item on before removing the tag and seal, since we do not accept returns once the disposable seal has been removed, broken or damaged in any way. Shoes come with a sticker under the sole; if you remove or alter this sticker, you may no longer return your purchase. \r\n\r\nUPS\r\nYour return can be sent to us by UPS, using the pre-printed label which you can find within the original shipment. If you send the package with UPS, return shipping costs charged to the customer will correspond to $6.00. Please visit http://www.ups.com/dropoff?loc=en_US to find the UPS drop-off location nearest to you. If you prefer you can send the return at your expense, with a courier of your choice. We are not responsible for any loss or damage to products if you ship your return without using UPS. \r\n\r\nWE OFFER NO EXCHANGES ON MERCHANDISE PURCHASED ON THE www.stoneisland.com US SITE\r\n\r\nDISCLAIMER OF WARRANTIES AND LIMITATION OF LIABILITY\r\n\r\nPROVIDER MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, AS TO THE PRODUCTS INCLUDED ON THE SITE NOR AS TO THE MERCHANDISE BEING SOLD TO YOU. TO THE FULLEST EXTENT PERMISSIBLE BY APPLICABLE LAW, PROVIDER DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, AND THERE ARE NO WARRANTIES, EXPRESS OR IMPLIED, WHICH EXTEND BEYOND THE DESCRIPTION OF THE MERCHANDISE CONTAINED ON OUR ORDER CONFIRMATION. PROVIDER WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING FROM THE USE OF THE SITE, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, PUNITIVE AND CONSEQUENTIAL DAMAGES. \r\n\r\nCERTAIN STATE LAWS DO NOT ALLOW LIMITATIONS ON IMPLIED WARRANTIES OR THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES. IF THESE LAWS APPLY TO YOU, SOME OR ALL OF THE ABOVE DISCLAIMERS, EXCLUSIONS, OR LIMITATIONS MAY NOT APPLY TO YOU, AND YOU MIGHT HAVE ADDITIONAL RIGHTS.\r\n\r\nForce Majeure\r\nProvider shall not be liable for any delay or failure in performance caused by circumstances beyond its reasonable control.", - "__index": "3", - "dateCreated": "Tue, 17 Nov 2015 21:03:44 GMT", - "tag": "returns" - }, - { - "id": "customer-care", - "title": "Customer Care", - "image": { - "uri": "", - "caption": "" - }, - "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam blandit in risus sit amet maximus. Phasellus ullamcorper auctor fermentum. Aenean diam libero, rhoncus vel efficitur sed, dictum vel neque. Aliquam mollis leo vitae est vehicula, non pulvinar elit congue. Phasellus sit amet mauris neque. Integer volutpat nisl est, vel finibus purus lacinia vehicula. Proin dapibus velit quis sapien ultricies accumsan. Sed accumsan dui id porta efficitur.\r\n\r\nCurabitur pretium ut libero a varius. Morbi in lacinia felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam dolor justo, consequat eu lectus at, interdum sollicitudin arcu. Nunc accumsan velit volutpat, venenatis leo eu, rhoncus nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus semper consequat ipsum, sed fringilla ligula tincidunt at.\r\n\r\nMauris vehicula, purus ut iaculis facilisis, mi leo dignissim libero, at lobortis lectus odio consequat urna. Etiam accumsan volutpat nibh, eget ultricies mi feugiat eu. Duis id aliquam enim. Pellentesque quis enim eu dolor bibendum interdum. Cras ultrices erat velit, eu volutpat erat consequat non. Nam ut nibh facilisis, egestas sapien vitae, scelerisque sapien. Nullam tortor ex, convallis vel nisi vitae, efficitur dapibus nunc. In hac habitasse platea dictumst. Nam posuere ligula lorem, sit amet ultricies odio tristique in. Etiam gravida tincidunt mollis. Duis quis nulla ligula. Etiam ut vehicula tellus. Sed ipsum lacus, tincidunt sit amet velit et, aliquet hendrerit erat. Nam sed velit dapibus, congue odio non, ultrices ligula. Suspendisse at quam eu lorem finibus ultricies id tempus lorem. Nulla vel quam luctus, viverra nulla cursus, faucibus tellus.\r\n\r\nPraesent magna ex, posuere at hendrerit varius, auctor a nisl. Nullam sodales erat ut nisl vestibulum luctus. Donec id sagittis orci. Cras imperdiet, erat non dictum feugiat, elit turpis viverra neque, interdum cursus mi turpis vitae dolor. Suspendisse potenti. Aenean et auctor diam, vel eleifend eros. Praesent viverra felis at enim elementum fermentum. Etiam convallis, elit porta molestie condimentum, arcu ligula vestibulum nisi, et aliquet massa tellus quis eros. Aliquam a dignissim tellus, non ullamcorper purus. Phasellus in risus mattis dui vehicula cursus in at urna.\r\n\r\nCurabitur laoreet lorem eu euismod volutpat. Suspendisse vulputate aliquet tempor. Pellentesque purus augue, eleifend a maximus eu, commodo nec felis. Mauris mattis turpis nec volutpat tincidunt. Mauris imperdiet ante at orci mollis sagittis. Etiam lacus risus, consectetur ut dui non, pulvinar pulvinar libero. Aliquam ut rhoncus justo, quis sollicitudin nisi. Proin et iaculis sem. Pellentesque id tempor elit, et tincidunt nunc. Quisque laoreet et massa quis imperdiet. Morbi dapibus, felis sed auctor porttitor, massa nunc sollicitudin urna, non congue odio enim eget nisi. Suspendisse semper vehicula nisl vitae vehicula. Maecenas sed justo quis nisi auctor ultrices. Nam vel dolor fringilla, accumsan nulla eu, rutrum ex. Donec ante quam, molestie vel ex eget, dictum luctus nunc. Phasellus tincidunt libero non quam finibus, at convallis sem laoreet.\r\n\r\nDonec consequat, leo tincidunt elementum consectetur, nisl augue sollicitudin dolor, vel fringilla dui lorem non enim. Morbi id arcu felis. Integer malesuada ex enim, sed consectetur massa condimentum id. In mollis libero eu neque sollicitudin, sit amet interdum orci bibendum. Curabitur tincidunt purus vel vestibulum placerat. Aliquam erat volutpat. Praesent ac eros diam. Mauris ultrices euismod sodales. Vestibulum dui leo, auctor sit amet finibus eu, suscipit eu diam. Cras ac rhoncus turpis, at sagittis mi. Praesent urna metus, euismod vitae nunc eget, suscipit auctor lectus. Pellentesque maximus arcu justo. Duis mi arcu, rutrum et vulputate nec, mattis sit amet risus. Donec posuere velit sed enim accumsan, eu lobortis nulla sagittis.\r\n\r\nDonec viverra consectetur turpis sit amet malesuada. Sed sit amet urna luctus, sodales est porta, aliquam mi. Curabitur et ullamcorper odio, dapibus facilisis nisl. Fusce tortor leo, mattis sit amet massa ut, ultrices aliquam massa. Pellentesque consectetur metus in molestie egestas. Quisque vehicula at mauris ut eleifend. Duis eu ipsum quis ipsum bibendum luctus.\r\n\r\nSed sed viverra diam. Quisque lacinia nisl orci. Fusce vulputate dui ut nunc vulputate feugiat. Praesent felis quam, semper nec dapibus eget, venenatis vitae leo. Maecenas rutrum egestas dapibus. Vestibulum sodales molestie varius. Ut ac laoreet est, nec posuere ipsum. Cras ac eros sapien. Quisque eu dui lorem. Donec congue varius tortor ac ullamcorper. Curabitur vulputate faucibus finibus. Donec tellus neque, euismod ac aliquet at, vehicula in mauris. Vivamus justo nulla, maximus sit amet quam ac, vulputate dapibus purus. Mauris ante urna, posuere varius vehicula sed, fringilla sed quam. In eget ex tincidunt, ultrices elit id, congue quam. Suspendisse congue tristique dolor, rhoncus venenatis purus tempor at.\r\n\r\nVivamus efficitur, odio in tempor rutrum, quam nunc congue orci, non posuere lorem lacus et arcu. Aenean sit amet diam quis dui dapibus semper ac vitae est. Aenean ornare arcu justo, id sodales odio maximus interdum. Curabitur sit amet augue pretium metus bibendum imperdiet vitae vitae nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc euismod ante eu justo mollis dignissim. Maecenas et velit eu lorem laoreet ornare. Sed accumsan est nec rutrum dignissim.\r\n\r\nIn bibendum mattis ligula. Pellentesque gravida felis sed congue viverra. Nam volutpat quam at velit sodales, nec egestas dolor consectetur. Etiam id tortor tincidunt, sollicitudin risus ut, lacinia diam. Morbi consequat euismod justo vitae sagittis. Pellentesque interdum orci ligula, tincidunt maximus nulla sollicitudin sed. Duis finibus odio eros, eget consequat ante tristique ac. Suspendisse at interdum leo. Nunc sagittis ante ac felis iaculis fermentum. Sed elementum dictum dictum. Aliquam eget metus molestie, varius mi ac, auctor quam.", - "__index": "4", - "dateCreated": "Tue, 17 Nov 2015 21:03:57 GMT", - "tag": "care" - } - ], - "store": [ - { - "id": "stone-island", - "title": "Stone Island", - "StoreIsOpen": "false", - "ClosedStoreImages": [ - { - "uri": "https://ltho.s3.amazonaws.com/fe9a4c24-eb7f-42be-9c36-d0ab5936bb13.png", - "caption": "" - }, - { - "uri": "https://ltho.s3.amazonaws.com/52b447ec-8635-4182-ae39-25dca98afae1.png", - "caption": "" - } - ], - "__index": "0", - "dateCreated": "Fri, 20 Nov 2015 00:45:03 GMT", - "collection": "SS_'016 PREVIEW", - "FitsLarge": "false", - "BackgroundIsGray": "true", - "CollectionId": "33064", - "StoreStatus": "closed", - "OpensOn": "Invalid Date" - } - ] -} \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/deeplink.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/deeplink.js deleted file mode 100755 index 7667cfcd..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/deeplink.js +++ /dev/null @@ -1,5 +0,0 @@ -function handleOpenURL (url) { - console.log("DEEP LINKING DETECTED", url) - url = url.replace("stoneisland:/", "") - app.router.parseRoute( url ) -} \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/geo.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/geo.js deleted file mode 100755 index 22899141..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/geo.js +++ /dev/null @@ -1,71 +0,0 @@ -var geo = (function(){ - var geo = {} - - var polling = false, fetching = false, poll_timeout = null - - geo.fetch = function(){ - fetching = true - navigator.geolocation.getCurrentPosition(geo.success, geo.error, {timeout: 15000}) - } - - geo.success = function(position){ - var lat_str = as_degrees( position.coords.latitude || 40.99167, "N", "S" ) - var lng_str = as_degrees( position.coords.longitude || -74.07944, "E", "W" ) - $(".latlng").html( lat_str + "     " + lng_str ) - geo.done() - } - - geo.error = function(error){ - $(".latlng").html( "+40° 58' 90.9\" N     74° 04' 46.3\" W" ) - geo.done() - } - - geo.done = function(){ - fetching = false - if (polling) { - clearTimeout( poll_timeout ) - poll_timeout = setTimeout(geo.fetch, 15000) - } - } - - geo.start_polling = function(){ - polling = true - if (! fetching) { - geo.fetch() - } - } - - geo.stop_polling = function(){ - polling = false - clearTimeout(poll_timeout) - } - - function as_degrees (n, pos, neg) { - var s = "" - var sig = n >= 0 ? pos : neg - - n = Math.abs(n) - s += Math.floor(n) + "° " - - n %= 1 - n *= 60 - nn = Math.floor(n) - if (nn < 10) nn = "0" + nn - s += nn + "' " - - n %= 1 - n *= 60 - nn = Math.floor(n) - if (nn < 10) nn = "0" + nn - s += nn - - n %= 1 - n *= 10 - nn = Math.floor(n) - s += "." + nn + '\" ' + sig - - return s - } - - return geo -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/push.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/push.js deleted file mode 100755 index 634ffe6d..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/etc/push.js +++ /dev/null @@ -1,77 +0,0 @@ -var push = (function(){ - var appId = "GS82ZxpN8Mecpc53rsyu6aLLGK0W4CKi42J25DLB" - var clientKey = "hQRtQfsgimYnX5PMivtcdXCG9eZhESeyTr0Rd8Sv" - var push = { settings: {} } - var parsePlugin - push.init = function(){ - parsePlugin = window.parsePlugin || { initialize: function(){} } - parsePlugin.initialize(appId, clientKey, push.did_initialize, push.error) - } - push.did_initialize = function() { - parsePlugin.registerCallback('onNotification', function(){ - window.onNotification = push.got_push_notification - }, push.error) - - push.settings.requested = localStorage.getItem("yoox.push_requested") == "true" - push.settings.hub = localStorage.getItem("yoox.push_hub") == "true" - push.settings.store = localStorage.getItem("yoox.push_store") == "true" - - if ( ! push.settings.requested ) { - localStorage.setItem("yoox.push_requested", "true") - push.subscribe("hub", function(){ - push.subscribe("store") - }) - } - } - push.subscribe = function(channel, cb){ - parsePlugin.subscribe(channel, function(){ - push.settings[channel] = true - localStorage.setItem("yoox.push_" + channel, "true") - console.log("subscribed to", channel) - cb && cb() - }, push.error) - } - push.unsubscribe = function(channel, cb){ - parsePlugin.unsubscribe(channel, function(){ - push.settings[channel] = false - localStorage.setItem("yoox.push_" + channel, "false") - console.log("unsubscribed from", channel) - cb && cb() - }, push.error) - } - // parsePlugin.getInstallationId(function(id) { - // var install_data = { - // installation_id: id, - // channels: ['SampleChannel'] - // } - // }, push.error) - push.got_push_notification = function(push_obj) { - // alert('We received this push notification: ' + JSON.stringify(push_obj)); - app.blog.refresh() - - try { - var is_hub = JSON.stringify(push_obj || {}).match(/hub/i) - if (is_hub) { - app.intro.$alert.show().html("[ HUB UPDATED ]") - } - else { - auth.clear_cart() - app.intro.$alert.show().html("[ STORE UPDATED ]") - } - } - catch (e) { - app.intro.$alert.show().html("[ HUB UPDATED ]") - } - - if (push_obj.receivedInForeground === false) { - // TODO: route the user to the uri in push_obj - } - else { - app.route("intro") - } - } - push.error = function(e){ - console.log("push error") - } - return push -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/AddressView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/AddressView.js deleted file mode 100755 index 4a05c4b6..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/AddressView.js +++ /dev/null @@ -1,272 +0,0 @@ - -var AddressView = SerializableView.extend({ - - template: $("#address_template").html(), - - disabled: false, - - events: { - "change [name=Province]": 'update_country', - "focus [name]": 'scroll_up_to_phone', - }, - - initialize: function(opt){ - this.parent = opt.parent - this.checkPhone = 'checkPhone' in opt ? opt.checkPhone : true - this.setElement( this.parent.$(".address") ) - this.$el.html(this.template) - }, - - populate: function(data){ - this.data = data - var address = data.Address.split("\n") - data.Address1 = address[0] - data.Address2 = address[1] - this.$(".address input").val("") - this.load_data(data) - this.update_country() - }, - - validate_presence: { - "Name": "Please enter your first name.", - "Surname": "Please enter your last name.", - "Address1": "Please enter your street address.", - "City": "Please enter your city.", - "ZipCode": "Please enter your zip code.", - }, - - validate_fields: function(data, errors){ - if (this.disabled) { return } - if (this.checkPhone && ! data.Phone) { errors.push([ "Phone", "Please enter your phone number." ]) } - if (this.checkPhone && data.Phone && data.Phone.replace(/[^0-9]/g, "").length < 10) { errors.push([ "Phone", "Phone numbers must be at least 10 digits." ]) } - if (! data.Province || data.Province == "NONE") { errors.push([ "Province", "Please choose your state." ]) } - data.Address = data.Address1 + "\n" + data.Address2 - data.UserId = auth.user_id - delete data.Address1 - delete data.Address2 - }, - - update_country: function(){ - var state = this.$("[name=Province]").val() - console.log(state) - if (CANADIAN_LOOKUP[state]) { - this.$(".country-label").html("CANADA") - } - else { - this.$(".country-label").html("UNITED STATES") - } - }, - - scroll_up_to_phone: function(e){ - app.view.scroller && app.view.scroller.scrollTo(0, -$(e.currentTarget).position().top) - }, - -}) - -var CANADIAN_PROVINCES = "AB BC MB NB NL NS NT NU ON PE SK QC YT".split(" ") -var CANADIAN_LOOKUP = {} -CANADIAN_PROVINCES.forEach(function(k){ CANADIAN_LOOKUP[k] = true }) - -var COUNTRIES = [ - ['Country Name', 'NONE'], - ['United States', 'US'], - ['Abkhazia', 'GE'], - ['Afghanistan', 'AF'], - ['Albania', 'AL'], - ['Algeria', 'DZ'], - ['Andorra', 'AD'], - ['Angola', 'AO'], - ['Antigua and Barbuda', 'AG'], - ['Argentina', 'AR'], - ['Armenia', 'AM'], - ['Australia', 'AU'], - ['Austria', 'AT'], - ['Azerbaijan', 'AZ'], - ['Bahamas', 'BS'], - ['Bahrain', 'BH'], - ['Bangladesh', 'BD'], - ['Barbados', 'BB'], - ['Belarus', 'BY'], - ['Belgium', 'BE'], - ['Belize', 'BZ'], - ['Benin', 'BJ'], - ['Bhutan', 'BT'], - ['Bolivia', 'BO'], - ['Bosnia and Herzegovina', 'BA'], - ['Botswana', 'BW'], - ['Brazil', 'BR'], - ['Brunei', 'BN'], - ['Bulgaria', 'BG'], - ['Burkina Faso', 'BF'], - ['Burundi', 'BI'], - ['Cambodia', 'KH'], - ['Cameroon', 'CM'], - ['Canada', 'CA'], - ['Cape Verde', 'CV'], - ['Central African Republic', 'CF'], - ['Chad', 'TD'], - ['Chile', 'CL'], - ['China', 'CN'], - ['Colombia', 'CO'], - ['Comoros', 'KM'], - ['Congo', 'CD'], - ['Congo-Brazzaville', 'CG'], - ['Costa Rica', 'CR'], - ['Cote d\'Ivoire (Ivory Coast)', 'CI'], - ['Croatia', 'HR'], - ['Cuba', 'CU'], - ['Cyprus', 'CY'], - ['Czech Republic', 'CZ'], - ['Denmark', 'DK'], - ['Djibouti', 'DJ'], - ['Dominica', 'DM'], - ['Dominican Republic', 'DO'], - ['Ecuador', 'EC'], - ['Egypt', 'EG'], - ['El Salvador', 'SV'], - ['Equatorial Guinea', 'GQ'], - ['Eritrea', 'ER'], - ['Estonia', 'EE'], - ['Ethiopia', 'ET'], - ['Fiji', 'FJ'], - ['Finland', 'FI'], - ['France', 'FR'], - ['Gabon', 'GA'], - ['Gambia', '220'], - ['Georgia', 'GE'], - ['Germany', 'DE'], - ['Ghana', 'GH'], - ['Greece', 'GR'], - ['Grenada', 'GD'], - ['Guatemala', 'GT'], - ['Guinea', 'GN'], - ['Guinea-Bissau', 'GW'], - ['Guyana', 'GY'], - ['Haiti', 'HT'], - ['Honduras', 'HN'], - ['Hungary', 'HU'], - ['Iceland', 'IS'], - ['India', 'IN'], - ['Indonesia', 'ID'], - ['Iran', 'IR'], - ['Iraq', 'IQ'], - ['Ireland', 'IE'], - ['Israel', 'IL'], - ['Italy', 'IT'], - ['Jamaica', 'JM'], - ['Japan', 'JP'], - ['Jordan', 'JO'], - ['Kazakhstan', 'KZ'], - ['Kenya', 'KE'], - ['Kiribati', 'KI'], - ['Kuwait', 'KW'], - ['Kyrgyzstan', 'KG'], - ['Laos', 'LA'], - ['Latvia', 'LV'], - ['Lebanon', 'LB'], - ['Lesotho', 'LS'], - ['Liberia', 'LR'], - ['Libya', 'LY'], - ['Liechtenstein', 'LI'], - ['Lithuania', 'LT'], - ['Luxembourg', 'LU'], - ['Macedonia', 'MK'], - ['Madagascar', 'MG'], - ['Malawi', 'MW'], - ['Malaysia', 'MY'], - ['Maldives', 'MV'], - ['Mali', 'ML'], - ['Malta', 'MT'], - ['Marshall Islands', 'MH'], - ['Mauritania', 'MR'], - ['Mauritius', 'MU'], - ['Mexico', 'MX'], - ['Micronesia', 'FM'], - ['Moldova', 'MD'], - ['Monaco', 'MC'], - ['Mongolia', 'MN'], - ['Montenegro', 'ME'], - ['Morocco', 'MA'], - ['Mozambique', 'MZ'], - ['Myanmar', 'MM'], - ['Nagorno-Karabakh', 'AZ'], - ['Namibia', 'NA'], - ['Nauru', 'NR'], - ['Nepal', 'NP'], - ['Netherlands', 'NL'], - ['New Zealand', 'NZ'], - ['Nicaragua', 'NI'], - ['Niger', 'NE'], - ['Nigeria', 'NG'], - ['North Korea', 'KP'], - ['Northern Cyprus', 'CY'], - ['Norway', 'NO'], - ['Oman', 'OM'], - ['Pakistan', 'PK'], - ['Palau', 'PW'], - ['Panama', 'PA'], - ['Papua New Guinea', 'PG'], - ['Paraguay', 'PY'], - ['Peru', 'PE'], - ['Philippines', 'PH'], - ['Poland', 'PL'], - ['Portugal', 'PT'], - ['Qatar', 'QA'], - ['Romania', 'RO'], - ['Russia', 'RU'], - ['Rwanda', 'RW'], - ['Saint Kitts and Nevis', 'KN'], - ['Saint Lucia', 'LC'], - ['Saint Vincent and the Grenadines', 'VC'], - ['Samoa', 'WS'], - ['San Marino', 'SM'], - ['Sao Tome and Principe', 'ST'], - ['Saudi Arabia', 'SA'], - ['Senegal', 'SN'], - ['Serbia', 'RS'], - ['Seychelles', 'SC'], - ['Sierra Leone', 'SL'], - ['Singapore', 'SG'], - ['Slovakia', 'SK'], - ['Slovenia', 'SI'], - ['Solomon Islands', 'SB'], - ['Somalia', 'SO'], - ['Somaliland', 'SO'], - ['South Africa', 'Rand'], - ['South Korea', 'KR'], - ['South Ossetia', 'GE'], - ['Spain', 'ES'], - ['Sri Lanka', 'LK'], - ['Sudan', 'SD'], - ['Suriname', 'SR'], - ['Swaziland', 'SZ'], - ['Sweden', 'SE'], - ['Switzerland', 'CH'], - ['Syria', 'SY'], - ['Taiwan', 'TW'], - ['Tajikistan', 'TJ'], - ['Tanzania', 'TZ'], - ['Thailand', 'TH'], - ['Timor-Leste', 'TL'], - ['Togo', 'TG'], - ['Tonga', 'TO'], - ['Transnistria', 'MD'], - ['Trinidad and Tobago', 'TT'], - ['Tunisia', 'TN'], - ['Turkey', 'TR'], - ['Turkmenistan', 'TM'], - ['Tuvalu', 'TV'], - ['Uganda', 'UG'], - ['Ukraine', 'UA'], - ['United Arab Emirates', 'AE'], - ['United Kingdom', 'GB'], - ['Uruguay', 'UY'], - ['Uzbekistan', 'UZ'], - ['Vanuatu', 'VU'], - ['Vatican City', 'VA'], - ['Venezuela', 'VE'], - ['Vietnam', 'VN'], - ['Yemen', 'YE'], - ['Zambia', 'ZM'], - ['Zimbabwe', 'ZW'], -] diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CreditCardView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CreditCardView.js deleted file mode 100755 index 63784618..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CreditCardView.js +++ /dev/null @@ -1,61 +0,0 @@ - -var CreditCardView = SerializableView.extend({ - - template: $("#creditcard_template").html(), - - cardOptions: { - accept: ['visa', 'mastercard', 'amex', 'jcb'], - }, - - events: { - }, - - initialize: function(opt){ - this.parent = opt.parent - this.setElement( this.parent.$(".cc") ) - this.$el.html(this.template) - - this.$number = this.$("[name=Number]") - this.$number.validateCreditCard(this.updateCard.bind(this), this.cardOptions) - }, - - populate: function(data){ - this.data = data - data.Number = "XXXX XXXX XXXX " + data.Number - this.$number.attr("type", "text") - this.parent.$(".cc input").val("") - this.$(".cc input").val("") - this.load_data(data) - }, - - updateCard: function(card){ - // console.log(card) - // card.card_type.name - // card.card_type.valid - }, - - validate_presence: { - 'Number': 'Please enter your credit card number.', - 'Cvv': 'Please enter your security code.', - }, - - validate_fields: function(data, errors){ - if (this.disabled) { return } - var card = this.$number.validateCreditCard(this.cardOptions) - if (! card.valid) { errors.push([ "Number", "Your card number is invalid." ]) } - if (! data.ExpirationMonth || data.ExpirationMonth == "NONE") { errors.push([ "ExpirationMonth", "Please enter the expiration month." ]) } - if (! data.ExpirationYear || data.ExpirationYear == "NONE") { errors.push([ "ExpirationYear", "Please select the expiration month." ]) } - data.UserId = auth.user_id - if (card.valid) { - data.Type = YOOX_CREDIT_CARD_NAME_LOOKUP[ card.card_type.name ] - } - }, - -}) - -var YOOX_CREDIT_CARD_NAME_LOOKUP = { - "visa": "Visa", - "mastercard": "Mastercard", - "amex": "AmericanExpress", - "jcb": "JCB", -} diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CurtainView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CurtainView.js deleted file mode 100755 index d444fd60..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/CurtainView.js +++ /dev/null @@ -1,39 +0,0 @@ -var CurtainView = View.extend({ - - el: "#curtain", - - events: { - "click": "click", - }, - - initialize: function(){ - }, - - klass: null, - show: function(klass){ - this.$el.addClass("visible") - if (klass) { - this.klass = klass - this.$el.addClass(klass) - } - }, - - hide: function(k){ - this.$el.removeClass("visible") - if (this.klass) { - setTimeout( function(){ - this.$el.removeClass(this.klass) - }.bind(this), 200 ) - } - }, - - click: function(){ - if (document.body.classList.contains("nav")) { - app.nav.hide() - } - if (app.selector.visible) { - app.selector.hide() - } - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/FooterView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/FooterView.js deleted file mode 100755 index 8641668f..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/FooterView.js +++ /dev/null @@ -1,41 +0,0 @@ -var FooterView = View.extend({ - - el: "#footer", - - events: { - "click .ok": "ok", - "click .cancel": "cancel", - }, - - initialize: function(){ - this.$ok = this.$(".ok") - this.$cancel = this.$(".cancel") - this.hide() - }, - - show: function(ok, cancel){ - if (cancel) { - this.$ok.removeClass("wide") - this.$cancel.show().html(cancel) - } - else { - this.$ok.addClass("wide") - this.$cancel.hide() - } - this.$ok.html(ok) - this.$el.show() - }, - - hide: function(){ - this.$el.hide() - }, - - ok: function(){ - (app.view.save || app.view.ok).bind(app.view)() - }, - - cancel: function(){ - app.view.cancel ? app.view.cancel() : app.intro.show() - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/HeaderView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/HeaderView.js deleted file mode 100755 index 0961a5e8..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/HeaderView.js +++ /dev/null @@ -1,57 +0,0 @@ -var HeaderView = View.extend({ - - el: "#header", - - events: { - "click .burger": "nav", - "click .logo": "logo", - "click .cart_rapper": "cart", - }, - - initialize: function(){ - this.$burger = this.$(".burger") - this.$cart = this.$(".cart") - this.$cart_count = this.$(".cart_count") - }, - - back_state: false, - set_back: function(state){ - this.back_state = state - if (state) { - this.$burger[0].className = "burger ion-ios-arrow-left" - } - else { - this.$burger[0].className = "burger ion-android-menu" - } - }, - - nav: function(){ - if (this.back_state) { - app.view.back() - } - else { - app.nav.show() - } - }, - - logo: function(){ - app.router.go("intro") - }, - - cart: function(){ - app.router.go("cart") - }, - - count: 0, - set_cart_count: function(n){ - this.count = n - this.$cart_count.html(n || "0") - }, - increment_cart_count: function(){ - this.$cart_count.html( ++this.count ) - }, - decrement_cart_count: function(){ - this.$cart_count.html( --this.count ) - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/IntroView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/IntroView.js deleted file mode 100755 index c075619a..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/IntroView.js +++ /dev/null @@ -1,64 +0,0 @@ -var IntroView = View.extend({ - - el: "#intro", - - events: { - "click .store": "store", - "click .hub": "hub", - "click .story": "story", - "click .archive": "archive", - }, - - initialize: function(){ - this.$alert = this.$(".alert") - this.compass = this.$("#compass").get(0) - this.orient = this.deviceorientation.bind(this) - this.$alert.hide() - }, - - show: function(){ - document.body.className = "intro" - window.addEventListener("deviceorientation", this.orient) - app.footer.hide() - this.orient({ alpha: 0 }) - }, - - hide: function(){ - window.removeEventListener("deviceorientation", this.orient) - this.$alert.hide() - }, - - deviceorientation: function(e){ - var heading - if ('webkitCompassHeading' in e) { - heading = e.webkitCompassHeading || 0 - } - else { - heading = e.alpha || 0 - } - heading = - heading - this.compass.style[transformProp] = "translateZ(0) translateX(-50%) translateY(-50%) rotate(" + heading + "deg)" - }, - - store: function(e){ - e.preventDefault() - e.stopPropagation() - app.router.go("store") - }, - hub: function(e){ - e.preventDefault() - e.stopPropagation() - app.router.go("hub") - }, - story: function(e){ - e.preventDefault() - e.stopPropagation() - app.router.go("story") - }, - archive: function(e){ - e.preventDefault() - e.stopPropagation() - app.router.go("archive") - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/NavView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/NavView.js deleted file mode 100755 index cfb39ff6..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/NavView.js +++ /dev/null @@ -1,162 +0,0 @@ -var NavView = View.extend({ - - el: "#nav", - - events: { - "click .logo": "intro", - - "click .store": "store", - "click .hub": "hub", - "click .story": "story", - "click .archive": "archive", - - "click .login": "login", - "click .logout": "logout", - "click .account": "account", - "click .faq": "faq", - "click .search": "search", - - "click .main": "back", - "click .account_back": "back", - "click .profile": "profile", - "click .payment": "payment", - "click .shipping": "shipping", - "click .settings": "settings", - "click .orders": "orders", - "click .return_link": "return_link", - - "click .faq_back": "back", - "click .privacy": "privacy", - "click .returns": "returns", - "click .terms": "terms", - "click .care": "care", - - "click .fb": "fb", - "click .insta": "insta", - "click .tw": "tw", - "click .yt": "yt", - }, - - initialize: function(){ - }, - - show: function(klass){ - $("body").addClass("nav") - app.curtain.show("dark") - if (klass) { - setTimeout(function(){ - this.addClass(klass) - }.bind(this), 500) - } - }, - - hide: function(){ - $("body").removeClass("nav") - app.curtain.hide("dark") - }, - - intro: function(){ - this.hide() - app.router.go("intro") - }, - store: function(){ - this.hide() - app.router.go("store") - }, - hub: function(){ - this.hide() - app.router.go("hub") - }, - story: function(){ - this.hide() - app.router.go("story") - }, - archive: function(){ - this.hide() - app.router.go("archive") - }, - - login: function(){ - this.hide() - auth.last_view = app.view - app.router.go("account/login") - }, - logout: function(){ - this.hide() - auth.last_view = app.view - app.router.go("account/logout") - }, - account: function(){ - this.el.className = "account" - }, - - back: function(){ - this.el.className = "" - }, - - profile: function(){ - this.hide() - app.router.go("account/profile") - }, - payment: function(){ - this.hide() - app.router.go("account/payment") - }, - shipping: function(){ - this.hide() - app.router.go("account/shipping") - }, - orders: function(){ - this.hide() - app.router.go("account/orders") - }, - settings: function(){ - this.hide() - app.router.go("account/settings") - }, - return_link: function(){ - window.open("http://www.stoneisland.com/yTos/Plugins/AreaLocalizer/Redirectarea?area=ProductExchange&controllerName=SearchOrder&actionName=Index", '_system') - }, - - - faq: function(){ - this.el.className = "faq" - }, - privacy: function(){ - this.hide() - app.router.go("page/privacy") - }, - returns: function(){ - this.hide() - app.router.go("page/returns") - }, - terms: function(){ - this.hide() - app.router.go("page/terms") - }, - care: function(e){ - e.preventDefault() - window.open("http://www.stoneisland.com/system/web/custom/hp/email.jsp", '_system') - }, - - - search: function(){ - this.hide() - app.router.go("search") - }, - - - fb: function(){ - window.open(is_ios ? "facebook://profile/231623463406" : "https://www.facebook.com/StoneIsland", '_system') - }, - insta: function(){ - window.open("https://instagram.com/stoneisland_official", '_system') - }, - tw: function(){ - window.open("https://twitter.com/stoneisland", '_system') - }, - yt: function(){ - window.open("https://www.youtube.com/user/StoneIslandOfficial", '_system') - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/SearchView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/SearchView.js deleted file mode 100755 index b477d72f..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/nav/SearchView.js +++ /dev/null @@ -1,16 +0,0 @@ -var SearchView = View.extend({ - - el: "#search", - - events: { - }, - - show: function(){ - app.footer.show("SEARCH") - document.body.className = "search" - }, - - save: function(){ - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ClosedStoreView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ClosedStoreView.js deleted file mode 100755 index 97b46006..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ClosedStoreView.js +++ /dev/null @@ -1,75 +0,0 @@ -var ClosedStoreView = View.extend({ - - el: "#closed", - - storeIsClosed: false, - - events: { - "click .website_link": "website_link", - }, - - delay: 8000, - - timeout: -1, - images: null, - images_loaded: {}, - - initialize: function(){ - this.loader = new Loader () - }, - - show: function(){ - this.setMessage(app.closed.storeClosedMessageOne, app.closed.storeClosedMessageTwo) - this.showElement() - }, - - showElement: function(){ - document.body.className = "closed" - this.animate() - app.footer.hide() - }, - - setMessage: function(msg_one, msg_two){ - $(".closed_store_msg h3").html(msg_one || "THIS STORE IS CURRENTLY CLOSED") - if (app.closed.storeClosedMessageTwo) { - $(".closed_store_msg h4").show().html(msg_two) - } - else { - $(".closed_store_msg h4").hide() - } - }, - - hide: function(){ - clearTimeout(this.timeout) - }, - - animate: function(){ - this.timeout = setTimeout(this.animate.bind(this), this.delay) - this.next() - }, - - next: function(){ - if (! this.images) return - var url = choice(this.images) - - if (this.images_loaded[url]) { - this.el.style.backgroundImage = 'url(' + url + ')' - } - else { - this.loader.preloadImage(url, function(img){ - this.el.style.backgroundImage = 'url(' + url + ')' - this.images_loaded[url] = true - }.bind(this)) - } - }, - - populate: function(data){ - this.images = data.map(function(img){ return img.uri }) - this.next() - }, - - website_link: function(){ - window.open("http://www.stoneisland.com/", '_system') - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/CollectionView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/CollectionView.js deleted file mode 100755 index 671d36b3..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/CollectionView.js +++ /dev/null @@ -1,171 +0,0 @@ - -var CollectionView = ScrollableView.extend({ - - el: "#collection", - template: $("#collection .template").html(), - loaded: false, - data: null, - items: {}, - - events: { - "touchstart .item": "touchstart", - "touchmove .item": "touchmove", - "touchend .item": "touchend", - "mousedown .item": "touchstart", - "mousemove .item": "touchmove", - "mouseup .item": "touchend", - "touchstart h1": "showDepartmentSelector", - }, - - initialize: function(){ - this.$title = this.$("h1") - this.$content = this.$(".content") - this.$loader = this.$(".loader") - this.scroller = new IScroll('#collection', app.iscroll_options) - this.filterView = new DepartmentFilter ({ parent: this }) - }, - - show: function(){ - if (! navigator.onLine) { - app.closed.showElement() - app.closed.setMessage("PLEASE GO ONLINE TO BROWSE
    THE STONE ISLAND STORE.", "") - return - } - if (sdk.env !== "test" && app.closed.storeIsClosed) { - return app.closed.show() - } - if (this.data && this.data.SearchResponseFull.Results.Items.length < 4) { - app.footer.hide() - } - else { - app.footer.show("FILTER") - } - document.body.className = "collection" - if (this.loaded) { - console.log("collection this loaded") - return this.populate(this.data) - } - else { - this.fetch() - } - }, - - save: function(){ - this.filterView.filter() - }, - - fetch: function(){ - console.log("collection fetch") - if (this.loaded) { - console.log("collection loaded") - return - } - this.$loader.show() - console.log("fetching", app.department_id) - sdk.product.collection({ - department_id: app.department_id, - success: this.populate.bind(this) - }) - }, - - refresh: function(){ - this.loaded = false - this.fetch() - }, - - populate: function(data){ - if (this.loaded && ! data) { - console.log("populate 1") - data = this.data - } - else { - console.log("populate 2") - this.data = data - this.loaded = false - console.log(data) - } - console.log(">>>>>>>> YES ") - if (! this.loaded) { - console.log("populate 3", data.SearchResponseFull.Results.Items.length) - this.loaded = true - this.$loader.hide() - this.$content.empty() - // DefaultCode10 -// data.SearchResponseFull.Results.Items.length = 1 - var is_single_product = (data.SearchResponseFull.Results.Items.length < 4) - this.$el.toggleClass("single", is_single_product) - - if (is_single_product) { - console.log("IS SINGLE PRODUCT") - var item = data.SearchResponseFull.Results.Items[0] - var url = sdk.image(item['DefaultCode10'], '13_f') - console.log(url) - var img = new Image () - img.src = url - } - -// if (data.SearchResponseFull.Results.Items.length == 1) { -// app.footer.hide() -// } -// else { -// app.footer.show("FILTER") -// } - - console.log( data.SearchResponseFull.Results.Items.length ) - data.SearchResponseFull.Results.Items.forEach(function(item){ - console.log(">>> ITEM") - this.append(item, is_single_product) - }.bind(this)) - this.deferScrollToTop() - } - this.afterFetchCallback && this.afterFetchCallback() - app.collection.deferRefresh() - }, - - append: function(item, is_single_product){ - this.items[ item['Code8'] ] = item - var t = this.template.replace(/{{image}}/, sdk.image(item['DefaultCode10'], is_single_product ? '13_f' : '11_f')) - .replace(/{{code8}}/, item['Code8']) - this.$content.append(t) - }, - - pick: function(e){ - var code = $(e.currentTarget).data("code") - var data = this.items[code] - app.product.load(code, data) - }, - - collectionName: "STONE ISLAND", - setCollectionName: function(name){ - this.collectionName = name - this.$title.html(this.collectionName) - }, - - showDepartmentSelector: function(){ - this.filterView.filter() - }, - - firstTouch: { x: 0, y: 0, id: "" }, - lastTouch: { x: 0, y: 0, id: "" }, - touchstart: function(e){ - var p = e.originalEvent.touches ? e.originalEvent.touches[0] : e.originalEvent - this.firstTouch.x = this.lastTouch.x = p.pageX - this.firstTouch.y = this.lastTouch.y = p.pageY - this.firstTouch.id = e.currentTarget.dataset.id - }, - touchmove: function(e){ - var p = e.originalEvent.touches ? e.originalEvent.touches[0] : e.originalEvent - this.lastTouch.x = p.pageX - this.lastTouch.y = p.pageY - this.lastTouch.id = e.currentTarget.dataset.id - }, - touchend: function(e){ - var first = app.collection.firstTouch - var last = app.collection.lastTouch - var distance = Math.sqrt( Math.pow(first.x - last.x, 2) + Math.pow(first.y - last.y, 2) ) - if (distance < 20) { - this.pick(e) - } - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/GalleryView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/GalleryView.js deleted file mode 100755 index 1428aca9..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/GalleryView.js +++ /dev/null @@ -1,65 +0,0 @@ -var GalleryView = View.extend({ - - el: "#gallery", - template: $("#gallery .template").html(), - - events: { -// "click .left": "prev", -// "click .right": "next", -// "touchstart .gallery": "touchstart", -// "touchmove .gallery": "touchmove", -// "touchend .gallery": "touchend", - }, - - initialize: function(){ - this.$(".template").remove() - }, - - reset: function(){ - this.gallery && this.gallery.destroy() - this.$el.empty() - }, - - populate: function(code, image_ids){ - var valid_styles = {} - image_ids.forEach(function(id){ - if (id.indexOf("_") == -1) return - var partz = id.split("_") - var size = parseInt(partz[0]), style = partz[1] - if (size > 13) return; - if (! valid_styles[style] || valid_styles[style] < size) { - valid_styles[style] = size - } - }) - Object.keys(valid_styles).sort(sort_image_styles).forEach(function(style){ - var id = valid_styles[style] + "_" + style - var t = this.template.replace(/{{image}}/, sdk.image(code, id)) - this.$el.append(t) - }.bind(this)) - - this.gallery = new Flickity( "#gallery", { - selector: '.item', - cellAlign: 'center', - autoPlay: false, - freeScroll: false, - wrapAround: true, - imagesLoaded: true, - prevNextButtons: false, - pageDots: false, - contain: true, - draggable: true, - }) - }, - - touchstart: function(e){ - }, - touchmove: function(e){ - }, - touchend: function(e){ - }, - -}) - -var YOOX_IMAGE_STYLE_ORDER = "ZZZ f r d e a b c g l".split(" ") - -function sort_image_styles (b,a){ return (YOOX_IMAGE_STYLE_ORDER.indexOf(b)) - (YOOX_IMAGE_STYLE_ORDER.indexOf(a)) } \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ProductView.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ProductView.js deleted file mode 100755 index 81ad536d..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/ProductView.js +++ /dev/null @@ -1,480 +0,0 @@ - -var ProductView = ScrollableView.extend({ - - el: "#product", - - events: { - "click .fit": "scroll_to_bottom", - "click .size": "select_size", - "click .color": "select_color", - "click .share": "share", - "click .gallery-left": "gallery_left", - "click .gallery-right": "gallery_right", - }, - - initialize: function(){ - this.gallery = new GalleryView () - this.scroller = new IScroll('#product', app.iscroll_options) - - this.$num = this.$(".num") - this.$title = this.$(".title") - this.$type = this.$(".type") - this.$price = this.$(".price") - this.$size = this.$(".size") - this.$share = this.$(".share") - this.$color = this.$(".color") - this.$body = this.$(".body") - this.$fit = this.$(".fit") - this.$sizing = this.$(".sizing") - this.$style = this.$(".style") - }, - - show: function(){ - this.showFooter() - document.body.className = "product" - }, - hide: function(){ - }, - - showFooter: function(){ - if (this.not_available) { - app.footer.show("SOLD OUT") - } - else { - app.footer.show("ADD TO CART", "BUY NOW") - } - }, - - item: null, - details: null, - size: null, - color: null, - code: null, - is_onesize: false, - fitLargeCodes: {}, - - sizes: null, - colors: null, - - cache: {}, - - gallery_left: function(){ - app.product.gallery.gallery.previous() - }, - gallery_right: function(){ - app.product.gallery.gallery.next() - }, - - find: function(code, cb){ - data = app.collection.items[code] || {} - if (code in this.cache) { - return cb(data, this.cache[code]) - } - sdk.product.item({ - code: code - }).done(function(details){ - this.cache[code] = details - cb(data, details) - }.bind(this)) - }, - - load: function(code, data){ - this.gallery.reset() - this.show() - if (app.view && app.view.hide) { - app.view.hide() - } - app.view = this - app.header.set_back(true) - - if (! app.collection.loaded) { - this.el.className = "loading" - app.collection.afterFetchCallback = this.load.bind(this, code, data) - app.collection.fetch() - return - } - else { - app.collection.afterFetchCallback = null - } - window.location.href = "#/store/" + code - - if (data) { - app.collection.items[code] = data - } - - this.el.className = "loading" - this.find(code, this.populate.bind(this)) - }, - - populate: function(data, details){ - this.el.className = "" - - console.log(data, details) - - var descriptions = this.get_descriptions(details) - - var name_partz = data['ModelNames'].split(' ') - var num = name_partz.shift() - var title = name_partz.join(' ') - var type = title_case( data['MicroCategory'] ) - var price = "$" + data['DiscountedPrice'] + ".00" - var body = descriptions['Details'] + " " + descriptions['EditorialDescription'] - // body = body.replace(/
    /g, "

    ").replace(/(
    )+$/, "") - - var default_color_id = this.populate_selectors(data, details) - - if (this.not_available) { - this.$style.css("opacity", 0) - this.$color.html("NOT AVAILABLE") - this.$size.hide() - this.gallery.populate( data['Code8'], details['Item']['ImageTypes'] ) - } - else { - this.$style.css("opacity", 1) - - var color = this.colors[default_color_id] - var color_label = color.label - var sizes = this.find_sizes_for_color(default_color_id) - var size = sizes[0] - var size_label = this.sizes[size].label - - this.gallery.populate( color.code, details['Item']['ImageTypes'] ) - - this.color = color - this.size = size - - this.is_onesize = !! this.sizes[1] - - this.$size.show().html(size_label) - if (color_label) { - this.$color.html(color_label) - } - else { - this.$color.hide() - } - } - - // console.log(color, color_label, size, size_label) - - this.item = data - this.details = details['Item'] - this.code = data['DefaultCode10'] - - console.log( data['DefaultCode10'] ) - - this.$num.html(num) - this.$title.html(title) - this.$type.html(type) - this.$price.html(price) - this.$body.html(body) - - var fits_large = !! this.fitLargeCodes[this.code] - app.product.$fit.toggle( fits_large ) - app.product.$sizing.toggle( fits_large ) - - this.showFooter() - - this.deferScrollToTop() - }, - - get_descriptions: function (details){ - var descriptions = {} - details['Item']['Descriptions'].forEach(function(pair){ - descriptions[pair.Key] = pair.Value - }) - return descriptions - }, - find_sizes_for_color: function(color_id){ - return Object.keys( this.colors[color_id].sizes ).sort(function(a,b){ - var ao = SIZE_ORDER[ a.label ], bo = SIZE_ORDER[ b.label ] - return aoShort sleeve T-Shirt in cotton jersey. Garment dyed.
    Stone Island Compass logo print on the front, made up of a series of numbers." -ItemDescription: "Logo detail
    Jersey
    Round collar
    Solid color
    " -KeywordDescription: "Logo detail Jersey Round collar Solid color Jersey Woven not made of fur " -Kind of fabric: "Woven" -MFC: "631520081CC-6315-81V0060" -MacroCategory: "POLO SHIRTS & T-SHIRTS" -MadeIn: "Made In Turkmenistan" -MadeInIsoCode: "TN" -MainMaterial: "Cotton" -Material Description: "Jersey" -MicroCategory: "Short sleeve t-shirt" -MicroCategoryPlural: "Short sleeve t-shirts" -ModelFabric: "631520081CC-6315-81" -ModelNames: "20081 DATA DRIP PIN" -Neckline: "Claudine or round collar" - -*/ diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/Selector.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/Selector.js deleted file mode 100755 index 89130021..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/Selector.js +++ /dev/null @@ -1,70 +0,0 @@ -var Selector = View.extend({ - - el: "#selector", - template: $("#selector .template").html(), - - events: { - "click .close": "hide", - "touchstart .options div": "pick", - }, - - initialize: function(){ - this.$options = this.$(".options") - }, - - lookup: null, - callback: null, - select: function(origin, options, callback){ - this.lookup = {} - this.callback = callback || function(item){ console.log(item) } - this.$options.empty() - options.forEach(function(opt){ - this.lookup[String(opt.id)] = opt - var t = this.template.replace(/{{id}}/, opt.id) - .replace(/{{label}}/, opt.label) - this.$options.append(t) - }.bind(this)) - this.$el.show() - app.curtain.show("white") - this.visible = true - $("#selector").removeClass("selector-outer-wrap") - if ( origin == "wide") { - $("#selector").addClass("selector-full") - } - else { - $("#selector").removeClass("selector-full") - } - var originXY = $("." + origin).offset() - var originWidth = $("." + origin).width() - var selectorHeight = $('#selector').height() - var originHeight = $("." + origin).height() - console.log(selectorHeight) - if ((selectorHeight > 250) && (!$("#selector").hasClass("selector-full"))) { - $("#selector").addClass("selector-outer-wrap") - } - var selectorHeight = $('#selector').height() - $("#selector").css({"top":(originXY.top - selectorHeight - originHeight + 20),"left":originXY.left}) - originXY = null; - originWidth = null; - originHeight = null; - selectorHeight = null; - }, - - hide: function(){ - this.lookup = this.callback = null - this.$el.hide() - app.curtain.hide() - this.visible = false - }, - - pick: function(e){ - e.preventDefault() - e.stopPropagation() - var $option = $(e.currentTarget) - var id = String($option.data("id")) - var selection = this.lookup[id] - this.callback( selection ) - this.hide() - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/CategoryFilter.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/CategoryFilter.js deleted file mode 100755 index 53f9a59b..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/CategoryFilter.js +++ /dev/null @@ -1,40 +0,0 @@ -var CategoryFilter = View.extend({ - - initialize: function(opt){ - this.parent = opt.parent - }, - - filter: function(){ - var cats = this.parent.data.SearchResponseFull.Refinements.Filters.Categories.map(function(cat){ - return { - id: cat.Id, - label: cat.Value - } - }) - if (this.last_choice) { - cats.push({ - id: "__remove_filter", - label: "REMOVE FILTER", - }) - } - app.selector.select("wide", cats, this.pick.bind(this)) - }, - - last_choice: null, - - pick: function(choice){ - this.parent.$content.empty() - if (choice.id == "__remove_filter") { - this.last_choice = null - this.parent.data.SearchResponseFull.Results.Items.forEach(this.parent.append.bind(this.parent)) - } - else { - this.last_choice = choice - this.parent.data.SearchResponseFull.Results.Items.filter(function(item){ - return item.MacroCategory == choice.label - }).forEach(this.parent.append.bind(this.parent)) - } - this.parent.deferScrollToTop() - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/DepartmentFilter.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/DepartmentFilter.js deleted file mode 100644 index cc0d925e..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/products/filters/DepartmentFilter.js +++ /dev/null @@ -1,31 +0,0 @@ -var DepartmentFilter = View.extend({ - - initialize: function(opt){ - this.parent = opt.parent - }, - - filter: function(){ - var deps = app.departments.map(function(dep){ - console.log(dep) - return { - id: dep.uri, - label: dep.text, - } - }) - app.selector.select("wide", deps, this.pick.bind(this)) - }, - - last_choice: null, - - pick: function(choice){ - this.parent.$content.empty() - this.last_choice = choice - app.department_id = choice.id - app.collection.loaded = false - app.collection.fetch() - app.footer.hide() - app.collection.setCollectionName(choice.label) - this.parent.deferScrollToTop() - }, - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Router.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Router.js deleted file mode 100755 index a8ec331f..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Router.js +++ /dev/null @@ -1,75 +0,0 @@ -var Router = View.extend({ - - routeByHash: false, - - go: function(url){ - this.parseRoute(url) - }, - - route: function(){ - var path = this.routeByHash ? window.location.hash.substr(0) : window.location.pathname - path = path || "/" - this.originalPath = path - this.parseRoute(path) - }, - - parseRoute: function(pathname){ - - pathname = pathname.replace(/^#/, "") - - if (pathname[0] !== "/") { pathname = "/" + pathname } - - var routes = this.routes, - path = pathname.split("/"); - - for (var i = 0; i < path.length; i++) { - if (! path[i].length) { - path[i] = null - } - } - - if (pathname in routes) { - this[this.routes[pathname]]() - return - } - - if (path[path.length-1] == null) { - path.pop() - } - - for (var route in routes) { - var routePath = route.split("/") - if (routePath[1] == path[1]) { - if (routePath[2] && routePath[2].indexOf(":") !== -1 && path[2] && (path[3] === routePath[3]) ) { - this[this.routes[route]](path[2]) - return - } - else if (routePath[2] == path[2]) { - if (routePath[3] && path[3]) { - if (routePath[3].indexOf(":") !== -1) { - this[this.routes[route]](path[3]) - return - } - else if (routePath[3] == path[3]) { - this[this.routes[route]]() - return - } - } - else if (! routePath[3] && ! path[3]) { - this[this.routes[route]]() - return - } - } - else if (! routePath[2] && (! path[2].length || ! path[2])) { - this[this.routes[route]]() - return - } - } - } - - if (is_mobile) { - window.location.href = "/" - } - } - -}) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Scrollable.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Scrollable.js deleted file mode 100755 index 0baff845..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Scrollable.js +++ /dev/null @@ -1,27 +0,0 @@ -var ScrollableView = View.extend({ - - events: { - "load img": "deferRefresh", - }, - - deferScrollToTop: function(){ - setTimeout(this.scrollToTop.bind(this), 0) - }, - - refreshScroller: function(){ - this.scroller.refresh() - clearTimeout( this.scrollerRefreshTimeout ) - }, - - scrollerRefreshTimeout: null, - deferRefresh: function(){ - clearTimeout( this.scrollerRefreshTimeout ) - this.scrollerRefreshTimeout = setTimeout(this.refreshScroller.bind(this)) - }, - - scrollToTop: function(){ - this.scroller.refresh() - this.scroller.scrollTo(0, 0) - }, - -}) \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Serializable.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Serializable.js deleted file mode 100755 index 8d25daf4..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/Serializable.js +++ /dev/null @@ -1,168 +0,0 @@ -var SerializableView = View.extend({ - - events: { - "change select": "update_select", - "change [type=date]": "update_date", - "focus input": "focus_input", - "click .date-wrapper": "focus_date", - "submit form": "save", - }, - - preload: function(data){ - if (! data && sdk.env == "production") { return } - data = data || this.test_data - if (! data) { return } - this.load_data(data) - }, - - load_data: function(data){ - Object.keys(data).forEach(function(key){ - var value = data[key] - var $el = this.$("[name=" + key + "]") - - if ($el.attr("type") == "checkbox") { - $el.prop("checked", value) - } - if ($el.attr("type") == "date") { - $el.val( value ) - this.update_date({ currentTarget: $el }) - } - else if ($el.prop("tagName") == "SELECT") { - $el.val( value ) - this.update_select({ currentTarget: $el }) - } - else { - $el.val( value ) - } - }.bind(this)) - }, - - serialize: function(){ - var fields = {} - this.$("input[name], select[name], textarea[name]").each( function(){ - if (this.type == "checkbox") { - if ($(this).prop("checked")) { - fields[this.name] = this.value - } - } - else { - fields[this.name] = this.value - } - }) - return fields - }, - - deserialize: function(data){ - this.$("input[name], textarea[name]").val("") - Object.keys(data).forEach(function(k){ - this.$("[" + k + "]").val(data[k]) - }) - }, - - focus_input: function(e){ - $(e.currentTarget).removeClass("error_hilite") - }, - - focus_date: function(e){ - $(e.currentTarget).find("input").focus() - }, - - update_select: function(e){ - var $target = $(e.currentTarget), value = $target.val() - var label = $target.find("option").filter(function(){ return this.value === value }).html() - $target.parent().addClass("picked") - $target.parent().find("span").html(label) - }, - - update_date: function(e){ - var $target = $(e.currentTarget), value = $target.val() - var label = moment(value).format("MM/DD/YYYY") - $target.parent().addClass("picked") - $target.parent().find("span").html(label) - }, - - validate: function(data, errors){ - var data = data || this.serialize() - var errors = errors || [] - var presence_msgs = this.validate_presence || {} - if (! this.disabled) { - Object.keys(presence_msgs).forEach(function(k){ - if (! data[k]) errors.push( [ k, presence_msgs[k] ] ) - }) - } - this.validate_fields && this.validate_fields(data, errors) - this.cc && this.cc.validate(data, errors) - this.address && this.address.validate(data, errors) - return { errors: errors, data: data } - }, - - show_errors: function(errors){ - console.log("showing errors") - console.log(errors) - var msgs = [] - errors.forEach(function(e, i){ - if (i > 0) { return } - this.$("[name=" + e[0] + "]").addClass('error_hilite') - msgs.push(e[1]) - }.bind(this)) - this.$msg.html(msgs.join("
    ")) - this.$msg.addClass('alert-notice') - }, - - hide_errors: function(){ - this.$msg.removeClass('alert-notice') - this.$msg.html("") - }, - - finalize: function(data){ - return data - }, - - save: function(e){ - e && e.preventDefault() - - var valid = this.validate() - if (valid.errors.length) { - this.show_errors(valid.errors) - return - } - else { - this.hide_errors() - } - - var finalized_data = this.finalize(valid.data) - this.submit( finalized_data ) - }, - - submit: function(data){ - if (! data) { - return - } - app.curtain.show("loading") - this.action({ - data: data, - success: function(data){ - app.curtain.hide("loading") - this.success(data) - }.bind(this), - error: function(data){ - app.curtain.hide("loading") - console.log("api error") - this.error(data) - }.bind(this), - }) - }, - - success: function(data){ - console.log("SUCCESS") - console.log(data) - }, - - error: function(data){ - console.log("FAIL") - console.log(data) - }, - -}) - -var FormView = View.extend(SerializableView.prototype).extend(ScrollableView.prototype) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/View.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/View.js deleted file mode 100755 index 2401df0d..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/lib/view/View.js +++ /dev/null @@ -1,147 +0,0 @@ -var View = (function($, _){ - - var View = function(options) { - this._id = _.uniqueId('view') - this.type = "view" - options || (options = {}); - _.extend(this, _.pick(options, viewOptions)) - this._ensureElement() - this.initialize.apply(this, arguments) - this.delegateEvents() - } - - var delegateEventSplitter = /^(\S+)\s*(.*)$/; - - var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; - - _.extend(View.prototype, { - - // The default `tagName` of a View's element is `"div"`. - tagName: 'div', - - $: function(selector) { - return this.$el.find(selector); - }, - - initialize: function(){}, - - setElement: function(element, delegate) { - if (this.$el) this.undelegateEvents(); - this.$el = element instanceof $ ? element : $(element); - this.el = this.$el[0]; - if (delegate !== false) this.delegateEvents(); - return this; - }, - - // Set callbacks, where `this.events` is a hash of - // - // *{"event selector": "callback"}* - // - // { - // 'mousedown .title': 'edit', - // 'click .button': 'save', - // 'click .open': function(e) { ... } - // } - // - // pairs. Callbacks will be bound to the view, with `this` set properly. - // Uses event delegation for efficiency. - // Omitting the selector binds the event to `this.el`. - // This only works for delegate-able events: not `focus`, `blur`, and - // not `change`, `submit`, and `reset` in Internet Explorer. - delegateEvents: function(events) { - if (!(events || (events = _.result(this, 'events')))) return this; - this.undelegateEvents(); - for (var key in events) { - var method = events[key]; - if (!_.isFunction(method)) method = this[events[key]]; - if (!method) continue; - - var match = key.match(delegateEventSplitter); - var eventName = match[1], selector = match[2]; - method = _.bind(method, this); - if (is_mobile) { - if (eventName === 'mouseenter' || eventName === 'mouseleave') { - continue - } - if (is_android && eventName === 'click') { - eventName = 'touchstart' - } - } - eventName += '.delegateEvents' + this._id; - if (selector === '') { - this.$el.on(eventName, method); - } else { - this.$el.on(eventName, selector, method); - } - } - return this; - }, - - // Clears all callbacks previously bound to the view with `delegateEvents`. - undelegateEvents: function() { - this.$el.off('.delegateEvents' + this._id); - return this; - }, - - // Ensure that the View has a DOM element to render into. - // If `this.el` is a string, pass it through `$()`, take the first - // matching element, and re-assign it to `el`. Otherwise, create - // an element from the `id`, `className` and `tagName` properties. - _ensureElement: function() { - this.setElement(_.result(this, 'el'), false); - }, - - preventDefault: function(e){ - e && e.preventDefault() - }, - - stopPropagation: function(e){ - e && e.stopPropagation() - }, - - }); - - - var extend = function(protoProps, staticProps) { - var staticProps = staticProps || {} - var parent = this; - var child; - var childEvents = {}; - - // The constructor function for the new subclass is either defined by you - // (the "constructor" property in your `extend` definition), or defaulted - // by us to simply call the parent's constructor. - if (protoProps && _.has(protoProps, 'constructor')) { - child = protoProps.constructor; - } else { - child = function(){ return parent.apply(this, arguments); }; - } - - // Extend events so we can subclass views - _.extend(childEvents, parent.prototype.events, protoProps.events) - - // Add static properties to the constructor function, if supplied. - _.extend(child, parent, staticProps); - - // Set the prototype chain to inherit from `parent`, without calling - // `parent`'s constructor function. - var Surrogate = function(){ this.constructor = child; }; - Surrogate.prototype = parent.prototype; - child.prototype = new Surrogate; - - // Add prototype properties (instance properties) to the subclass, - // if supplied. - if (protoProps) _.extend(child.prototype, protoProps); - - // Set a convenience property in case the parent's prototype is needed - // later. - child.prototype.__super__ = parent.prototype; - child.prototype.events = childEvents - - return child; - }; - - View.extend = extend; - - return View; -})(jQuery, _) diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/_sdk.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/_sdk.js deleted file mode 100755 index 017df015..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/_sdk.js +++ /dev/null @@ -1,38 +0,0 @@ -var sdk = (function(){ - var sdk = {} - - sdk.env = "development" - - var endpoint = "https://secure.api.yoox.biz/" - // var endpoint = "http://api.yoox.biz/" - - sdk.init = function(opt){ - switch (sdk.env = opt.env || "development") { - case 'test': - endpoint = "http://lvh.me:9090/" - break - default: - case 'development': - endpoint = "/" - break - case 'production': - endpoint = "https://secure.api.yoox.biz/" - break - } - } - - sdk.path = function(api, path){ - return endpoint + api + "/STONEISLAND_US/" + path - } - - sdk.image = function(code, size){ - return "http://cdn.yoox.biz/" + code.substr(0,2) + "/" + code + "_" + size + ".jpg" - } - - $.ajaxSetup({ - // possibly: application/json; charset=utf-8" - contentType: "application/json", - }) - - return sdk -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/account.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/account.js deleted file mode 100755 index 3eb3f3bd..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/account.js +++ /dev/null @@ -1,133 +0,0 @@ -sdk.account = (function(){ - - var user_id, access_token - - // https://gist.github.com/fanfare/d18498e7fa25acbd4486 - var account = {} - account.signup = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Account.API/1.5", "users.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-api-key": auth.apikey, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - user_id = data['UserAccount']['UserId'] - access_token = data['UserAccount']['AccessToken'] - - auth.set_user(user_id, access_token) - - opt.success(data) - }, - error: opt.error, - }) - } - - account.login = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Account.API/1.5", "authfull.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - auth.user = data['UserFull'] - user_id = data['UserFull']['idUser'] - access_token = data['UserFull']['AccessToken'] - - auth.set_user(user_id, access_token) - - opt.success(data) - }, - error: opt.error, - }) - } - - account.checkin = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: "{}", - success: function(data){ - auth.user = data.User - opt.success(data) - }, - error: opt.error, - }) - } - - account.update = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - account.update_mail_and_password = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Account.API/1.5", "auth/" + auth.user_id + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - account.fetch_orders = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/orders.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - account.fetch_single_order = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/orders/" + opt.id + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - return account - -})() diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/address.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/address.js deleted file mode 100755 index 1256df54..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/address.js +++ /dev/null @@ -1,78 +0,0 @@ -sdk.address = (function(){ - var address = {} - - address.list = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/addressBook.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: opt.data, - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - complete: function(data){ - console.log("really weird") - console.log(data) - } - }) - } - - address.add = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/addressBook/item.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - address.update = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/addressBook/item.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - address.destroy = function(opt){ - return $.ajax({ - method: "DELETE", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/" + opt.id + "/addressBook.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - return address - -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/auth.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/auth.js deleted file mode 100755 index fa8dd71c..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/auth.js +++ /dev/null @@ -1,148 +0,0 @@ -/* - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - "x-yoox-device": auth.device, - "x-yoox-api-key": auth.apikey, - }, -*/ - -var auth = sdk.auth = (function(){ - var auth = {} - - auth.appname = is_iphone ? "native-iphone-stoneisland/1.0.0" : "native-android-stoneisland/1.0.0" - auth.apikey = "U2FsdGVkX18fThqg9bF0/ZgE9Jg948hn8O9EXli4B2729nAESCQaexv//M5+7+za" - auth.device = "smartphone" - - auth.access_token = "" - auth.user_id = -1 - - auth.next_view = null - auth.deferred_product = null - - // ios: integrate keychain api - // android: cordova.file.externalRootDirectory api - - auth.init = function(fn){ - console.log("AUTH INIT") - auth.get_user(function(){ - if (auth.logged_in()) { - sdk.account.checkin({ - success: function(data){ - fn && fn( auth.logged_in() ) - }, - error: function(){ - auth.log_out() - fn && fn( false ) - // - }, - }) - auth.get_cart() - } - else { - fn && fn( auth.logged_in() ) - } - }) - } - - auth.set_user = function(user_id, access_token, cb){ - auth.access_token = access_token - auth.user_id = user_id - - localStorage.setItem("yoox.access_token", access_token) - localStorage.setItem("yoox.user_id", user_id) - cb && cb() - } - auth.get_user = function(cb){ - auth.access_token = localStorage.getItem("yoox.access_token") || "" - auth.user_id = localStorage.getItem("yoox.user_id") || -1 - cb && cb() - } - auth.clear_user = function(cb){ - auth.access_token = "" - auth.user_id = -1 - localStorage.removeItem("yoox.access_token") - localStorage.removeItem("yoox.user_id") - cb && cb() - } - - auth.set_cart = function(cart_id, cart_token, cb){ - localStorage.setItem("yoox.cart_token", cart_token) - localStorage.setItem("yoox.cart_id", cart_id) - cb && cb() - } - auth.get_cart = function(cb){ - sdk.cart.token = localStorage.getItem("yoox.cart_token") || "" - sdk.cart.id = localStorage.getItem("yoox.cart_id") || -1 - cb && cb() - } - auth.clear_cart = function(cb){ - sdk.cart.token = "" - sdk.cart.id = -1 - localStorage.removeItem("yoox.cart_token") - localStorage.removeItem("yoox.cart_id") - cb && cb() - } - auth.create_cart = function(opt){ - opt = opt || {} - if (auth.has_cart()) { - opt.success && opt.success() - return - } - sdk.cart.initialize({ - success: function(data){ - sdk.cart.set_user({ - success: function(){ - auth.set_cart(sdk.cart.id, sdk.cart.token, function(){ - opt.success && opt.success() - }) - }, - error: function(){ - opt.clear_cart() - opt.error && opt.error() - }, - }) - }, - error: function(){ - opt.clear_cart() - opt.error && opt.error() - } - }) - } - - auth.add_deferred_product_to_cart = function(opt){ - opt = opt || {} - // auth.deferred_product - if (! auth.deferred_product) { - console.log("VV NO DEFERRED PROD") - opt.success && opt.success() - return - } - sdk.cart.add_item({ - data: auth.deferred_product, - success: function(){ - console.log("ADDED ITEM") - app.header.increment_cart_count() - opt.success && opt.success() - }, - error: function(data){ - console.log("ERROR ADDING ITEM") - opt.error && opt.error() - }, - }) - auth.deferred_product = null - } - - auth.log_out = function(){ - auth.clear_user() - auth.clear_cart() - } - auth.logged_in = function(){ - return (auth.user_id && auth.user_id !== -1 && auth.user_id !== "undefined") - } - auth.has_cart = function(){ - return (sdk.cart.id && sdk.cart.id !== -1 && sdk.cart.id !== "undefined") - } - - return auth -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/cart.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/cart.js deleted file mode 100755 index 3ff2e1d2..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/cart.js +++ /dev/null @@ -1,248 +0,0 @@ -sdk.cart = (function(){ - var cart = {} - - cart.id = "" - cart.token = "" - - // https://gist.github.com/fanfare/9a50c524aea417d0bf3e - cart.initialize = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Cart.API/1.6", "carts.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-device": auth.device, - }, - data: "{}", - // data: opt.data, - success: function(data){ - cart.id = data["CartSession"]["CartId"] - cart.token = data["CartSession"]["CartToken"] - auth.set_cart( cart.id, cart.token ) - opt.success(data) - }, - error: opt.error, - }) - } - - cart.set_user = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/user.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify({ - "UserId": auth.user_id, - "UserToken": auth.access_token, - }), - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - // Code10, Size, Section - cart.add_item = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/items.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - cart.delete_item = function(opt){ - return $.ajax({ - method: "DELETE", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + - "/items/" + opt.data.Code10 + - "/" + opt.data.Size + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: "{}", - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - cart.get_status = function(opt){ - if (! cart.id) { - return opt.error({ error: "no cart" }) - } - return $.ajax({ - method: "GET", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - "x-yoox-device": auth.device, - }, - success: function(data){ - if (data['Error']) { - opt.error && opt.error(data) - } - else { - opt.success(data) - } - }, - error: opt.error, - }) - } - - cart.set_shipping_address = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/receiver.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify(opt.data), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - // NB: Payment type may simply be 1 (credit card) - cart.set_payment_type = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/paymentType.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - cart.get_card_types = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Cart.API/1.6", "cardTypes.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: "", - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - // use with full CC data if not storing it in wallet - cart.set_credit_card = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/creditCard.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - // use with a stored GUID - // NB: if "verification number" is 1, use CVV/CID/CVC security code - // if "verification number" is 2, use "Issue Number" - cart.use_stored_credit_card = function(opt){ - var data = { - "Guid": opt.data.guid, - "UserId": auth.user_id, - "AccessToken": auth.access_token, - } - if (opt.data.cvv) { - data["Cvv"] = opt.data.cvv - } - if (opt.data.issue) { - data["Issue"] = opt.data.issue - } - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/userCreditCard.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify(data), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - cart.secure_finalize = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/secureFinalizer.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - "x-yoox-device": auth.device, - }, - data: JSON.stringify( opt.data || {} ), - success: function(data){ - console.log(data) - // order number is: - // "Info": "2905Y07FA13020" - opt.success(data) - }, - error: opt.error, - }) - } - - cart.finalize = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Cart.API/1.6", "carts/" + cart.id + "/finalizer.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": cart.token, - }, - data: JSON.stringify( opt.data || {} ), - success: function(data){ - console.log(data) - // order number is: - // "Info": "2905Y07FA13020" - opt.success(data) - }, - error: opt.error, - }) - } - - return cart -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/payment.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/payment.js deleted file mode 100755 index 283fee92..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/payment.js +++ /dev/null @@ -1,72 +0,0 @@ -sdk.payment = (function(){ - var payment = {} - - payment.add_credit_card = function(opt){ - return $.ajax({ - method: "POST", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/cards.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: JSON.stringify( opt.data ), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - payment.list_credit_cards = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/cards.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: opt.data, - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - payment.delete_credit_card = function(opt){ - return $.ajax({ - method: "DELETE", - url: sdk.path("Account.API/1.5", "users/" + auth.user_id + "/cards/" + opt.guid + ".json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-account-token": auth.access_token, - }, - data: "{}", - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - payment.get_payment_types = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Cart.API/1.6", "availablePaymentTypes.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-device": auth.device, - }, - data: opt.data, - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - return payment -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/product.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/product.js deleted file mode 100755 index 671d1fea..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/product.js +++ /dev/null @@ -1,68 +0,0 @@ -sdk.product = (function(){ - var product = {} - - var default_gallery = 31617 - var default_department = "NkXStnsl" - - product.all = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Search.API/1.3", "search.json"), - data: { format: "full", productsPerPage: 100 }, - success: opt.success, - error: opt.error, - }) - } - - product.collection = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Search.API/1.3", "search.json"), - data: { format: "full", department: opt.department_id || default_department, productsPerPage: 100 }, - success: opt.success, - error: opt.error, - }) - } - - product.department_codes = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Search.API/1.3", "search/results.json"), - data: { format: "full", department: opt.department_id || default_department, page: 1 }, - success: opt.success, - error: opt.error, - }) - } - - product.collection_by_gallery = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Search.API/1.2", "search.json"), - data: { format: "full", gallery: opt.gallery_id || default_gallery, productsPerPage: 100 }, - success: opt.success, - error: opt.error, - }) - } - - // https://gist.github.com/fanfare/2d25d1b36944188948ff - product.item = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Item.API/1.0", "item/" + opt.code + ".json"), - success: opt.success, - error: opt.error, - }) - } - - product.search = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Search.API/1.2", "search.json"), - data: { format: "full", gallery: opt.gallery_id || default_gallery, textSearch: opt.query, productsPerPage: 100 }, - success: opt.success, - error: opt.error, - }) - } - - return product -})() \ No newline at end of file diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/shipping.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/shipping.js deleted file mode 100755 index 28a0db76..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/sdk/shipping.js +++ /dev/null @@ -1,85 +0,0 @@ -sdk.shipping = (function() { - var shipping = {} - - - // https://gist.github.com/fanfare/edb524128461b573d833 - - // BOX TYPE - - shipping.get_box_types = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Cart.API/1.6", "carts/" + sdk.cart.id + "/availableBoxTypes.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": sdk.cart.token, - }, - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - shipping.set_box_type = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + sdk.cart.id + "/boxType.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": sdk.cart.token, - }, - data: JSON.stringify({ - "Type": opt.type, - }), - success: function(data){ - // console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - - // DELIVERY TYPES - - // The response is different than described in the API reference.. - // https://gist.github.com/fanfare/15dfbca6a16ae6bed503 - - shipping.get_delivery_types = function(opt){ - return $.ajax({ - method: "GET", - url: sdk.path("Cart.API/1.6", "carts/" + sdk.cart.id + "/availableDeliveryTypes.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": sdk.cart.token, - }, - success: function(data){ - opt.success(data) - }, - error: opt.error, - }) - } - - shipping.set_delivery_type = function(opt){ - return $.ajax({ - method: "PUT", - url: sdk.path("Cart.API/1.6", "carts/" + sdk.cart.id + "/deliveryType.json"), - headers: { - "x-yoox-appname": auth.appname, - "x-yoox-cart-token": sdk.cart.token, - }, - data: JSON.stringify({ - "Id": opt.id, - }), - success: function(data){ - //console.log(data) - opt.success(data) - }, - error: opt.error, - }) - } - - return shipping -})() diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/fastclick.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/fastclick.js deleted file mode 100755 index 9c746c2b..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/fastclick.js +++ /dev/null @@ -1,790 +0,0 @@ -/** - * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs. - * - * @version 1.0.1 - * @codingstandard ftlabs-jsv2 - * @copyright The Financial Times Limited [All Rights Reserved] - * @license MIT License (see LICENSE.txt) - */ - -/*jslint browser:true, node:true*/ -/*global define, Event, Node*/ - - -/** - * Instantiate fast-clicking listeners on the specified layer. - * - * @constructor - * @param {Element} layer The layer to listen on - * @param {Object} options The options to override the defaults - */ -function FastClick(layer, options) { - 'use strict'; - var oldOnClick; - - options = options || {}; - - /** - * Whether a click is currently being tracked. - * - * @type boolean - */ - this.trackingClick = false; - - - /** - * Timestamp for when click tracking started. - * - * @type number - */ - this.trackingClickStart = 0; - - - /** - * The element being tracked for a click. - * - * @type EventTarget - */ - this.targetElement = null; - - - /** - * X-coordinate of touch start event. - * - * @type number - */ - this.touchStartX = 0; - - - /** - * Y-coordinate of touch start event. - * - * @type number - */ - this.touchStartY = 0; - - - /** - * ID of the last touch, retrieved from Touch.identifier. - * - * @type number - */ - this.lastTouchIdentifier = 0; - - - /** - * Touchmove boundary, beyond which a click will be cancelled. - * - * @type number - */ - this.touchBoundary = options.touchBoundary || 10; - - - /** - * The FastClick layer. - * - * @type Element - */ - this.layer = layer; - - /** - * The minimum time between tap(touchstart and touchend) events - * - * @type number - */ - this.tapDelay = options.tapDelay || 200; - - if (FastClick.notNeeded(layer)) { - return; - } - - // Some old versions of Android don't have Function.prototype.bind - function bind(method, context) { - return function() { return method.apply(context, arguments); }; - } - - - var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel']; - var context = this; - for (var i = 0, l = methods.length; i < l; i++) { - context[methods[i]] = bind(context[methods[i]], context); - } - - // Set up event handlers as required - if (deviceIsAndroid) { - layer.addEventListener('mouseover', this.onMouse, true); - layer.addEventListener('mousedown', this.onMouse, true); - layer.addEventListener('mouseup', this.onMouse, true); - } - - layer.addEventListener('click', this.onClick, true); - layer.addEventListener('touchstart', this.onTouchStart, false); - layer.addEventListener('touchmove', this.onTouchMove, false); - layer.addEventListener('touchend', this.onTouchEnd, false); - layer.addEventListener('touchcancel', this.onTouchCancel, false); - - // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) - // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick - // layer when they are cancelled. - if (!Event.prototype.stopImmediatePropagation) { - layer.removeEventListener = function(type, callback, capture) { - var rmv = Node.prototype.removeEventListener; - if (type === 'click') { - rmv.call(layer, type, callback.hijacked || callback, capture); - } else { - rmv.call(layer, type, callback, capture); - } - }; - - layer.addEventListener = function(type, callback, capture) { - var adv = Node.prototype.addEventListener; - if (type === 'click') { - adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) { - if (!event.propagationStopped) { - callback(event); - } - }), capture); - } else { - adv.call(layer, type, callback, capture); - } - }; - } - - // If a handler is already declared in the element's onclick attribute, it will be fired before - // FastClick's onClick handler. Fix this by pulling out the user-defined handler function and - // adding it as listener. - if (typeof layer.onclick === 'function') { - - // Android browser on at least 3.2 requires a new reference to the function in layer.onclick - // - the old one won't work if passed to addEventListener directly. - oldOnClick = layer.onclick; - layer.addEventListener('click', function(event) { - oldOnClick(event); - }, false); - layer.onclick = null; - } -} - - -/** - * Android requires exceptions. - * - * @type boolean - */ -var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0; - - -/** - * iOS requires exceptions. - * - * @type boolean - */ -var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent); - - -/** - * iOS 4 requires an exception for select elements. - * - * @type boolean - */ -var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent); - - -/** - * iOS 6.0(+?) requires the target element to be manually derived - * - * @type boolean - */ -var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS ([6-9]|\d{2})_\d/).test(navigator.userAgent); - - -/** - * Determine whether a given element requires a native click. - * - * @param {EventTarget|Element} target Target DOM element - * @returns {boolean} Returns true if the element needs a native click - */ -FastClick.prototype.needsClick = function(target) { - 'use strict'; - switch (target.nodeName.toLowerCase()) { - - // Don't send a synthetic click to disabled inputs (issue #62) - case 'button': - case 'select': - case 'textarea': - if (target.disabled) { - return true; - } - - break; - case 'input': - - // File inputs need real clicks on iOS 6 due to a browser bug (issue #68) - if ((deviceIsIOS && target.type === 'file') || target.disabled) { - return true; - } - - break; - case 'label': - case 'video': - return true; - } - - return (/\bneedsclick\b/).test(target.className); -}; - - -/** - * Determine whether a given element requires a call to focus to simulate click into element. - * - * @param {EventTarget|Element} target Target DOM element - * @returns {boolean} Returns true if the element requires a call to focus to simulate native click. - */ -FastClick.prototype.needsFocus = function(target) { - 'use strict'; - switch (target.nodeName.toLowerCase()) { - case 'textarea': - return true; - case 'select': - return !deviceIsAndroid; - case 'input': - switch (target.type) { - case 'button': - case 'checkbox': - case 'file': - case 'image': - case 'radio': - case 'submit': - return false; - } - - // No point in attempting to focus disabled inputs - return !target.disabled && !target.readOnly; - default: - return (/\bneedsfocus\b/).test(target.className); - } -}; - - -/** - * Send a click event to the specified element. - * - * @param {EventTarget|Element} targetElement - * @param {Event} event - */ -FastClick.prototype.sendClick = function(targetElement, event) { - 'use strict'; - var clickEvent, touch; - - // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24) - if (document.activeElement && document.activeElement !== targetElement) { - document.activeElement.blur(); - } - - touch = event.changedTouches[0]; - - // Synthesise a click event, with an extra attribute so it can be tracked - clickEvent = document.createEvent('MouseEvents'); - clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); - clickEvent.forwardedTouchEvent = true; - targetElement.dispatchEvent(clickEvent); -}; - -FastClick.prototype.determineEventType = function(targetElement) { - 'use strict'; - - //Issue #159: Android Chrome Select Box does not open with a synthetic click event - if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') { - return 'mousedown'; - } - - return 'click'; -}; - - -/** - * @param {EventTarget|Element} targetElement - */ -FastClick.prototype.focus = function(targetElement) { - 'use strict'; - var length; - - // Issue #160: on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724. - if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') { - length = targetElement.value.length; - targetElement.setSelectionRange(length, length); - } else { - targetElement.focus(); - } -}; - - -/** - * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it. - * - * @param {EventTarget|Element} targetElement - */ -FastClick.prototype.updateScrollParent = function(targetElement) { - 'use strict'; - var scrollParent, parentElement; - - scrollParent = targetElement.fastClickScrollParent; - - // Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the - // target element was moved to another parent. - if (!scrollParent || !scrollParent.contains(targetElement)) { - parentElement = targetElement; - do { - if (parentElement.scrollHeight > parentElement.offsetHeight) { - scrollParent = parentElement; - targetElement.fastClickScrollParent = parentElement; - break; - } - - parentElement = parentElement.parentElement; - } while (parentElement); - } - - // Always update the scroll top tracker if possible. - if (scrollParent) { - scrollParent.fastClickLastScrollTop = scrollParent.scrollTop; - } -}; - - -/** - * @param {EventTarget} targetElement - * @returns {Element|EventTarget} - */ -FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) { - 'use strict'; - - // On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node. - if (eventTarget.nodeType === Node.TEXT_NODE) { - return eventTarget.parentNode; - } - - return eventTarget; -}; - - -/** - * On touch start, record the position and scroll offset. - * - * @param {Event} event - * @returns {boolean} - */ -FastClick.prototype.onTouchStart = function(event) { - 'use strict'; - var targetElement, touch, selection; - - // Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111). - if (event.targetTouches.length > 1) { - return true; - } - - targetElement = this.getTargetElementFromEventTarget(event.target); - touch = event.targetTouches[0]; - - if (deviceIsIOS) { - - // Only trusted events will deselect text on iOS (issue #49) - selection = window.getSelection(); - if (selection.rangeCount && !selection.isCollapsed) { - return true; - } - - if (!deviceIsIOS4) { - - // Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23): - // when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched - // with the same identifier as the touch event that previously triggered the click that triggered the alert. - // Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an - // immediately preceeding touch event (issue #52), so this fix is unavailable on that platform. - if (touch.identifier === this.lastTouchIdentifier) { - event.preventDefault(); - return false; - } - - this.lastTouchIdentifier = touch.identifier; - - // If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and: - // 1) the user does a fling scroll on the scrollable layer - // 2) the user stops the fling scroll with another tap - // then the event.target of the last 'touchend' event will be the element that was under the user's finger - // when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check - // is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42). - this.updateScrollParent(targetElement); - } - } - - this.trackingClick = true; - this.trackingClickStart = event.timeStamp; - this.targetElement = targetElement; - - this.touchStartX = touch.pageX; - this.touchStartY = touch.pageY; - - // Prevent phantom clicks on fast double-tap (issue #36) - if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { - event.preventDefault(); - } - - return true; -}; - - -/** - * Based on a touchmove event object, check whether the touch has moved past a boundary since it started. - * - * @param {Event} event - * @returns {boolean} - */ -FastClick.prototype.touchHasMoved = function(event) { - 'use strict'; - var touch = event.changedTouches[0], boundary = this.touchBoundary; - - if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) { - return true; - } - - return false; -}; - - -/** - * Update the last position. - * - * @param {Event} event - * @returns {boolean} - */ -FastClick.prototype.onTouchMove = function(event) { - 'use strict'; - if (!this.trackingClick) { - return true; - } - - // If the touch has moved, cancel the click tracking - if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) { - this.trackingClick = false; - this.targetElement = null; - } - - return true; -}; - - -/** - * Attempt to find the labelled control for the given label element. - * - * @param {EventTarget|HTMLLabelElement} labelElement - * @returns {Element|null} - */ -FastClick.prototype.findControl = function(labelElement) { - 'use strict'; - - // Fast path for newer browsers supporting the HTML5 control attribute - if (labelElement.control !== undefined) { - return labelElement.control; - } - - // All browsers under test that support touch events also support the HTML5 htmlFor attribute - if (labelElement.htmlFor) { - return document.getElementById(labelElement.htmlFor); - } - - // If no for attribute exists, attempt to retrieve the first labellable descendant element - // the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label - return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea'); -}; - - -/** - * On touch end, determine whether to send a click event at once. - * - * @param {Event} event - * @returns {boolean} - */ -FastClick.prototype.onTouchEnd = function(event) { - 'use strict'; - var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement; - - if (!this.trackingClick) { - return true; - } - - // Prevent phantom clicks on fast double-tap (issue #36) - if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { - this.cancelNextClick = true; - return true; - } - - // Reset to prevent wrong click cancel on input (issue #156). - this.cancelNextClick = false; - - this.lastClickTime = event.timeStamp; - - trackingClickStart = this.trackingClickStart; - this.trackingClick = false; - this.trackingClickStart = 0; - - // On some iOS devices, the targetElement supplied with the event is invalid if the layer - // is performing a transition or scroll, and has to be re-detected manually. Note that - // for this to function correctly, it must be called *after* the event target is checked! - // See issue #57; also filed as rdar://13048589 . - if (deviceIsIOSWithBadTarget) { - touch = event.changedTouches[0]; - - // In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null - targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement; - targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent; - } - - targetTagName = targetElement.tagName.toLowerCase(); - if (targetTagName === 'label') { - forElement = this.findControl(targetElement); - if (forElement) { - this.focus(targetElement); - if (deviceIsAndroid) { - return false; - } - - targetElement = forElement; - } - } else if (this.needsFocus(targetElement)) { - - // Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through. - // Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37). - if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) { - this.targetElement = null; - return false; - } - - this.focus(targetElement); - this.sendClick(targetElement, event); - - // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open. - // Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others) - if (!deviceIsIOS || targetTagName !== 'select') { - this.targetElement = null; - event.preventDefault(); - } - - return false; - } - - if (deviceIsIOS && !deviceIsIOS4) { - - // Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled - // and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42). - scrollParent = targetElement.fastClickScrollParent; - if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) { - return true; - } - } - - // Prevent the actual click from going though - unless the target node is marked as requiring - // real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted. - if (!this.needsClick(targetElement)) { - event.preventDefault(); - this.sendClick(targetElement, event); - } - - return false; -}; - - -/** - * On touch cancel, stop tracking the click. - * - * @returns {void} - */ -FastClick.prototype.onTouchCancel = function() { - 'use strict'; - this.trackingClick = false; - this.targetElement = null; -}; - - -/** - * Determine mouse events which should be permitted. - * - * @param {Event} event - * @returns {boolean} - */ -FastClick.prototype.onMouse = function(event) { - 'use strict'; - - // If a target element was never set (because a touch event was never fired) allow the event - if (!this.targetElement) { - return true; - } - - if (event.forwardedTouchEvent) { - return true; - } - - // Programmatically generated events targeting a specific element should be permitted - if (!event.cancelable) { - return true; - } - - // Derive and check the target element to see whether the mouse event needs to be permitted; - // unless explicitly enabled, prevent non-touch click events from triggering actions, - // to prevent ghost/doubleclicks. - if (!this.needsClick(this.targetElement) || this.cancelNextClick) { - - // Prevent any user-added listeners declared on FastClick element from being fired. - if (event.stopImmediatePropagation) { - event.stopImmediatePropagation(); - } else { - - // Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) - event.propagationStopped = true; - } - - // Cancel the event - event.stopPropagation(); - event.preventDefault(); - - return false; - } - - // If the mouse event is permitted, return true for the action to go through. - return true; -}; - - -/** - * On actual clicks, determine whether this is a touch-generated click, a click action occurring - * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or - * an actual click which should be permitted. - * - * @param {Event} event - * @returns {boolean} - */ -FastClick.prototype.onClick = function(event) { - 'use strict'; - var permitted; - - // It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early. - if (this.trackingClick) { - this.targetElement = null; - this.trackingClick = false; - return true; - } - - // Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target. - if (event.target.type === 'submit' && event.detail === 0) { - return true; - } - - permitted = this.onMouse(event); - - // Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through. - if (!permitted) { - this.targetElement = null; - } - - // If clicks are permitted, return true for the action to go through. - return permitted; -}; - - -/** - * Remove all FastClick's event listeners. - * - * @returns {void} - */ -FastClick.prototype.destroy = function() { - 'use strict'; - var layer = this.layer; - - if (deviceIsAndroid) { - layer.removeEventListener('mouseover', this.onMouse, true); - layer.removeEventListener('mousedown', this.onMouse, true); - layer.removeEventListener('mouseup', this.onMouse, true); - } - - layer.removeEventListener('click', this.onClick, true); - layer.removeEventListener('touchstart', this.onTouchStart, false); - layer.removeEventListener('touchmove', this.onTouchMove, false); - layer.removeEventListener('touchend', this.onTouchEnd, false); - layer.removeEventListener('touchcancel', this.onTouchCancel, false); -}; - - -/** - * Check whether FastClick is needed. - * - * @param {Element} layer The layer to listen on - */ -FastClick.notNeeded = function(layer) { - 'use strict'; - var metaViewport; - var chromeVersion; - - // Devices that don't support touch don't need FastClick - if (typeof window.ontouchstart === 'undefined') { - return true; - } - - // Chrome version - zero for other browsers - chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1]; - - if (chromeVersion) { - - if (deviceIsAndroid) { - metaViewport = document.querySelector('meta[name=viewport]'); - - if (metaViewport) { - // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89) - if (metaViewport.content.indexOf('user-scalable=no') !== -1) { - return true; - } - // Chrome 32 and above with width=device-width or less don't need FastClick - if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) { - return true; - } - } - - // Chrome desktop doesn't need FastClick (issue #15) - } else { - return true; - } - } - - // IE10 with -ms-touch-action: none, which disables double-tap-to-zoom (issue #97) - if (layer.style.msTouchAction === 'none') { - return true; - } - - return false; -}; - - -/** - * Factory method for creating a FastClick object - * - * @param {Element} layer The layer to listen on - * @param {Object} options The options to override the defaults - */ -FastClick.attach = function(layer, options) { - 'use strict'; - return new FastClick(layer, options); -}; - - -if (typeof define !== 'undefined' && define.amd) { - - // AMD. Register as an anonymous module. - define(function() { - 'use strict'; - return FastClick; - }); -} else if (typeof module !== 'undefined' && module.exports) { - module.exports = FastClick.attach; - module.exports.FastClick = FastClick; -} else { - window.FastClick = FastClick; -} diff --git a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/flickity.pkgd.js b/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/flickity.pkgd.js deleted file mode 100755 index 0471fa5b..00000000 --- a/StoneIsland/platforms/ios/Stone Island.xcarchive/Products/Applications/Stone Island.app/www/js/vendor/flickity.pkgd.js +++ /dev/null @@ -1,5090 +0,0 @@ -/*! - * Flickity PACKAGED v1.0.1 - * Touch, responsive, flickable galleries - * - * Licensed GPLv3 for open source use - * or Flickity Commercial License for commercial use - * - * http://flickity.metafizzy.co - * Copyright 2015 Metafizzy - */ - -/** - * Bridget makes jQuery widgets - * v1.1.0 - * MIT license - */ - -( function( window ) { - - - -// -------------------------- utils -------------------------- // - -var slice = Array.prototype.slice; - -function noop() {} - -// -------------------------- definition -------------------------- // - -function defineBridget( $ ) { - -// bail if no jQuery -if ( !$ ) { - return; -} - -// -------------------------- addOptionMethod -------------------------- // - -/** - * adds option method -> $().plugin('option', {...}) - * @param {Function} PluginClass - constructor class - */ -function addOptionMethod( PluginClass ) { - // don't overwrite original option method - if ( PluginClass.prototype.option ) { - return; - } - - // option setter - PluginClass.prototype.option = function( opts ) { - // bail out if not an object - if ( !$.isPlainObject( opts ) ){ - return; - } - this.options = $.extend( true, this.options, opts ); - }; -} - -// -------------------------- plugin bridge -------------------------- // - -// helper function for logging errors -// $.error breaks jQuery chaining -var logError = typeof console === 'undefined' ? noop : - function( message ) { - console.error( message ); - }; - -/** - * jQuery plugin bridge, access methods like $elem.plugin('method') - * @param {String} namespace - plugin name - * @param {Function} PluginClass - constructor class - */ -function bridge( namespace, PluginClass ) { - // add to jQuery fn namespace - $.fn[ namespace ] = function( options ) { - if ( typeof options === 'string' ) { - // call plugin method when first argument is a string - // get arguments for method - var args = slice.call( arguments, 1 ); - - for ( var i=0, len = this.length; i < len; i++ ) { - var elem = this[i]; - var instance = $.data( elem, namespace ); - if ( !instance ) { - logError( "cannot call methods on " + namespace + " prior to initialization; " + - "attempted to call '" + options + "'" ); - continue; - } - if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) { - logError( "no such method '" + options + "' for " + namespace + " instance" ); - continue; - } - - // trigger method with arguments - var returnValue = instance[ options ].apply( instance, args ); - - // break look and return first value if provided - if ( returnValue !== undefined ) { - return returnValue; - } - } - // return this if no return value - return this; - } else { - return this.each( function() { - var instance = $.data( this, namespace ); - if ( instance ) { - // apply options & init - instance.option( options ); - instance._init(); - } else { - // initialize new instance - instance = new PluginClass( this, options ); - $.data( this, namespace, instance ); - } - }); - } - }; - -} - -// -------------------------- bridget -------------------------- // - -/** - * converts a Prototypical class into a proper jQuery plugin - * the class must have a ._init method - * @param {String} namespace - plugin name, used in $().pluginName - * @param {Function} PluginClass - constructor class - */ -$.bridget = function( namespace, PluginClass ) { - addOptionMethod( PluginClass ); - bridge( namespace, PluginClass ); -}; - -return $.bridget; - -} - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD - define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget ); -} else if ( typeof exports === 'object' ) { - defineBridget( require('jquery') ); -} else { - // get jquery from browser global - defineBridget( window.jQuery ); -} - -})( window ); - -/*! - * classie v1.0.1 - * class helper functions - * from bonzo https://github.com/ded/bonzo - * MIT license - * - * classie.has( elem, 'my-class' ) -> true/false - * classie.add( elem, 'my-new-class' ) - * classie.remove( elem, 'my-unwanted-class' ) - * classie.toggle( elem, 'my-class' ) - */ - -/*jshint browser: true, strict: true, undef: true, unused: true */ -/*global define: false, module: false */ - -( function( window ) { - - - -// class helper functions from bonzo https://github.com/ded/bonzo - -function classReg( className ) { - return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); -} - -// classList support for class management -// altho to be fair, the api sucks because it won't accept multiple classes at once -var hasClass, addClass, removeClass; - -if ( 'classList' in document.documentElement ) { - hasClass = function( elem, c ) { - return elem.classList.contains( c ); - }; - addClass = function( elem, c ) { - elem.classList.add( c ); - }; - removeClass = function( elem, c ) { - elem.classList.remove( c ); - }; -} -else { - hasClass = function( elem, c ) { - return classReg( c ).test( elem.className ); - }; - addClass = function( elem, c ) { - if ( !hasClass( elem, c ) ) { - elem.className = elem.className + ' ' + c; - } - }; - removeClass = function( elem, c ) { - elem.className = elem.className.replace( classReg( c ), ' ' ); - }; -} - -function toggleClass( elem, c ) { - var fn = hasClass( elem, c ) ? removeClass : addClass; - fn( elem, c ); -} - -var classie = { - // full names - hasClass: hasClass, - addClass: addClass, - removeClass: removeClass, - toggleClass: toggleClass, - // short names - has: hasClass, - add: addClass, - remove: removeClass, - toggle: toggleClass -}; - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD - define( 'classie/classie',classie ); -} else if ( typeof exports === 'object' ) { - // CommonJS - module.exports = classie; -} else { - // browser global - window.classie = classie; -} - -})( window ); - -/*! - * EventEmitter v4.2.11 - git.io/ee - * Unlicense - http://unlicense.org/ - * Oliver Caldwell - http://oli.me.uk/ - * @preserve - */ - -;(function () { - - - /** - * Class for managing events. - * Can be extended to provide event functionality in other classes. - * - * @class EventEmitter Manages event registering and emitting. - */ - function EventEmitter() {} - - // Shortcuts to improve speed and size - var proto = EventEmitter.prototype; - var exports = this; - var originalGlobalValue = exports.EventEmitter; - - /** - * Finds the index of the listener for the event in its storage array. - * - * @param {Function[]} listeners Array of listeners to search through. - * @param {Function} listener Method to look for. - * @return {Number} Index of the specified listener, -1 if not found - * @api private - */ - function indexOfListener(listeners, listener) { - var i = listeners.length; - while (i--) { - if (listeners[i].listener === listener) { - return i; - } - } - - return -1; - } - - /** - * Alias a method while keeping the context correct, to allow for overwriting of target method. - * - * @param {String} name The name of the target method. - * @return {Function} The aliased method - * @api private - */ - function alias(name) { - return function aliasClosure() { - return this[name].apply(this, arguments); - }; - } - - /** - * Returns the listener array for the specified event. - * Will initialise the event object and listener arrays if required. - * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. - * Each property in the object response is an array of listener functions. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Function[]|Object} All listener functions for the event. - */ - proto.getListeners = function getListeners(evt) { - var events = this._getEvents(); - var response; - var key; - - // Return a concatenated array of all matching events if - // the selector is a regular expression. - if (evt instanceof RegExp) { - response = {}; - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - response[key] = events[key]; - } - } - } - else { - response = events[evt] || (events[evt] = []); - } - - return response; - }; - - /** - * Takes a list of listener objects and flattens it into a list of listener functions. - * - * @param {Object[]} listeners Raw listener objects. - * @return {Function[]} Just the listener functions. - */ - proto.flattenListeners = function flattenListeners(listeners) { - var flatListeners = []; - var i; - - for (i = 0; i < listeners.length; i += 1) { - flatListeners.push(listeners[i].listener); - } - - return flatListeners; - }; - - /** - * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. - * - * @param {String|RegExp} evt Name of the event to return the listeners from. - * @return {Object} All listener functions for an event in an object. - */ - proto.getListenersAsObject = function getListenersAsObject(evt) { - var listeners = this.getListeners(evt); - var response; - - if (listeners instanceof Array) { - response = {}; - response[evt] = listeners; - } - - return response || listeners; - }; - - /** - * Adds a listener function to the specified event. - * The listener will not be added if it is a duplicate. - * If the listener returns true then it will be removed after it is called. - * If you pass a regular expression as the event name then the listener will be added to all events that match it. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListener = function addListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var listenerIsWrapped = typeof listener === 'object'; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { - listeners[key].push(listenerIsWrapped ? listener : { - listener: listener, - once: false - }); - } - } - - return this; - }; - - /** - * Alias of addListener - */ - proto.on = alias('addListener'); - - /** - * Semi-alias of addListener. It will add a listener that will be - * automatically removed after its first execution. - * - * @param {String|RegExp} evt Name of the event to attach the listener to. - * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addOnceListener = function addOnceListener(evt, listener) { - return this.addListener(evt, { - listener: listener, - once: true - }); - }; - - /** - * Alias of addOnceListener. - */ - proto.once = alias('addOnceListener'); - - /** - * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. - * You need to tell it what event names should be matched by a regex. - * - * @param {String} evt Name of the event to create. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvent = function defineEvent(evt) { - this.getListeners(evt); - return this; - }; - - /** - * Uses defineEvent to define multiple events. - * - * @param {String[]} evts An array of event names to define. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.defineEvents = function defineEvents(evts) { - for (var i = 0; i < evts.length; i += 1) { - this.defineEvent(evts[i]); - } - return this; - }; - - /** - * Removes a listener function from the specified event. - * When passed a regular expression as the event name, it will remove the listener from all events that match it. - * - * @param {String|RegExp} evt Name of the event to remove the listener from. - * @param {Function} listener Method to remove from the event. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListener = function removeListener(evt, listener) { - var listeners = this.getListenersAsObject(evt); - var index; - var key; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - index = indexOfListener(listeners[key], listener); - - if (index !== -1) { - listeners[key].splice(index, 1); - } - } - } - - return this; - }; - - /** - * Alias of removeListener - */ - proto.off = alias('removeListener'); - - /** - * Adds listeners in bulk using the manipulateListeners method. - * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. - * You can also pass it a regular expression to add the array of listeners to all events that match it. - * Yeah, this function does quite a bit. That's probably a bad thing. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.addListeners = function addListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(false, evt, listeners); - }; - - /** - * Removes listeners in bulk using the manipulateListeners method. - * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be removed. - * You can also pass it a regular expression to remove the listeners from all events that match it. - * - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeListeners = function removeListeners(evt, listeners) { - // Pass through to manipulateListeners - return this.manipulateListeners(true, evt, listeners); - }; - - /** - * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. - * The first argument will determine if the listeners are removed (true) or added (false). - * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. - * You can also pass it an event name and an array of listeners to be added/removed. - * You can also pass it a regular expression to manipulate the listeners of all events that match it. - * - * @param {Boolean} remove True if you want to remove listeners, false if you want to add. - * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. - * @param {Function[]} [listeners] An optional array of listener functions to add/remove. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { - var i; - var value; - var single = remove ? this.removeListener : this.addListener; - var multiple = remove ? this.removeListeners : this.addListeners; - - // If evt is an object then pass each of its properties to this method - if (typeof evt === 'object' && !(evt instanceof RegExp)) { - for (i in evt) { - if (evt.hasOwnProperty(i) && (value = evt[i])) { - // Pass the single listener straight through to the singular method - if (typeof value === 'function') { - single.call(this, i, value); - } - else { - // Otherwise pass back to the multiple function - multiple.call(this, i, value); - } - } - } - } - else { - // So evt must be a string - // And listeners must be an array of listeners - // Loop over it and pass each one to the multiple method - i = listeners.length; - while (i--) { - single.call(this, evt, listeners[i]); - } - } - - return this; - }; - - /** - * Removes all listeners from a specified event. - * If you do not specify an event then all listeners will be removed. - * That means every event will be emptied. - * You can also pass a regex to remove all events that match it. - * - * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.removeEvent = function removeEvent(evt) { - var type = typeof evt; - var events = this._getEvents(); - var key; - - // Remove different things depending on the state of evt - if (type === 'string') { - // Remove all listeners for the specified event - delete events[evt]; - } - else if (evt instanceof RegExp) { - // Remove all events matching the regex. - for (key in events) { - if (events.hasOwnProperty(key) && evt.test(key)) { - delete events[key]; - } - } - } - else { - // Remove all listeners in all events - delete this._events; - } - - return this; - }; - - /** - * Alias of removeEvent. - * - * Added to mirror the node API. - */ - proto.removeAllListeners = alias('removeEvent'); - - /** - * Emits an event of your choice. - * When emitted, every listener attached to that event will be executed. - * If you pass the optional argument array then those arguments will be passed to every listener upon execution. - * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately. - * So they will not arrive within the array on the other side, they will be separate. - * You can also pass a regular expression to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {Array} [args] Optional array of arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emitEvent = function emitEvent(evt, args) { - var listeners = this.getListenersAsObject(evt); - var listener; - var i; - var key; - var response; - - for (key in listeners) { - if (listeners.hasOwnProperty(key)) { - i = listeners[key].length; - - while (i--) { - // If the listener returns true then it shall be removed from the event - // The function is executed either with a basic call or an apply if there is an args array - listener = listeners[key][i]; - - if (listener.once === true) { - this.removeListener(evt, listener.listener); - } - - response = listener.listener.apply(this, args || []); - - if (response === this._getOnceReturnValue()) { - this.removeListener(evt, listener.listener); - } - } - } - } - - return this; - }; - - /** - * Alias of emitEvent - */ - proto.trigger = alias('emitEvent'); - - /** - * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. - * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. - * - * @param {String|RegExp} evt Name of the event to emit and execute listeners for. - * @param {...*} Optional additional arguments to be passed to each listener. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.emit = function emit(evt) { - var args = Array.prototype.slice.call(arguments, 1); - return this.emitEvent(evt, args); - }; - - /** - * Sets the current value to check against when executing listeners. If a - * listeners return value matches the one set here then it will be removed - * after execution. This value defaults to true. - * - * @param {*} value The new value to check for when executing listeners. - * @return {Object} Current instance of EventEmitter for chaining. - */ - proto.setOnceReturnValue = function setOnceReturnValue(value) { - this._onceReturnValue = value; - return this; - }; - - /** - * Fetches the current value to check against when executing listeners. If - * the listeners return value matches this one then it should be removed - * automatically. It will return true by default. - * - * @return {*|Boolean} The current value to check for or the default, true. - * @api private - */ - proto._getOnceReturnValue = function _getOnceReturnValue() { - if (this.hasOwnProperty('_onceReturnValue')) { - return this._onceReturnValue; - } - else { - return true; - } - }; - - /** - * Fetches the events object and creates one if required. - * - * @return {Object} The events storage object. - * @api private - */ - proto._getEvents = function _getEvents() { - return this._events || (this._events = {}); - }; - - /** - * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. - * - * @return {Function} Non conflicting EventEmitter class. - */ - EventEmitter.noConflict = function noConflict() { - exports.EventEmitter = originalGlobalValue; - return EventEmitter; - }; - - // Expose the class either via AMD, CommonJS or the global object - if (typeof define === 'function' && define.amd) { - define('eventEmitter/EventEmitter',[],function () { - return EventEmitter; - }); - } - else if (typeof module === 'object' && module.exports){ - module.exports = EventEmitter; - } - else { - exports.EventEmitter = EventEmitter; - } -}.call(this)); - -/*! - * eventie v1.0.6 - * event binding helper - * eventie.bind( elem, 'click', myFn ) - * eventie.unbind( elem, 'click', myFn ) - * MIT license - */ - -/*jshint browser: true, undef: true, unused: true */ -/*global define: false, module: false */ - -( function( window ) { - - - -var docElem = document.documentElement; - -var bind = function() {}; - -function getIEEvent( obj ) { - var event = window.event; - // add event.target - event.target = event.target || event.srcElement || obj; - return event; -} - -if ( docElem.addEventListener ) { - bind = function( obj, type, fn ) { - obj.addEventListener( type, fn, false ); - }; -} else if ( docElem.attachEvent ) { - bind = function( obj, type, fn ) { - obj[ type + fn ] = fn.handleEvent ? - function() { - var event = getIEEvent( obj ); - fn.handleEvent.call( fn, event ); - } : - function() { - var event = getIEEvent( obj ); - fn.call( obj, event ); - }; - obj.attachEvent( "on" + type, obj[ type + fn ] ); - }; -} - -var unbind = function() {}; - -if ( docElem.removeEventListener ) { - unbind = function( obj, type, fn ) { - obj.removeEventListener( type, fn, false ); - }; -} else if ( docElem.detachEvent ) { - unbind = function( obj, type, fn ) { - obj.detachEvent( "on" + type, obj[ type + fn ] ); - try { - delete obj[ type + fn ]; - } catch ( err ) { - // can't delete window object properties - obj[ type + fn ] = undefined; - } - }; -} - -var eventie = { - bind: bind, - unbind: unbind -}; - -// ----- module definition ----- // - -if ( typeof define === 'function' && define.amd ) { - // AMD - define( 'eventie/eventie',eventie ); -} else if ( typeof exports === 'object' ) { - // CommonJS - module.exports = eventie; -} else { - // browser global - window.eventie = eventie; -} - -})( window ); - -/*! - * getStyleProperty v1.0.4 - * original by kangax - * http://perfectionkills.com/feature-testing-css-properties/ - * MIT license - */ - -/*jshint browser: true, strict: true, undef: true */ -/*global define: false, exports: false, module: false */ - -( function( window ) { - - - -var prefixes = 'Webkit Moz ms Ms O'.split(' '); -var docElemStyle = document.documentElement.style; - -function getStyleProperty( propName ) { - if ( !propName ) { - return; - } - - // test standard property first - if ( typeof docElemStyle[ propName ] === 'string' ) { - return propName; - } - - // capitalize - propName = propName.charAt(0).toUpperCase() + propName.slice(1); - - // test vendor specific properties - var prefixed; - for ( var i=0, len = prefixes.length; i < len; i++ ) { - prefixed = prefixes[i] + propName; - if ( typeof docElemStyle[ prefixed ] === 'string' ) { - return prefixed; - } - } -} - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD - define( 'get-style-property/get-style-property',[],function() { - return getStyleProperty; - }); -} else if ( typeof exports === 'object' ) { - // CommonJS for Component - module.exports = getStyleProperty; -} else { - // browser global - window.getStyleProperty = getStyleProperty; -} - -})( window ); - -/*! - * getSize v1.2.2 - * measure size of elements - * MIT license - */ - -/*jshint browser: true, strict: true, undef: true, unused: true */ -/*global define: false, exports: false, require: false, module: false, console: false */ - -( function( window, undefined ) { - - - -// -------------------------- helpers -------------------------- // - -// get a number from a string, not a percentage -function getStyleSize( value ) { - var num = parseFloat( value ); - // not a percent like '100%', and a number - var isValid = value.indexOf('%') === -1 && !isNaN( num ); - return isValid && num; -} - -function noop() {} - -var logError = typeof console === 'undefined' ? noop : - function( message ) { - console.error( message ); - }; - -// -------------------------- measurements -------------------------- // - -var measurements = [ - 'paddingLeft', - 'paddingRight', - 'paddingTop', - 'paddingBottom', - 'marginLeft', - 'marginRight', - 'marginTop', - 'marginBottom', - 'borderLeftWidth', - 'borderRightWidth', - 'borderTopWidth', - 'borderBottomWidth' -]; - -function getZeroSize() { - var size = { - width: 0, - height: 0, - innerWidth: 0, - innerHeight: 0, - outerWidth: 0, - outerHeight: 0 - }; - for ( var i=0, len = measurements.length; i < len; i++ ) { - var measurement = measurements[i]; - size[ measurement ] = 0; - } - return size; -} - - - -function defineGetSize( getStyleProperty ) { - -// -------------------------- setup -------------------------- // - -var isSetup = false; - -var getStyle, boxSizingProp, isBoxSizeOuter; - -/** - * setup vars and functions - * do it on initial getSize(), rather than on script load - * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397 - */ -function setup() { - // setup once - if ( isSetup ) { - return; - } - isSetup = true; - - var getComputedStyle = window.getComputedStyle; - getStyle = ( function() { - var getStyleFn = getComputedStyle ? - function( elem ) { - return getComputedStyle( elem, null ); - } : - function( elem ) { - return elem.currentStyle; - }; - - return function getStyle( elem ) { - var style = getStyleFn( elem ); - if ( !style ) { - logError( 'Style returned ' + style + - '. Are you running this code in a hidden iframe on Firefox? ' + - 'See http://bit.ly/getsizebug1' ); - } - return style; - }; - })(); - - // -------------------------- box sizing -------------------------- // - - boxSizingProp = getStyleProperty('boxSizing'); - - /** - * WebKit measures the outer-width on style.width on border-box elems - * IE & Firefox measures the inner-width - */ - if ( boxSizingProp ) { - var div = document.createElement('div'); - div.style.width = '200px'; - div.style.padding = '1px 2px 3px 4px'; - div.style.borderStyle = 'solid'; - div.style.borderWidth = '1px 2px 3px 4px'; - div.style[ boxSizingProp ] = 'border-box'; - - var body = document.body || document.documentElement; - body.appendChild( div ); - var style = getStyle( div ); - - isBoxSizeOuter = getStyleSize( style.width ) === 200; - body.removeChild( div ); - } - -} - -// -------------------------- getSize -------------------------- // - -function getSize( elem ) { - setup(); - - // use querySeletor if elem is string - if ( typeof elem === 'string' ) { - elem = document.querySelector( elem ); - } - - // do not proceed on non-objects - if ( !elem || typeof elem !== 'object' || !elem.nodeType ) { - return; - } - - var style = getStyle( elem ); - - // if hidden, everything is 0 - if ( style.display === 'none' ) { - return getZeroSize(); - } - - var size = {}; - size.width = elem.offsetWidth; - size.height = elem.offsetHeight; - - var isBorderBox = size.isBorderBox = !!( boxSizingProp && - style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' ); - - // get all measurements - for ( var i=0, len = measurements.length; i < len; i++ ) { - var measurement = measurements[i]; - var value = style[ measurement ]; - value = mungeNonPixel( elem, value ); - var num = parseFloat( value ); - // any 'auto', 'medium' value will be 0 - size[ measurement ] = !isNaN( num ) ? num : 0; - } - - var paddingWidth = size.paddingLeft + size.paddingRight; - var paddingHeight = size.paddingTop + size.paddingBottom; - var marginWidth = size.marginLeft + size.marginRight; - var marginHeight = size.marginTop + size.marginBottom; - var borderWidth = size.borderLeftWidth + size.borderRightWidth; - var borderHeight = size.borderTopWidth + size.borderBottomWidth; - - var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; - - // overwrite width and height if we can get it from style - var styleWidth = getStyleSize( style.width ); - if ( styleWidth !== false ) { - size.width = styleWidth + - // add padding and border unless it's already including it - ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); - } - - var styleHeight = getStyleSize( style.height ); - if ( styleHeight !== false ) { - size.height = styleHeight + - // add padding and border unless it's already including it - ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); - } - - size.innerWidth = size.width - ( paddingWidth + borderWidth ); - size.innerHeight = size.height - ( paddingHeight + borderHeight ); - - size.outerWidth = size.width + marginWidth; - size.outerHeight = size.height + marginHeight; - - return size; -} - -// IE8 returns percent values, not pixels -// taken from jQuery's curCSS -function mungeNonPixel( elem, value ) { - // IE8 and has percent value - if ( window.getComputedStyle || value.indexOf('%') === -1 ) { - return value; - } - var style = elem.style; - // Remember the original values - var left = style.left; - var rs = elem.runtimeStyle; - var rsLeft = rs && rs.left; - - // Put in the new values to get a computed value out - if ( rsLeft ) { - rs.left = elem.currentStyle.left; - } - style.left = value; - value = style.pixelLeft; - - // Revert the changed values - style.left = left; - if ( rsLeft ) { - rs.left = rsLeft; - } - - return value; -} - -return getSize; - -} - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD for RequireJS - define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize ); -} else if ( typeof exports === 'object' ) { - // CommonJS for Component - module.exports = defineGetSize( require('desandro-get-style-property') ); -} else { - // browser global - window.getSize = defineGetSize( window.getStyleProperty ); -} - -})( window ); - -/*! - * docReady v1.0.4 - * Cross browser DOMContentLoaded event emitter - * MIT license - */ - -/*jshint browser: true, strict: true, undef: true, unused: true*/ -/*global define: false, require: false, module: false */ - -( function( window ) { - - - -var document = window.document; -// collection of functions to be triggered on ready -var queue = []; - -function docReady( fn ) { - // throw out non-functions - if ( typeof fn !== 'function' ) { - return; - } - - if ( docReady.isReady ) { - // ready now, hit it - fn(); - } else { - // queue function when ready - queue.push( fn ); - } -} - -docReady.isReady = false; - -// triggered on various doc ready events -function onReady( event ) { - // bail if already triggered or IE8 document is not ready just yet - var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete'; - if ( docReady.isReady || isIE8NotReady ) { - return; - } - - trigger(); -} - -function trigger() { - docReady.isReady = true; - // process queue - for ( var i=0, len = queue.length; i < len; i++ ) { - var fn = queue[i]; - fn(); - } -} - -function defineDocReady( eventie ) { - // trigger ready if page is ready - if ( document.readyState === 'complete' ) { - trigger(); - } else { - // listen for events - eventie.bind( document, 'DOMContentLoaded', onReady ); - eventie.bind( document, 'readystatechange', onReady ); - eventie.bind( window, 'load', onReady ); - } - - return docReady; -} - -// transport -if ( typeof define === 'function' && define.amd ) { - // AMD - define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady ); -} else if ( typeof exports === 'object' ) { - module.exports = defineDocReady( require('eventie') ); -} else { - // browser global - window.docReady = defineDocReady( window.eventie ); -} - -})( window ); - -/** - * matchesSelector v1.0.3 - * matchesSelector( element, '.selector' ) - * MIT license - */ - -/*jshint browser: true, strict: true, undef: true, unused: true */ -/*global define: false, module: false */ - -( function( ElemProto ) { - - - - var matchesMethod = ( function() { - // check for the standard method name first - if ( ElemProto.matches ) { - return 'matches'; - } - // check un-prefixed - if ( ElemProto.matchesSelector ) { - return 'matchesSelector'; - } - // check vendor prefixes - var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; - - for ( var i=0, len = prefixes.length; i < len; i++ ) { - var prefix = prefixes[i]; - var method = prefix + 'MatchesSelector'; - if ( ElemProto[ method ] ) { - return method; - } - } - })(); - - // ----- match ----- // - - function match( elem, selector ) { - return elem[ matchesMethod ]( selector ); - } - - // ----- appendToFragment ----- // - - function checkParent( elem ) { - // not needed if already has parent - if ( elem.parentNode ) { - return; - } - var fragment = document.createDocumentFragment(); - fragment.appendChild( elem ); - } - - // ----- query ----- // - - // fall back to using QSA - // thx @jonathantneal https://gist.github.com/3062955 - function query( elem, selector ) { - // append to fragment if no parent - checkParent( elem ); - - // match elem with all selected elems of parent - var elems = elem.parentNode.querySelectorAll( selector ); - for ( var i=0, len = elems.length; i < len; i++ ) { - // return true if match - if ( elems[i] === elem ) { - return true; - } - } - // otherwise return false - return false; - } - - // ----- matchChild ----- // - - function matchChild( elem, selector ) { - checkParent( elem ); - return match( elem, selector ); - } - - // ----- matchesSelector ----- // - - var matchesSelector; - - if ( matchesMethod ) { - // IE9 supports matchesSelector, but doesn't work on orphaned elems - // check for that - var div = document.createElement('div'); - var supportsOrphans = match( div, 'div' ); - matchesSelector = supportsOrphans ? match : matchChild; - } else { - matchesSelector = query; - } - - // transport - if ( typeof define === 'function' && define.amd ) { - // AMD - define( 'matches-selector/matches-selector',[],function() { - return matchesSelector; - }); - } else if ( typeof exports === 'object' ) { - module.exports = matchesSelector; - } - else { - // browser global - window.matchesSelector = matchesSelector; - } - -})( Element.prototype ); - -/** - * Fizzy UI utils v1.0.1 - * MIT license - */ - -/*jshint browser: true, undef: true, unused: true, strict: true */ - -( function( window, factory ) { - /*global define: false, module: false, require: false */ - - // universal module definition - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( 'fizzy-ui-utils/utils',[ - 'doc-ready/doc-ready', - 'matches-selector/matches-selector' - ], function( docReady, matchesSelector ) { - return factory( window, docReady, matchesSelector ); - }); - } else if ( typeof exports == 'object' ) { - // CommonJS - module.exports = factory( - window, - require('doc-ready'), - require('desandro-matches-selector') - ); - } else { - // browser global - window.fizzyUIUtils = factory( - window, - window.docReady, - window.matchesSelector - ); - } - -}( window, function factory( window, docReady, matchesSelector ) { - - - -var utils = {}; - -// ----- extend ----- // - -// extends objects -utils.extend = function( a, b ) { - for ( var prop in b ) { - a[ prop ] = b[ prop ]; - } - return a; -}; - -// ----- modulo ----- // - -utils.modulo = function( num, div ) { - return ( ( num % div ) + div ) % div; -}; - -// ----- isArray ----- // - -var objToString = Object.prototype.toString; -utils.isArray = function( obj ) { - return objToString.call( obj ) == '[object Array]'; -}; - -// ----- makeArray ----- // - -// turn element or nodeList into an array -utils.makeArray = function( obj ) { - var ary = []; - if ( utils.isArray( obj ) ) { - // use object if already an array - ary = obj; - } else if ( obj && typeof obj.length == 'number' ) { - // convert nodeList to array - for ( var i=0, len = obj.length; i < len; i++ ) { - ary.push( obj[i] ); - } - } else { - // array of single index - ary.push( obj ); - } - return ary; -}; - -// ----- indexOf ----- // - -// index of helper cause IE8 -utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) { - return ary.indexOf( obj ); - } : function( ary, obj ) { - for ( var i=0, len = ary.length; i < len; i++ ) { - if ( ary[i] === obj ) { - return i; - } - } - return -1; - }; - -// ----- removeFrom ----- // - -utils.removeFrom = function( ary, obj ) { - var index = utils.indexOf( ary, obj ); - if ( index != -1 ) { - ary.splice( index, 1 ); - } -}; - -// ----- isElement ----- // - -// http://stackoverflow.com/a/384380/182183 -utils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ? - function isElementDOM2( obj ) { - return obj instanceof HTMLElement; - } : - function isElementQuirky( obj ) { - return obj && typeof obj == 'object' && - obj.nodeType == 1 && typeof obj.nodeName == 'string'; - }; - -// ----- setText ----- // - -utils.setText = ( function() { - var setTextProperty; - function setText( elem, text ) { - // only check setTextProperty once - setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' ); - elem[ setTextProperty ] = text; - } - return setText; -})(); - -// ----- getParent ----- // - -utils.getParent = function( elem, selector ) { - while ( elem != document.body ) { - elem = elem.parentNode; - if ( matchesSelector( elem, selector ) ) { - return elem; - } - } -}; - -// ----- getQueryElement ----- // - -// use element as selector string -utils.getQueryElement = function( elem ) { - if ( typeof elem == 'string' ) { - return document.querySelector( elem ); - } - return elem; -}; - -// ----- handleEvent ----- // - -// enable .ontype to trigger from .addEventListener( elem, 'type' ) -utils.handleEvent = function( event ) { - var method = 'on' + event.type; - if ( this[ method ] ) { - this[ method ]( event ); - } -}; - -// ----- filterFindElements ----- // - -utils.filterFindElements = function( elems, selector ) { - // make array of elems - elems = utils.makeArray( elems ); - var ffElems = []; - - for ( var i=0, len = elems.length; i < len; i++ ) { - var elem = elems[i]; - // check that elem is an actual element - if ( !utils.isElement( elem ) ) { - continue; - } - // filter & find items if we have a selector - if ( selector ) { - // filter siblings - if ( matchesSelector( elem, selector ) ) { - ffElems.push( elem ); - } - // find children - var childElems = elem.querySelectorAll( selector ); - // concat childElems to filterFound array - for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { - ffElems.push( childElems[j] ); - } - } else { - ffElems.push( elem ); - } - } - - return ffElems; -}; - -// ----- debounceMethod ----- // - -utils.debounceMethod = function( _class, methodName, threshold ) { - // original method - var method = _class.prototype[ methodName ]; - var timeoutName = methodName + 'Timeout'; - - _class.prototype[ methodName ] = function() { - var timeout = this[ timeoutName ]; - if ( timeout ) { - clearTimeout( timeout ); - } - var args = arguments; - - var _this = this; - this[ timeoutName ] = setTimeout( function() { - method.apply( _this, args ); - delete _this[ timeoutName ]; - }, threshold || 100 ); - }; -}; - -// ----- htmlInit ----- // - -// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ -utils.toDashed = function( str ) { - return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { - return $1 + '-' + $2; - }).toLowerCase(); -}; - -var console = window.console; -/** - * allow user to initialize classes via .js-namespace class - * htmlInit( Widget, 'widgetName' ) - * options are parsed from data-namespace-option attribute - */ -utils.htmlInit = function( WidgetClass, namespace ) { - docReady( function() { - var dashedNamespace = utils.toDashed( namespace ); - var elems = document.querySelectorAll( '.js-' + dashedNamespace ); - var dataAttr = 'data-' + dashedNamespace + '-options'; - - for ( var i=0, len = elems.length; i < len; i++ ) { - var elem = elems[i]; - var attr = elem.getAttribute( dataAttr ); - var options; - try { - options = attr && JSON.parse( attr ); - } catch ( error ) { - // log error, do not initialize - if ( console ) { - console.error( 'Error parsing ' + dataAttr + ' on ' + - elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' + - error ); - } - continue; - } - // initialize - var instance = new WidgetClass( elem, options ); - // make available via $().data('layoutname') - var jQuery = window.jQuery; - if ( jQuery ) { - jQuery.data( elem, namespace, instance ); - } - } - }); -}; - -// ----- ----- // - -return utils; - -})); - -( function( window, factory ) { - - // universal module definition - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( 'flickity/js/cell',[ - 'get-size/get-size' - ], function( getSize ) { - return factory( window, getSize ); - }); - } else if ( typeof exports == 'object' ) { - // CommonJS - module.exports = factory( - window, - require('get-size') - ); - } else { - // browser global - window.Flickity = window.Flickity || {}; - window.Flickity.Cell = factory( - window, - window.getSize - ); - } - -}( window, function factory( window, getSize ) { - - - -function Cell( elem, parent ) { - this.element = elem; - this.parent = parent; - - this.create(); -} - -var isIE8 = 'attachEvent' in window; - -Cell.prototype.create = function() { - this.element.style.position = 'absolute'; - // IE8 prevent child from changing focus http://stackoverflow.com/a/17525223/182183 - if ( isIE8 ) { - this.element.setAttribute( 'unselectable', 'on' ); - } - this.x = 0; - this.shift = 0; -}; - -Cell.prototype.destroy = function() { - // reset style - this.element.style.position = ''; - var side = this.parent.originSide; - this.element.style[ side ] = ''; -}; - -Cell.prototype.getSize = function() { - this.size = getSize( this.element ); -}; - -Cell.prototype.setPosition = function( x ) { - this.x = x; - this.setDefaultTarget(); - this.renderPosition( x ); -}; - -Cell.prototype.setDefaultTarget = function() { - var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight'; - this.target = this.x + this.size[ marginProperty ] + - this.size.width * this.parent.cellAlign; -}; - -Cell.prototype.renderPosition = function( x ) { - // render position of cell with in slider - var side = this.parent.originSide; - this.element.style[ side ] = this.parent.getPositionValue( x ); -}; - -/** - * @param {Integer} factor - 0, 1, or -1 -**/ -Cell.prototype.wrapShift = function( shift ) { - this.shift = shift; - this.renderPosition( this.x + this.parent.slideableWidth * shift ); -}; - -Cell.prototype.remove = function() { - this.element.parentNode.removeChild( this.element ); -}; - -return Cell; - -})); - -( function( window, factory ) { - - // universal module definition - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( 'flickity/js/animate',[ - 'get-style-property/get-style-property', - 'fizzy-ui-utils/utils' - ], function( getStyleProperty, utils ) { - return factory( window, getStyleProperty, utils ); - }); - } else if ( typeof exports == 'object' ) { - // CommonJS - module.exports = factory( - window, - require('desandro-get-style-property'), - require('fizzy-ui-utils') - ); - } else { - // browser global - window.Flickity = window.Flickity || {}; - window.Flickity.animatePrototype = factory( - window, - window.getStyleProperty, - window.fizzyUIUtils - ); - } - -}( window, function factory( window, getStyleProperty, utils ) { - - - -// -------------------------- requestAnimationFrame -------------------------- // - -// https://gist.github.com/1866474 - -var lastTime = 0; -var prefixes = 'webkit moz ms o'.split(' '); -// get unprefixed rAF and cAF, if present -var requestAnimationFrame = window.requestAnimationFrame; -var cancelAnimationFrame = window.cancelAnimationFrame; -// loop through vendor prefixes and get prefixed rAF and cAF -var prefix; -for( var i = 0; i < prefixes.length; i++ ) { - if ( requestAnimationFrame && cancelAnimationFrame ) { - break; - } - prefix = prefixes[i]; - requestAnimationFrame = requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ]; - cancelAnimationFrame = cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] || - window[ prefix + 'CancelRequestAnimationFrame' ]; -} - -// fallback to setTimeout and clearTimeout if either request/cancel is not supported -if ( !requestAnimationFrame || !cancelAnimationFrame ) { - requestAnimationFrame = function( callback ) { - var currTime = new Date().getTime(); - var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ); - var id = window.setTimeout( function() { - callback( currTime + timeToCall ); - }, timeToCall ); - lastTime = currTime + timeToCall; - return id; - }; - - cancelAnimationFrame = function( id ) { - window.clearTimeout( id ); - }; -} - -// -------------------------- animate -------------------------- // - -var proto = {}; - -proto.startAnimation = function() { - if ( this.isAnimating ) { - return; - } - - this.isAnimating = true; - this.restingFrames = 0; - this.animate(); -}; - -proto.animate = function() { - this.applySelectedAttraction(); - - var previousX = this.x; - - this.integratePhysics(); - this.positionSlider(); - this.settle( previousX ); - // animate next frame - if ( this.isAnimating ) { - var _this = this; - requestAnimationFrame( function animateFrame() { - _this.animate(); - }); - } - - /** / - // log animation frame rate - var now = new Date(); - if ( this.then ) { - console.log( ~~( 1000 / (now-this.then)) + 'fps' ) - } - this.then = now; - /**/ -}; - - -var transformProperty = getStyleProperty('transform'); -var is3d = !!getStyleProperty('perspective'); - -proto.positionSlider = function() { - var x = this.x; - // wrap position around - if ( this.options.wrapAround && this.cells.length > 1 ) { - x = utils.modulo( x, this.slideableWidth ); - x = x - this.slideableWidth; - this.shiftWrapCells( x ); - } - - x = x + this.cursorPosition; - - // reverse if right-to-left and using transform - x = this.options.rightToLeft && transformProperty ? -x : x; - - var value = this.getPositionValue( x ); - - if ( transformProperty ) { - // use 3D tranforms for hardware acceleration on iOS - // but use 2D when settled, for better font-rendering - this.slider.style[ transformProperty ] = is3d && this.isAnimating ? - 'translate3d(' + value + ',0,0)' : 'translateX(' + value + ')'; - } else { - this.slider.style[ this.originSide ] = value; - } -}; - -proto.positionSliderAtSelected = function() { - if ( !this.cells.length ) { - return; - } - var selectedCell = this.cells[ this.selectedIndex ]; - this.x = -selectedCell.target; - this.positionSlider(); -}; - -proto.getPositionValue = function( position ) { - if ( this.options.percentPosition ) { - // percent position, round to 2 digits, like 12.34% - return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 )+ '%'; - } else { - // pixel positioning - return Math.round( position ) + 'px'; - } -}; - -proto.settle = function( previousX ) { - // keep track of frames where x hasn't moved - if ( !this.isPointerDown && Math.round( this.x * 100 ) == Math.round( previousX * 100 ) ) { - this.restingFrames++; - } - // stop animating if resting for 3 or more frames - if ( this.restingFrames > 2 ) { - this.isAnimating = false; - delete this.isFreeScrolling; - // render position with translateX when settled - if ( is3d ) { - this.positionSlider(); - } - this.dispatchEvent('settle'); - } -}; - -proto.shiftWrapCells = function( x ) { - // shift before cells - var beforeGap = this.cursorPosition + x; - this._shiftCells( this.beforeShiftCells, beforeGap, -1 ); - // shift after cells - var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition ); - this._shiftCells( this.afterShiftCells, afterGap, 1 ); -}; - -proto._shiftCells = function( cells, gap, shift ) { - for ( var i=0, len = cells.length; i < len; i++ ) { - var cell = cells[i]; - var cellShift = gap > 0 ? shift : 0; - cell.wrapShift( cellShift ); - gap -= cell.size.outerWidth; - } -}; - -proto._unshiftCells = function( cells ) { - if ( !cells || !cells.length ) { - return; - } - for ( var i=0, len = cells.length; i < len; i++ ) { - cells[i].wrapShift( 0 ); - } -}; - -// -------------------------- physics -------------------------- // - -proto.integratePhysics = function() { - this.velocity += this.accel; - this.x += this.velocity; - this.velocity *= this.getFrictionFactor(); - // reset acceleration - this.accel = 0; -}; - -proto.applyForce = function( force ) { - this.accel += force; -}; - -proto.getFrictionFactor = function() { - return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ]; -}; - - -proto.getRestingPosition = function() { - // my thanks to Steven Wittens, who simplified this math greatly - return this.x + this.velocity / ( 1 - this.getFrictionFactor() ); -}; - - -proto.applySelectedAttraction = function() { - // do not attract if pointer down or no cells - var len = this.cells.length; - if ( this.isPointerDown || this.isFreeScrolling || !len ) { - return; - } - var cell = this.cells[ this.selectedIndex ]; - var wrap = this.options.wrapAround && len > 1 ? - this.slideableWidth * Math.floor( this.selectedIndex / len ) : 0; - var distance = ( cell.target + wrap ) * -1 - this.x; - var force = distance * this.options.selectedAttraction; - this.applyForce( force ); -}; - -return proto; - -})); - -/*! - * Flickity v1.0.1 - * Touch, responsive, flickable galleries - * - * Licensed GPLv3 for open source use - * or Flickity Commercial License for commercial use - * - * http://flickity.metafizzy.co - * Copyright 2015 Metafizzy - */ - -( function( window, factory ) { - - // universal module definition - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( 'flickity/js/flickity',[ - 'classie/classie', - 'eventEmitter/EventEmitter', - 'eventie/eventie', - 'get-size/get-size', - 'fizzy-ui-utils/utils', - './cell', - './animate' - ], function( classie, EventEmitter, eventie, getSize, utils, Cell, animatePrototype ) { - return factory( window, classie, EventEmitter, eventie, getSize, utils, Cell, animatePrototype ); - }); - } else if ( typeof exports == 'object' ) { - // CommonJS - module.exports = factory( - window, - require('desandro-classie'), - require('wolfy87-eventemitter'), - require('eventie'), - require('get-size'), - require('fizzy-ui-utils'), - require('./cell'), - require('./animate') - ); - } else { - // browser global - var _Flickity = window.Flickity; - - window.Flickity = factory( - window, - window.classie, - window.EventEmitter, - window.eventie, - window.getSize, - window.fizzyUIUtils, - _Flickity.Cell, - _Flickity.animatePrototype - ); - } - -}( window, function factory( window, classie, EventEmitter, eventie, getSize, - utils, Cell, animatePrototype ) { - - - -// vars -var jQuery = window.jQuery; -var getComputedStyle = window.getComputedStyle; -var console = window.console; - -function moveElements( elems, toElem ) { - elems = utils.makeArray( elems ); - while ( elems.length ) { - toElem.appendChild( elems.shift() ); - } -} - -// -------------------------- Flickity -------------------------- // - -// globally unique identifiers -var GUID = 0; -// internal store of all Flickity intances -var instances = {}; - -function Flickity( element, options ) { - var queryElement = utils.getQueryElement( element ); - if ( !queryElement ) { - if ( console ) { - console.error( 'Bad element for Flickity: ' + ( queryElement || element ) ); - } - return; - } - this.element = queryElement; - // add jQuery - if ( jQuery ) { - this.$element = jQuery( this.element ); - } - // options - this.options = utils.extend( {}, this.constructor.defaults ); - this.option( options ); - - // kick things off - this._create(); -} - -Flickity.defaults = { - accessibility: true, - cellAlign: 'center', - // cellSelector: undefined, - // contain: false, - freeScrollFriction: 0.075, // friction when free-scrolling - friction: 0.28, // friction when selecting - // initialIndex: 0, - percentPosition: true, - resize: true, - selectedAttraction: 0.025, - setGallerySize: true - // watchCSS: false, - // wrapAround: false -}; - -// hash of methods triggered on _create() -Flickity.createMethods = []; - -// inherit EventEmitter -utils.extend( Flickity.prototype, EventEmitter.prototype ); - -Flickity.prototype._create = function() { - // add id for Flickity.data - var id = this.guid = ++GUID; - this.element.flickityGUID = id; // expando - instances[ id ] = this; // associate via id - // initial properties - this.selectedIndex = this.options.initialIndex || 0; - // how many frames slider has been in same position - this.restingFrames = 0; - // initial physics properties - this.x = 0; - this.velocity = 0; - this.accel = 0; - this.originSide = this.options.rightToLeft ? 'right' : 'left'; - // create viewport & slider - this.viewport = document.createElement('div'); - this.viewport.className = 'flickity-viewport'; - Flickity.setUnselectable( this.viewport ); - this._createSlider(); - - if ( this.options.resize || this.options.watchCSS ) { - eventie.bind( window, 'resize', this ); - this.isResizeBound = true; - } - - for ( var i=0, len = Flickity.createMethods.length; i < len; i++ ) { - var method = Flickity.createMethods[i]; - this[ method ](); - } - - if ( this.options.watchCSS ) { - this.watchCSS(); - } else { - this.activate(); - } - -}; - -/** - * set options - * @param {Object} opts - */ -Flickity.prototype.option = function( opts ) { - utils.extend( this.options, opts ); -}; - -Flickity.prototype.activate = function() { - if ( this.isActive ) { - return; - } - this.isActive = true; - classie.add( this.element, 'flickity-enabled' ); - if ( this.options.rightToLeft ) { - classie.add( this.element, 'flickity-rtl' ); - } - - // move initial cell elements so they can be loaded as cells - var cellElems = this._filterFindCellElements( this.element.children ); - moveElements( cellElems, this.slider ); - this.viewport.appendChild( this.slider ); - this.element.appendChild( this.viewport ); - - this.getSize(); - // get cells from children - this.reloadCells(); - - if ( this.options.accessibility ) { - // allow element to focusable - this.element.tabIndex = 0; - // listen for key presses - eventie.bind( this.element, 'keydown', this ); - } - - this.emit('activate'); - - this.positionSliderAtSelected(); - this.select( this.selectedIndex ); -}; - -// slider positions the cells -Flickity.prototype._createSlider = function() { - // slider element does all the positioning - var slider = document.createElement('div'); - slider.className = 'flickity-slider'; - slider.style[ this.originSide ] = 0; - this.slider = slider; -}; - -Flickity.prototype._filterFindCellElements = function( elems ) { - return utils.filterFindElements( elems, this.options.cellSelector ); -}; - -// goes through all children -Flickity.prototype.reloadCells = function() { - // collection of item elements - this.cells = this._makeCells( this.slider.children ); - this.positionCells(); - this._getWrapShiftCells(); - this.setGallerySize(); -}; - -/** - * turn elements into Flickity.Cells - * @param {Array or NodeList or HTMLElement} elems - * @returns {Array} items - collection of new Flickity Cells - */ -Flickity.prototype._makeCells = function( elems ) { - var cellElems = this._filterFindCellElements( elems ); - - // create new Flickity for collection - var cells = []; - for ( var i=0, len = cellElems.length; i < len; i++ ) { - var elem = cellElems[i]; - var cell = new Cell( elem, this ); - cells.push( cell ); - } - - return cells; -}; - -Flickity.prototype.getLastCell = function() { - return this.cells[ this.cells.length - 1 ]; -}; - -// positions all cells -Flickity.prototype.positionCells = function() { - // size all cells - this._sizeCells( this.cells ); - // position all cells - this._positionCells( 0 ); -}; - -/** - * position certain cells - * @param {Integer} index - which cell to start with - */ -Flickity.prototype._positionCells = function( index ) { - // also measure maxCellHeight - // start 0 if positioning all cells - this.maxCellHeight = index ? this.maxCellHeight || 0 : 0; - var cellX = 0; - // get cellX - if ( index > 0 ) { - var startCell = this.cells[ index - 1 ]; - cellX = startCell.x + startCell.size.outerWidth; - } - var cell; - for ( var len = this.cells.length, i=index; i < len; i++ ) { - cell = this.cells[i]; - cell.setPosition( cellX ); - cellX += cell.size.outerWidth; - this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight ); - } - // keep track of cellX for wrap-around - this.slideableWidth = cellX; - // contain cell target - this._containCells(); -}; - -/** - * cell.getSize() on multiple cells - * @param {Array} cells - */ -Flickity.prototype._sizeCells = function( cells ) { - for ( var i=0, len = cells.length; i < len; i++ ) { - var cell = cells[i]; - cell.getSize(); - } -}; - -// alias _init for jQuery plugin .flickity() -Flickity.prototype._init = -Flickity.prototype.reposition = function() { - this.positionCells(); - this.positionSliderAtSelected(); -}; - -Flickity.prototype.getSize = function() { - this.size = getSize( this.element ); - this.setCellAlign(); - this.cursorPosition = this.size.innerWidth * this.cellAlign; -}; - -var cellAlignShorthands = { - // cell align, then based on origin side - center: { - left: 0.5, - right: 0.5 - }, - left: { - left: 0, - right: 1 - }, - right: { - right: 0, - left: 1 - } -}; - -Flickity.prototype.setCellAlign = function() { - var shorthand = cellAlignShorthands[ this.options.cellAlign ]; - this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign; -}; - -Flickity.prototype.setGallerySize = function() { - if ( this.options.setGallerySize ) { - this.viewport.style.height = this.maxCellHeight + 'px'; - } -}; - -Flickity.prototype._getWrapShiftCells = function() { - // only for wrap-around - if ( !this.options.wrapAround ) { - return; - } - // unshift previous cells - this._unshiftCells( this.beforeShiftCells ); - this._unshiftCells( this.afterShiftCells ); - // get before cells - // initial gap - var gapX = this.cursorPosition; - var cellIndex = this.cells.length - 1; - this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 ); - // get after cells - // ending gap between last cell and end of gallery viewport - gapX = this.size.innerWidth - this.cursorPosition; - // start cloning at first cell, working forwards - this.afterShiftCells = this._getGapCells( gapX, 0, 1 ); -}; - -Flickity.prototype._getGapCells = function( gapX, cellIndex, increment ) { - // keep adding cells until the cover the initial gap - var cells = []; - while ( gapX > 0 ) { - var cell = this.cells[ cellIndex ]; - if ( !cell ) { - break; - } - cells.push( cell ); - cellIndex += increment; - gapX -= cell.size.outerWidth; - } - return cells; -}; - -// ----- contain ----- // - -// contain cell targets so no excess sliding -Flickity.prototype._containCells = function() { - if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) { - return; - } - var startMargin = this.options.rightToLeft ? 'marginRight' : 'marginLeft'; - var endMargin = this.options.rightToLeft ? 'marginLeft' : 'marginRight'; - var firstCellStartMargin = this.cells[0].size[ startMargin ]; - var lastCell = this.getLastCell(); - var contentWidth = this.slideableWidth - lastCell.size[ endMargin ]; - var endLimit = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign ); - // content is less than gallery size - var isContentSmaller = contentWidth < this.size.innerWidth; - // contain each cell target - for ( var i=0, len = this.cells.length; i < len; i++ ) { - var cell = this.cells[i]; - // reset default target - cell.setDefaultTarget(); - if ( isContentSmaller ) { - // all cells fit inside gallery - cell.target = contentWidth * this.cellAlign; - } else { - // contain to bounds - cell.target = Math.max( cell.target, this.cursorPosition + firstCellStartMargin ); - cell.target = Math.min( cell.target, endLimit ); - } - } -}; - -// ----- ----- // - -/** - * emits events via eventEmitter and jQuery events - * @param {String} type - name of event - * @param {Event} event - original event - * @param {Array} args - extra arguments - */ -Flickity.prototype.dispatchEvent = function( type, event, args ) { - var emitArgs = [ event ].concat( args ); - this.emitEvent( type, emitArgs ); - - if ( jQuery && this.$element ) { - if ( event ) { - // create jQuery event - var $event = jQuery.Event( event ); - $event.type = type; - this.$element.trigger( $event, args ); - } else { - // just trigger with type if no event available - this.$element.trigger( type, args ); - } - } -}; - -// -------------------------- select -------------------------- // - -/** - * @param {Integer} index - index of the cell - * @param {Boolean} isWrap - will wrap-around to last/first if at the end - */ -Flickity.prototype.select = function( index, isWrap ) { - if ( !this.isActive ) { - return; - } - // wrap position so slider is within normal area - var len = this.cells.length; - if ( this.options.wrapAround && len > 1 ) { - if ( index < 0 ) { - this.x -= this.slideableWidth; - } else if ( index >= len ) { - this.x += this.slideableWidth; - } - } - - if ( this.options.wrapAround || isWrap ) { - index = utils.modulo( index, len ); - } - - if ( this.cells[ index ] ) { - this.selectedIndex = index; - this.setSelectedCell(); - this.startAnimation(); - this.dispatchEvent('cellSelect'); - } -}; - -Flickity.prototype.previous = function( isWrap ) { - this.select( this.selectedIndex - 1, isWrap ); -}; - -Flickity.prototype.next = function( isWrap ) { - this.select( this.selectedIndex + 1, isWrap ); -}; - -Flickity.prototype.setSelectedCell = function() { - this._removeSelectedCellClass(); - this.selectedCell = this.cells[ this.selectedIndex ]; - this.selectedElement = this.selectedCell.element; - classie.add( this.selectedElement, 'is-selected' ); -}; - -Flickity.prototype._removeSelectedCellClass = function() { - if ( this.selectedCell ) { - classie.remove( this.selectedCell.element, 'is-selected' ); - } -}; - -// -------------------------- get cells -------------------------- // - -/** - * get Flickity.Cell, given an Element - * @param {Element} elem - * @returns {Flickity.Cell} item - */ -Flickity.prototype.getCell = function( elem ) { - // loop through cells to get the one that matches - for ( var i=0, len = this.cells.length; i < len; i++ ) { - var cell = this.cells[i]; - if ( cell.element == elem ) { - return cell; - } - } -}; - -/** - * get collection of Flickity.Cells, given Elements - * @param {Element, Array, NodeList} elems - * @returns {Array} cells - Flickity.Cells - */ -Flickity.prototype.getCells = function( elems ) { - elems = utils.makeArray( elems ); - var cells = []; - for ( var i=0, len = elems.length; i < len; i++ ) { - var elem = elems[i]; - var cell = this.getCell( elem ); - if ( cell ) { - cells.push( cell ); - } - } - return cells; -}; - -/** - * get cell elements - * @returns {Array} cellElems - */ -Flickity.prototype.getCellElements = function() { - var cellElems = []; - for ( var i=0, len = this.cells.length; i < len; i++ ) { - cellElems.push( this.cells[i].element ); - } - return cellElems; -}; - -/** - * get parent cell from an element - * @param {Element} elem - * @returns {Flickit.Cell} cell - */ -Flickity.prototype.getParentCell = function( elem ) { - // first check if elem is cell - var cell = this.getCell( elem ); - if ( cell ) { - return cell; - } - // try to get parent cell elem - elem = utils.getParent( elem, '.flickity-slider > *' ); - return this.getCell( elem ); -}; - -// -------------------------- events -------------------------- // - -Flickity.prototype.uiChange = function() { - this.emit('uiChange'); -}; - -Flickity.prototype.childUIPointerDown = function( event ) { - this.emitEvent( 'childUIPointerDown', [ event ] ); -}; - -// ----- resize ----- // - -Flickity.prototype.onresize = function() { - this.watchCSS(); - this.resize(); -}; - -utils.debounceMethod( Flickity, 'onresize', 150 ); - -Flickity.prototype.resize = function() { - if ( !this.isActive ) { - return; - } - this.getSize(); - // wrap values - if ( this.options.wrapAround ) { - this.x = utils.modulo( this.x, this.slideableWidth ); - } - this.positionCells(); - this._getWrapShiftCells(); - this.setGallerySize(); - this.positionSliderAtSelected(); -}; - -var supportsConditionalCSS = Flickity.supportsConditionalCSS = ( function() { - var supports; - return function checkSupport() { - if ( supports !== undefined ) { - return supports; - } - if ( !getComputedStyle ) { - supports = false; - return; - } - // style body's :after and check that - var style = document.createElement('style'); - var cssText = document.createTextNode('body:after { content: "foo"; display: none; }'); - style.appendChild( cssText ); - document.head.appendChild( style ); - var afterContent = getComputedStyle( document.body, ':after' ).content; - // check if able to get :after content - supports = afterContent.indexOf('foo') != -1; - document.head.removeChild( style ); - return supports; - }; -})(); - -// watches the :after property, activates/deactivates -Flickity.prototype.watchCSS = function() { - var watchOption = this.options.watchCSS; - if ( !watchOption ) { - return; - } - var supports = supportsConditionalCSS(); - if ( !supports ) { - // activate if watch option is fallbackOn - var method = watchOption == 'fallbackOn' ? 'activate' : 'deactivate'; - this[ method ](); - return; - } - - var afterContent = getComputedStyle( this.element, ':after' ).content; - // activate if :after { content: 'flickity' } - if ( afterContent.indexOf('flickity') != -1 ) { - this.activate(); - } else { - this.deactivate(); - } -}; - -// ----- keydown ----- // - -// go previous/next if left/right keys pressed -Flickity.prototype.onkeydown = function( event ) { - // only work if element is in focus - if ( !this.options.accessibility || - ( document.activeElement && document.activeElement != this.element ) ) { - return; - } - - if ( event.keyCode == 37 ) { - // go left - var leftMethod = this.options.rightToLeft ? 'next' : 'previous'; - this.uiChange(); - this[ leftMethod ](); - } else if ( event.keyCode == 39 ) { - // go right - var rightMethod = this.options.rightToLeft ? 'previous' : 'next'; - this.uiChange(); - this[ rightMethod ](); - } -}; - -// -------------------------- destroy -------------------------- // - -// deactivate all Flickity functionality, but keep stuff available -Flickity.prototype.deactivate = function() { - if ( !this.isActive ) { - return; - } - classie.remove( this.element, 'flickity-enabled' ); - classie.remove( this.element, 'flickity-rtl' ); - // destroy cells - for ( var i=0, len = this.cells.length; i < len; i++ ) { - var cell = this.cells[i]; - cell.destroy(); - } - this._removeSelectedCellClass(); - this.element.removeChild( this.viewport ); - // move child elements back into element - moveElements( this.slider.children, this.element ); - if ( this.options.accessibility ) { - this.element.removeAttribute('tabIndex'); - eventie.unbind( this.element, 'keydown', this ); - } - // set flags - this.isActive = false; - this.emit('deactivate'); -}; - -Flickity.prototype.destroy = function() { - this.deactivate(); - if ( this.isResizeBound ) { - eventie.unbind( window, 'resize', this ); - } - this.emit('destroy'); - if ( jQuery && this.$element ) { - jQuery.removeData( this.element, 'flickity' ); - } - delete this.element.flickityGUID; - delete instances[ this.guid ]; -}; - -// -------------------------- prototype -------------------------- // - -utils.extend( Flickity.prototype, animatePrototype ); - -// -------------------------- extras -------------------------- // - -// quick check for IE8 -var isIE8 = 'attachEvent' in window; - -Flickity.setUnselectable = function( elem ) { - if ( !isIE8 ) { - return; - } - // IE8 prevent child from changing focus http://stackoverflow.com/a/17525223/182183 - elem.setAttribute( 'unselectable', 'on' ); -}; - -/** - * get Flickity instance from element - * @param {Element} elem - * @returns {Flickity} - */ -Flickity.data = function( elem ) { - elem = utils.getQueryElement( elem ); - var id = elem && elem.flickityGUID; - return id && instances[ id ]; -}; - -utils.htmlInit( Flickity, 'flickity' ); - -if ( jQuery && jQuery.bridget ) { - jQuery.bridget( 'flickity', Flickity ); -} - -Flickity.Cell = Cell; - -return Flickity; - -})); - -/*! - * Unipointer v1.1.0 - * base class for doing one thing with pointer event - * MIT license - */ - -/*jshint browser: true, undef: true, unused: true, strict: true */ -/*global define: false, module: false, require: false */ - -( function( window, factory ) { - - // universal module definition - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( 'unipointer/unipointer',[ - 'eventEmitter/EventEmitter', - 'eventie/eventie' - ], function( EventEmitter, eventie ) { - return factory( window, EventEmitter, eventie ); - }); - } else if ( typeof exports == 'object' ) { - // CommonJS - module.exports = factory( - window, - require('wolfy87-eventemitter'), - require('eventie') - ); - } else { - // browser global - window.Unipointer = factory( - window, - window.EventEmitter, - window.eventie - ); - } - -}( window, function factory( window, EventEmitter, eventie ) { - - - -function noop() {} - -function Unipointer() {} - -// inherit EventEmitter -Unipointer.prototype = new EventEmitter(); - -Unipointer.prototype.bindStartEvent = function( elem ) { - this._bindStartEvent( elem, true ); -}; - -Unipointer.prototype.unbindStartEvent = function( elem ) { - this._bindStartEvent( elem, false ); -}; - -/** - * works as unbinder, as you can ._bindStart( false ) to unbind - * @param {Boolean} isBind - will unbind if falsey - */ -Unipointer.prototype._bindStartEvent = function( elem, isBind ) { - // munge isBind, default to true - isBind = isBind === undefined ? true : !!isBind; - var bindMethod = isBind ? 'bind' : 'unbind'; - - if ( window.navigator.pointerEnabled ) { - // W3C Pointer Events, IE11. See https://coderwall.com/p/mfreca - eventie[ bindMethod ]( elem, 'pointerdown', this ); - } else if ( window.navigator.msPointerEnabled ) { - // IE10 Pointer Events - eventie[ bindMethod ]( elem, 'MSPointerDown', this ); - } else { - // listen for both, for devices like Chrome Pixel - eventie[ bindMethod ]( elem, 'mousedown', this ); - eventie[ bindMethod ]( elem, 'touchstart', this ); - } -}; - -// trigger handler methods for events -Unipointer.prototype.handleEvent = function( event ) { - var method = 'on' + event.type; - if ( this[ method ] ) { - this[ method ]( event ); - } -}; - -// returns the touch that we're keeping track of -Unipointer.prototype.getTouch = function( touches ) { - for ( var i=0, len = touches.length; i < len; i++ ) { - var touch = touches[i]; - if ( touch.identifier == this.pointerIdentifier ) { - return touch; - } - } -}; - -// ----- start event ----- // - -Unipointer.prototype.onmousedown = function( event ) { - // dismiss clicks from right or middle buttons - var button = event.button; - if ( button && ( button !== 0 && button !== 1 ) ) { - return; - } - this._pointerDown( event, event ); -}; - -Unipointer.prototype.ontouchstart = function( event ) { - this._pointerDown( event, event.changedTouches[0] ); -}; - -Unipointer.prototype.onMSPointerDown = -Unipointer.prototype.onpointerdown = function( event ) { - this._pointerDown( event, event ); -}; - -/** - * pointer start - * @param {Event} event - * @param {Event or Touch} pointer - */ -Unipointer.prototype._pointerDown = function( event, pointer ) { - // dismiss other pointers - if ( this.isPointerDown ) { - return; - } - - this.isPointerDown = true; - // save pointer identifier to match up touch events - this.pointerIdentifier = pointer.pointerId !== undefined ? - // pointerId for pointer events, touch.indentifier for touch events - pointer.pointerId : pointer.identifier; - - this.pointerDown( event, pointer ); -}; - -Unipointer.prototype.pointerDown = function( event, pointer ) { - this._bindPostStartEvents( event ); - this.emitEvent( 'pointerDown', [ event, pointer ] ); -}; - -// hash of events to be bound after start event -var postStartEvents = { - mousedown: [ 'mousemove', 'mouseup' ], - touchstart: [ 'touchmove', 'touchend', 'touchcancel' ], - pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ], - MSPointerDown: [ 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel' ] -}; - -Unipointer.prototype._bindPostStartEvents = function( event ) { - if ( !event ) { - return; - } - // get proper events to match start event - var events = postStartEvents[ event.type ]; - // IE8 needs to be bound to document - var node = event.preventDefault ? window : document; - // bind events to node - for ( var i=0, len = events.length; i < len; i++ ) { - var evnt = events[i]; - eventie.bind( node, evnt, this ); - } - // save these arguments - this._boundPointerEvents = { - events: events, - node: node - }; -}; - -Unipointer.prototype._unbindPostStartEvents = function() { - var args = this._boundPointerEvents; - // IE8 can trigger dragEnd twice, check for _boundEvents - if ( !args || !args.events ) { - return; - } - - for ( var i=0, len = args.events.length; i < len; i++ ) { - var event = args.events[i]; - eventie.unbind( args.node, event, this ); - } - delete this._boundPointerEvents; -}; - -// ----- move event ----- // - -Unipointer.prototype.onmousemove = function( event ) { - this._pointerMove( event, event ); -}; - -Unipointer.prototype.onMSPointerMove = -Unipointer.prototype.onpointermove = function( event ) { - if ( event.pointerId == this.pointerIdentifier ) { - this._pointerMove( event, event ); - } -}; - -Unipointer.prototype.ontouchmove = function( event ) { - var touch = this.getTouch( event.changedTouches ); - if ( touch ) { - this._pointerMove( event, touch ); - } -}; - -/** - * pointer move - * @param {Event} event - * @param {Event or Touch} pointer - * @private - */ -Unipointer.prototype._pointerMove = function( event, pointer ) { - this.pointerMove( event, pointer ); -}; - -// public -Unipointer.prototype.pointerMove = function( event, pointer ) { - this.emitEvent( 'pointerMove', [ event, pointer ] ); -}; - -// ----- end event ----- // - - -Unipointer.prototype.onmouseup = function( event ) { - this._pointerUp( event, event ); -}; - -Unipointer.prototype.onMSPointerUp = -Unipointer.prototype.onpointerup = function( event ) { - if ( event.pointerId == this.pointerIdentifier ) { - this._pointerUp( event, event ); - } -}; - -Unipointer.prototype.ontouchend = function( event ) { - var touch = this.getTouch( event.changedTouches ); - if ( touch ) { - this._pointerUp( event, touch ); - } -}; - -/** - * pointer up - * @param {Event} event - * @param {Event or Touch} pointer - * @private - */ -Unipointer.prototype._pointerUp = function( event, pointer ) { - this._pointerDone(); - this.pointerUp( event, pointer ); -}; - -// public -Unipointer.prototype.pointerUp = function( event, pointer ) { - this.emitEvent( 'pointerUp', [ event, pointer ] ); -}; - -// ----- pointer done ----- // - -// triggered on pointer up & pointer cancel -Unipointer.prototype._pointerDone = function() { - // reset properties - this.isPointerDown = false; - delete this.pointerIdentifier; - // remove events - this._unbindPostStartEvents(); - this.pointerDone(); -}; - -Unipointer.prototype.pointerDone = noop; - -// ----- pointer cancel ----- // - -Unipointer.prototype.onMSPointerCancel = -Unipointer.prototype.onpointercancel = function( event ) { - if ( event.pointerId == this.pointerIdentifier ) { - this._pointerCancel( event, event ); - } -}; - -Unipointer.prototype.ontouchcancel = function( event ) { - var touch = this.getTouch( event.changedTouches ); - if ( touch ) { - this._pointerCancel( event, touch ); - } -}; - -/** - * pointer cancel - * @param {Event} event - * @param {Event or Touch} pointer - * @private - */ -Unipointer.prototype._pointerCancel = function( event, pointer ) { - this._pointerDone(); - this.pointerCancel( event, pointer ); -}; - -// public -Unipointer.prototype.pointerCancel = function( event, pointer ) { - this.emitEvent( 'pointerCancel', [ event, pointer ] ); -}; - -// ----- ----- // - -// utility function for getting x/y cooridinates from event, because IE8 -Unipointer.getPointerPoint = function( pointer ) { - return { - x: pointer.pageX !== undefined ? pointer.pageX : pointer.clientX, - y: pointer.pageY !== undefined ? pointer.pageY : pointer.clientY - }; -}; - -// ----- ----- // - -return Unipointer; - -})); - -/*! - * Unidragger v1.1.3 - * Draggable base class - * MIT license - */ - -/*jshint browser: true, unused: true, undef: true, strict: true */ - -( function( window, factory ) { - /*global define: false, module: false, require: false */ - - // universal module definition - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( 'unidragger/unidragger',[ - 'eventie/eventie', - 'unipointer/unipointer' - ], function( eventie, Unipointer ) { - return factory( window, eventie, Unipointer ); - }); - } else if ( typeof exports == 'object' ) { - // CommonJS - module.exports = factory( - window, - require('eventie'), - require('unipointer') - ); - } else { - // browser global - window.Unidragger = factory( - window, - window.eventie, - window.Unipointer - ); - } - -}( window, function factory( window, eventie, Unipointer ) { - - - -// ----- ----- // - -function noop() {} - -// handle IE8 prevent default -function preventDefaultEvent( event ) { - if ( event.preventDefault ) { - event.preventDefault(); - } else { - event.returnValue = false; - } -} - -// -------------------------- Unidragger -------------------------- // - -function Unidragger() {} - -// inherit Unipointer & EventEmitter -Unidragger.prototype = new Unipointer(); - -// ----- bind start ----- // - -Unidragger.prototype.bindHandles = function() { - this._bindHandles( true ); -}; - -Unidragger.prototype.unbindHandles = function() { - this._bindHandles( false ); -}; - -var navigator = window.navigator; -/** - * works as unbinder, as you can .bindHandles( false ) to unbind - * @param {Boolean} isBind - will unbind if falsey - */ -Unidragger.prototype._bindHandles = function( isBind ) { - // munge isBind, default to true - isBind = isBind === undefined ? true : !!isBind; - // extra bind logic - var binderExtra; - if ( navigator.pointerEnabled ) { - binderExtra = function( handle ) { - // disable scrolling on the element - handle.style.touchAction = isBind ? 'none' : ''; - }; - } else if ( navigator.msPointerEnabled ) { - binderExtra = function( handle ) { - // disable scrolling on the element - handle.style.msTouchAction = isBind ? 'none' : ''; - }; - } else { - binderExtra = function() { - // TODO re-enable img.ondragstart when unbinding - if ( isBind ) { - disableImgOndragstart( handle ); - } - }; - } - // bind each handle - var bindMethod = isBind ? 'bind' : 'unbind'; - for ( var i=0, len = this.handles.length; i < len; i++ ) { - var handle = this.handles[i]; - this._bindStartEvent( handle, isBind ); - binderExtra( handle ); - eventie[ bindMethod ]( handle, 'click', this ); - } -}; - -// remove default dragging interaction on all images in IE8 -// IE8 does its own drag thing on images, which messes stuff up - -function noDragStart() { - return false; -} - -// TODO replace this with a IE8 test -var isIE8 = 'attachEvent' in document.documentElement; - -// IE8 only -var disableImgOndragstart = !isIE8 ? noop : function( handle ) { - - if ( handle.nodeName == 'IMG' ) { - handle.ondragstart = noDragStart; - } - - var images = handle.querySelectorAll('img'); - for ( var i=0, len = images.length; i < len; i++ ) { - var img = images[i]; - img.ondragstart = noDragStart; - } -}; - -// ----- start event ----- // - -/** - * pointer start - * @param {Event} event - * @param {Event or Touch} pointer - */ -Unidragger.prototype.pointerDown = function( event, pointer ) { - this._dragPointerDown( event, pointer ); - // kludge to blur focused inputs in dragger - var focused = document.activeElement; - if ( focused && focused.blur ) { - focused.blur(); - } - // bind move and end events - this._bindPostStartEvents( event ); - this.emitEvent( 'pointerDown', [ event, pointer ] ); -}; - -// base pointer down logic -Unidragger.prototype._dragPointerDown = function( event, pointer ) { - // track to see when dragging starts - this.pointerDownPoint = Unipointer.getPointerPoint( pointer ); - - // prevent default, unless touchstart or s and ",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("