Full Code of rubymotion/BubbleWrap for AI

master afdc89e7f49e cached
186 files
553.1 KB
153.9k tokens
690 symbols
1 requests
Download .txt
Showing preview only (601K chars total). Download the full file or copy to clipboard to get everything.
Repository: rubymotion/BubbleWrap
Branch: master
Commit: afdc89e7f49e
Files: 186
Total size: 553.1 KB

Directory structure:
gitextract_83mw8g5j/

├── .gitignore
├── .travis.yml
├── .yardopts
├── CHANGELOG.md
├── GEM.md
├── GETTING_STARTED.md
├── Gemfile
├── HACKING.md
├── LICENSE
├── README.md
├── Rakefile
├── bubble-wrap.gemspec
├── lib/
│   ├── bubble-wrap/
│   │   ├── all.rb
│   │   ├── camera.rb
│   │   ├── core.rb
│   │   ├── ext/
│   │   │   └── motion_project_app.rb
│   │   ├── ext.rb
│   │   ├── font.rb
│   │   ├── loader.rb
│   │   ├── location.rb
│   │   ├── mail.rb
│   │   ├── media.rb
│   │   ├── motion.rb
│   │   ├── network-indicator.rb
│   │   ├── reactor.rb
│   │   ├── requirement/
│   │   │   └── path_manipulation.rb
│   │   ├── requirement.rb
│   │   ├── rss_parser.rb
│   │   ├── sms.rb
│   │   ├── test.rb
│   │   ├── ui.rb
│   │   └── version.rb
│   └── bubble-wrap.rb
├── motion/
│   ├── core/
│   │   ├── app.rb
│   │   ├── device/
│   │   │   ├── ios/
│   │   │   │   ├── camera.rb
│   │   │   │   ├── camera_wrapper.rb
│   │   │   │   └── screen.rb
│   │   │   ├── osx/
│   │   │   │   └── screen.rb
│   │   │   └── screen.rb
│   │   ├── device.rb
│   │   ├── ios/
│   │   │   ├── app.rb
│   │   │   ├── device.rb
│   │   │   └── ns_index_path.rb
│   │   ├── json.rb
│   │   ├── kvo.rb
│   │   ├── ns_index_path.rb
│   │   ├── ns_notification_center.rb
│   │   ├── ns_url_request.rb
│   │   ├── ns_user_defaults.rb
│   │   ├── osx/
│   │   │   ├── app.rb
│   │   │   └── device.rb
│   │   ├── persistence.rb
│   │   ├── pollute.rb
│   │   ├── string.rb
│   │   └── time.rb
│   ├── core.rb
│   ├── font/
│   │   └── font.rb
│   ├── ios/
│   │   └── 8/
│   │       └── location_constants.rb
│   ├── location/
│   │   ├── location.rb
│   │   └── pollute.rb
│   ├── mail/
│   │   ├── mail.rb
│   │   └── result.rb
│   ├── media/
│   │   ├── media.rb
│   │   └── player.rb
│   ├── motion/
│   │   ├── accelerometer.rb
│   │   ├── device_motion.rb
│   │   ├── gyroscope.rb
│   │   ├── magnetometer.rb
│   │   └── motion.rb
│   ├── network-indicator/
│   │   └── network-indicator.rb
│   ├── reactor/
│   │   ├── default_deferrable.rb
│   │   ├── deferrable.rb
│   │   ├── dependent_deferrable.rb
│   │   ├── eventable.rb
│   │   ├── future.rb
│   │   ├── periodic_timer.rb
│   │   ├── queue.rb
│   │   ├── thread_aware_deferrable.rb
│   │   └── timer.rb
│   ├── reactor.rb
│   ├── rss_parser.rb
│   ├── shortcut.rb
│   ├── sms/
│   │   ├── result.rb
│   │   └── sms.rb
│   ├── test_suite_delegate.rb
│   ├── ui/
│   │   ├── pollute.rb
│   │   ├── ui_activity_view_controller_wrapper.rb
│   │   ├── ui_alert_view.rb
│   │   ├── ui_bar_button_item.rb
│   │   ├── ui_control_wrapper.rb
│   │   ├── ui_view_controller_wrapper.rb
│   │   └── ui_view_wrapper.rb
│   └── util/
│       ├── constants.rb
│       └── deprecated.rb
├── resources/
│   ├── Localizable.strings
│   └── atom.xml
├── samples/
│   ├── alert/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   └── controllers/
│   │   │       └── alert_view_controller.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── camera/
│   │   ├── Gemfile
│   │   ├── README.md
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   └── controllers/
│   │   │       └── camera_controller.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── gesture/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── README.md
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   ├── controllers/
│   │   │   │   └── drawing_view_controller.rb
│   │   │   ├── helpers/
│   │   │   │   └── drawing_helper.rb
│   │   │   └── views/
│   │   │       └── drawing/
│   │   │           ├── gesture_view.rb
│   │   │           └── rect_view.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── location/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── README.md
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   ├── controllers/
│   │   │   │   └── places_list_controller.rb
│   │   │   └── models/
│   │   │       └── places.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── media/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   └── controllers/
│   │   │       └── play_controller.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   └── osx/
│       ├── Gemfile
│       ├── Rakefile
│       ├── app/
│       │   ├── app_delegate.rb
│       │   └── menu.rb
│       ├── resources/
│       │   └── Credits.rtf
│       └── spec/
│           └── main_spec.rb
└── spec/
    ├── lib/
    │   ├── bubble-wrap/
    │   │   ├── ext/
    │   │   │   ├── motion_project_app_spec.rb
    │   │   │   └── motion_project_config_spec.rb
    │   │   ├── requirement/
    │   │   │   └── path_manipulation_spec.rb
    │   │   └── requirement_spec.rb
    │   ├── bubble-wrap_spec.rb
    │   └── motion_stub.rb
    └── motion/
        ├── core/
        │   ├── app_spec.rb
        │   ├── device/
        │   │   ├── ios/
        │   │   │   ├── camera_spec.rb
        │   │   │   ├── camera_wrapper_spec.rb
        │   │   │   ├── device_spec.rb
        │   │   │   └── screen_spec.rb
        │   │   └── osx/
        │   │       └── screen_spec.rb
        │   ├── device_spec.rb
        │   ├── ios/
        │   │   ├── app_spec.rb
        │   │   └── ns_index_path_spec.rb
        │   ├── json_spec.rb
        │   ├── kvo_spec.rb
        │   ├── ns_index_path_spec.rb
        │   ├── ns_notification_center_spec.rb
        │   ├── osx/
        │   │   └── app_spec.rb
        │   ├── persistence_spec.rb
        │   ├── string_spec.rb
        │   └── time_spec.rb
        ├── core_spec.rb
        ├── font/
        │   └── font_spec.rb
        ├── location/
        │   └── location_spec.rb
        ├── mail/
        │   ├── mail_spec.rb
        │   └── result_spec.rb
        ├── media/
        │   └── player_spec.rb
        ├── motion/
        │   └── core_motion_spec.rb
        ├── network-indicator/
        │   └── network_indicator_spec.rb
        ├── reactor/
        │   ├── deferrable_spec.rb
        │   ├── dependent_deferrable_spec.rb
        │   ├── eventable_spec.rb
        │   └── thread_aware_deferrable_spec.rb
        ├── reactor_spec.rb
        ├── rss_parser_spec.rb
        ├── sms/
        │   ├── result_spec.rb
        │   └── sms_spec.rb
        ├── ui/
        │   ├── pollute_spec.rb
        │   ├── ui_activity_view_controller_wrapper_spec.rb
        │   ├── ui_alert_view_spec.rb
        │   ├── ui_bar_button_item_spec.rb
        │   ├── ui_control_wrapper_spec.rb
        │   ├── ui_view_controller_wrapper_spec.rb
        │   └── ui_view_wrapper_spec.rb
        └── util/
            ├── constants_spec.rb
            └── deprecated_spec.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.rake_tasks~
pkg/*
build/
.DS_Store
.repl_history


================================================
FILE: .travis.yml
================================================
language: objective-c
osx_image: xcode8
before_install:
  - sudo motion update
  - motion repo
script:
  - bundle exec rake clean
  - bundle exec rake spec
  - bundle exec rake clean
  - bundle exec rake spec target=10
  - bundle exec rake clean
  - bundle exec rake spec osx=true


================================================
FILE: .yardopts
================================================
lib/**/*.rb
motion/**/*.rb

================================================
FILE: CHANGELOG.md
================================================
## Unreleased

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.7...master)

## 1.9.7

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.6...v1.9.7)

* [iOS] Fix iOS 11 photo library crash ([#493](https://github.com/rubymotion-community/BubbleWrap/pull/493))
* [iOS] Updated Device.simulator? to work in iOS 13+ ([#499](https://github.com/rubymotion-community/BubbleWrap/pull/499))
* [iOS] Add MobileCoreServices to list of required frameworks. Fixes issue with missing KUTTypeMovie constant.

## 1.9.6

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.5...v1.9.6)

* [iOS] Add Device.force_touch? ([#478](https://github.com/rubymotion-community/BubbleWrap/pull/478))
* [iOS] Fixes for iOS 10 ([#489](https://github.com/rubymotion-community/BubbleWrap/pull/489))

## 1.9.5

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.4...v1.9.5)

* Fixed 'simulator?' so it returns the correct value, when running ios 8 or below on device. ([#481](https://github.com/rubymotion-community/BubbleWrap/pull/481))

## ~~1.9.3~~ 1.9.4

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.2...v1.9.4)

* Fixed `Device.simulator?` for iOS 9. ([#473](https://github.com/rubymotion-community/BubbleWrap/pull/473))

## 1.9.2

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.1...v1.9.2)

* Added `DependentDeferrable`. ([#469](https://github.com/rubymotion-community/BubbleWrap/pull/469))

## 1.9.1

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.0...v1.9.1)

* Fix issue in loading iOS 8 constants for CoreLocation

## 1.9.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.8.0...v1.9.0)

* Add support for `keyboardType` on first input field of `BW::UIAlertView` ([#406](https://github.com/rubymotion-community/BubbleWrap/pull/406))
* Implement #+ and #- for NSIndexPath to incr/decr row ([#420](https://github.com/rubymotion-community/BubbleWrap/pull/420))
* Extract CoreMotion classes to make it easier to use and more maintainable ([#454](https://github.com/rubymotion-community/BubbleWrap/pull/454))
* Motion extract classes ([#454](https://github.com/rubymotion-community/BubbleWrap/pull/454))
* Added RSS fields: creator, category, encoded  ([#461](https://github.com/rubymotion-community/BubbleWrap/pull/461))
* KVO `observe!` and ability to pass multiple key paths to `observe` ([#460](https://github.com/rubymotion-community/BubbleWrap/pull/460))
* `App.short_version` ([#466](https://github.com/rubymotion-community/BubbleWrap/pull/466))
* Bump the required version of iOS to >= 7 ([#424](https://github.com/rubymotion-community/BubbleWrap/pull/424))
* Bump the required version of iOS to >= 7 ([#424](https://github.com/rubymotion-community/BubbleWrap/pull/424))
* Fixes to CoreLocation ([#422](https://github.com/rubymotion-community/BubbleWrap/pull/422)) & ([#432](https://github.com/rubymotion-community/BubbleWrap/pull/432))
* Adds default text option to BW::UIAlertView ([#467](https://github.com/rubymotion-community/BubbleWrap/pull/467))
* Bump the minimum required RubyMotion version to `3.12`.

## ... nothing to see here... move along.

## 1.4.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.3.0...v1.4.0)

* Added `BW::Mail` for sending emails ([#247](https://github.com/rubymotion-community/BubbleWrap/pull/247))
* Added `BW::SMS` for sending SMS/iMessages ([#287](https://github.com/rubymotion-community/BubbleWrap/pull/287))
* Added `App::Persistence.delete` ([#286](https://github.com/rubymotion-community/BubbleWrap/pull/286))
* Added `BW::HTTP::Response#error`, which is an `NSError` instance ([#284](https://github.com/rubymotion-community/BubbleWrap/pull/284))
* Added `BW::HTTP::Query#cancel` to chancel URL requests ([#278](https://github.com/rubymotion-community/BubbleWrap/pull/278))
* Added `App.info_plist` ([#273](https://github.com/rubymotion-community/BubbleWrap/pull/273/))
* Added `BW::Device.interface_orientation` ([#265](https://github.com/rubymotion-community/BubbleWrap/pull/265))
* Added `OPTIONS` request method to `BW::HTTP` ([#260](https://github.com/rubymotion-community/BubbleWrap/pull/260))
* Added `Time.iso8601_with_timezone` ([#255](https://github.com/rubymotion-community/BubbleWrap/pull/255))
* Added `:encoding` option to `BW::HTTP` ([#251](https://github.com/rubymotion-community/BubbleWrap/pull/251))
* Moved `BW::Reactor::Timer` and `BW::Reactor::PeriodicTimer` from `NSTimer` to GCD `Dispatch::Source.timer` ([#242](https://github.com/rubymotion-community/BubbleWrap/pull/242))
	* Option `:common_modes` for BW::Reactor::PeriodicTimer has been deprecated, it's not needed anymore.
* Fixed App#window (and thus `BW::Camera`) to work with iOS7 modals ([#305](https://github.com/rubymotion-community/BubbleWrap/pull/305))
* Fixed patches on `String` to be on `NSString` ([#292](https://github.com/rubymotion-community/BubbleWrap/pull/292))
* Fixed `BW::HTTP` success heuristic to match RFC 2616 ([#282](https://github.com/rubymotion-community/BubbleWrap/pull/282))
* Fixed `BW::HTTP` to correctly identify `false` parameters ([#261](https://github.com/rubymotion-community/BubbleWrap/issues/261) [#262](https://github.com/rubymotion-community/BubbleWrap/pull/262))
* Fixed `BW::Reactor` to correctly handle unregistered procs ([#253](https://github.com/rubymotion-community/BubbleWrap/pull/253))
* Fixed `BW::localized_string` to mirror Cocoa API by returning the `key` if no localization exists ([#181](https://github.com/rubymotion-community/BubbleWrap/pull/181))
* Addressed a few memory related problems ([#270](https://github.com/rubymotion-community/BubbleWrap/pull/270) [#275](https://github.com/rubymotion-community/BubbleWrap/pull/275) [#276](https://github.com/rubymotion-community/BubbleWrap/pull/276))

## 1.3.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.2.0...v1.3.0)

* Added OS X support for RubyMotion 2.0 ([#233](https://github.com/rubymotion-community/BubbleWrap/pull/233)). BubbleWrap *drops support* for RubyMotion 1.x.
* Changed `BW::UIBarButtonItem` internals; `.build` is now deprecated and forwards to `.new` ([#226](https://github.com/rubymotion-community/BubbleWrap/pull/226))
* Changed `HTTP` to present credentials with an `Authorization` header *before* any requests are made, unless the `:present_credentials` option `== false` ([#199](https://github.com/rubymotion-community/BubbleWrap/pull/199))
* Fixed `HTTP` to not append a question-mark (`?`) at the end of URL requests with empty `:payload`s ([#221](https://github.com/rubymotion-community/BubbleWrap/pull/221))
* Fixed `HTTP` to correctly parameterize an array of hashes, Rails-style ([#219](https://github.com/rubymotion-community/BubbleWrap/pull/219))

## 1.2.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.5...v1.2.0)

* Added `BW::UIBarButtonItem`, a factory-esque wrapper for `UIBarButtonItem` ([#202](https://github.com/rubymotion-community/BubbleWrap/pull/202))
* Added `BW::Font`, a wrapper for creating `UIFont` objects ([#206](https://github.com/rubymotion-community/BubbleWrap/pull/206))
* Added `BW::Reactor::Eventable#off`, to remove `BW::Reactor` callbacks ([#205](https://github.com/rubymotion-community/BubbleWrap/pull/205))
* Added `BW::Constants.get`, which is a class to help wrapper creation ([#203](https://github.com/rubymotion-community/BubbleWrap/pull/203))
* Added `BW::Location.get_once` to grab only one location ([#197](https://github.com/rubymotion-community/BubbleWrap/pull/197))
* Added `App#environment`, to detect the current RubyMotion environment ([#191](https://github.com/rubymotion-community/BubbleWrap/pull/191))
* Added `:follow_urls` option to `BW::HTTP` ([#192](https://github.com/rubymotion-community/BubbleWrap/pull/192))
* Added `:common_modes` option to `BW::Reactor`to change the runloop mode (#190)
* Added `:no_redirect` option to `BW::HTTP` ([#187](https://github.com/rubymotion-community/BubbleWrap/pull/187))
* Added `:cookies` option to `BW::HTTP` ([#204](https://github.com/rubymotion-community/BubbleWrap/pull/204))

## 1.1.5

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.4...v1.1.5)

* Fix `BW::Camera` view-controller selection process to pickup a window's `presentedViewController` ([#183](https://github.com/rubymotion-community/BubbleWrap/pull/183))
* Fix strings parsed in `BW::JSON` to be mutable ([#175](https://github.com/rubymotion-community/BubbleWrap/pull/175))
* Add option for `:credential_persistence`/`NSURLCredentialPersistence` in `BW::HTTP` ([#166](https://github.com/rubymotion-community/BubbleWrap/pull/166))
* Change `Device.wide_screen?` to `Device.long_screen?` ([#159](https://github.com/rubymotion-community/BubbleWrap/pull/159))
* String escaping fixes to `BW::HTTP` ([#160](https://github.com/rubymotion-community/BubbleWrap/pull/160) [#161](https://github.com/rubymotion-community/BubbleWrap/pull/161) [#162](https://github.com/rubymotion-community/BubbleWrap/pull/162))
* Add `Device.sdk_version`

## 1.1.4

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.3...v1.1.4)

* Support RubyMotion 1.24 or above (https://github.com/rubymotion-community/BubbleWrap/pull/143)
* Fixed a problem with `when` events not properly handling multiple targets per event. Now defaults to one target per event with an option to append multiple targets.

## 1.1.3

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.2...v1.1.3)


## 1.1.2

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.1...v1.1.2)

* Fixed a problem with the load path.
* Added `format:` to the HTTP wrapper with [5 supported formats supported](https://github.com/rubymotion-community/BubbleWrap/pull/109) that sets the content type accordingly.
* Default HTTP Content-Type for `POST` like requests is back to being
  form url encoded.

## 1.1.1

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.1.0...v1.1.1)

### Enhancements

* Added support for symbols as selectors to the KVO module.
* Improved the RSSParser by providing a delegate to handle errors.

### Bug Fixes

* Fixed a bug with the way JSON payloads were handled in the HTTP
  wrapper.
* Fixed a bug with the way the headers and content types were handled in
  the HTTP wrapper.

## 1.1.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.0.0...v1.1.0)

* Added `BubbleWrap::Reactor`,  a simplified implementation of the Event Machine API on top of GCD.
* Added upload support to the HTTP wrapper.
* Added `BubbleWrap.create_uuid` to generate a uuid string.
* Added a program progress proc option to the HTTP wrapper.
* Added a RSS parser.
* Added a camera wrapper.
* Split the various wrappers in self contained and requirable libraries.
* Added a wrapper around the location/gps APIs.
* Added a merge method to the persistence layer so multiple values can
  be saved at once.
* Added a way to create `UIColor` instances using a hex string: `'#FF8A19'.to_color` or color keyword: `'blue'.to_color`, `'dark_gray'.to_color`.

## 1.0.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.4.0...v1.0.0)

* Improved the integration with RubyMotion build system.
* Improved test suite.
* Added better documentation, including on how to work on the internals.
* Added a KVO DSL to observe objects.
* Renamed `Device.screen.widthForOrientation` to Device.screen.width_for_orientation` and `Device.screen.heightForOrientation` to `Device.screen.height_for_orientation`.
* The `HTTP` wrapper now encodes arrays in params in a way that's compatible with Rails.

## 0.4.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.3.1...v0.4.0)

* Refactored the code and test suite to be more modular and to handle
  dependencies. One can now require only a subset of BW such as `require 'bubble-wrap/core'` or 'bubble-wrap/http'

## 0.3.1

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.3.0...v0.3.1)

* Added App.run_after(delay){ }
* HTTP responses return true to ok? when the status code is 20x.

## 0.3.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.2.1...v0.3.0)

* Major refactoring preparing for 1.0

## 0.2.1

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.2.0...v0.2.1)

* Minor fix in the way the dependencies are set (had to monkey patch
  RubyMotion)

## 0.2.0

[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v0.1.2...v0.2.0)

* Added network activity notification to the HTTP wrapper.
* fixed a bug in the `NSNotificationCenter` wrapper.

## 0.1.2

Start packaging this lib as a gem.


================================================
FILE: GEM.md
================================================
# Creating a RubyMotion gem with BubbleWrap

Let's say we want to develop a simple library gem that lists the
people in a user's addressbook.

Let's start by initializing an empty gem directory:

```
$ gem install bundler
$ bundle gem bw-addressbook
```

Add BubbleWrap and Rake to your gem's dependencies in `bw-addressbook.gemspec`:

```ruby
Gem::Specification.new do |gem|
  gem.add_dependency 'bubble-wrap'
  gem.add_development_dependency 'rake'
end
```

Then run `bundler`:
```
$ bundle
Fetching gem metadata from https://rubygems.org/..
Using rake (0.9.2.2) 
Installing bubble-wrap (0.4.0) 
Using bw-addressbook (0.0.1) from source at /Users/jnh/Dev/tmp/bw-addressbook 
Using bundler (1.1.4) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
```

Modify your `lib/bw-addressbook.rb` to include:

```ruby
require 'bw-addressbook/version'
BW.require 'motion/address_book.rb'
```

Edit your project's `Rakefile` to include:

```ruby
#!/usr/bin/env rake
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project'
require "bundler/gem_tasks"
Bundler.setup
Bundler.require
require 'bubble-wrap/test'
```

At this point we should have a working RubyMotion environment able to
compile our code as we write it.

Let's start by creating a spec for our address book gem in `spec/address_book_spec.rb`:

```ruby
describe AddressBook do
  describe '.list' do
    it 'returns an Enumerable' do
      AddressBook.list.is_a?(Enumerable).should == true
    end
  end
end
```

Now if you run `rake spec` you can watch the spec fail:

```
2012-06-07 11:19:35.506 Untitled[14987:f803] *** Terminating app due to uncaught exception 'NameError', reason: 'uninitialized constant AddressBook (NameError)'
*** First throw call stack:
(0x8f6022 0x286cd6 0x140054 0x291f 0x2645 0x1)
terminate called throwing an exception
```

Let's go and define ourselves an `AddressBook` class in `motion/address_book.rb`:

```ruby
class AddressBook
end
```

You'll now get a spec failure:

```
NoMethodError: undefined method `list' for AddressBook:Class
	spec.rb:156:in `block in run_spec_block': .list - returns an Enumerable
	 4:in `execute_block'
	spec.rb:156:in `run_spec_block'
	spec.rb:171:in `run'
```

Well, we'd better go and define it then, eh?

```
class AddressBook
  def self.list
    []
  end
end
```

I'm going to leave it here for now, but you're welcome to take a look at the 
fully working demonstration project on [Github](http://github.com/jamesotron/bw-addressbook-demo).


================================================
FILE: GETTING_STARTED.md
================================================
# Getting Started with BubbleWrap

A short guide to starting a RubyMotion application using the bubble wrappers.

## A quick note about RubyMotion

[RubyMotion](http://www.rubymotion.com/) is a commercial product available from
[HipByte SPRL](http://www.hipbyte.com/). RubyMotion needs a recent (10.6 or newer)
version of Mac OS X and Apple's Xcode tools installed. If you don't have a working
RubyMotion install take a look at the [getting started guide](http://www.rubymotion.com/developer-center/guides/getting-started/).

## Create a new RubyMotion project

RubyMotion ships with the `motion` command-line tool to handle creating projects,
updating and creating support tickets.

```
$ motion create bw-demo
    Create bw-demo
    Create bw-demo/.gitignore
    Create bw-demo/Rakefile
    Create bw-demo/app
    Create bw-demo/app/app_delegate.rb
    Create bw-demo/resources
    Create bw-demo/spec
    Create bw-demo/spec/main_spec.rb
```

This gives us an empty project (and one failing spec).  That's fine for now.

## Set up Bundler

[Bundler](http://www.gembundler.com/) is a project to manage your project's
RubyGem dependencies. You can get by without it if you want to, but it will
save time and hassle as the number of BubbleWrap gems grows over time.

```
$ gem install bundler
```

Create a new file called `Gemfile` in your project directory and add the
following:

```ruby
source :rubygems
gem 'bubble-wrap', '~> 1.0.0'
gem 'rake'
```

Then run `bundle` from the command-line in the same directory and Bundler
should install BubbleWrap and Rake for you.


## Adding BubbleWrap

Now that we have BubbleWrap installed we need to configure the project to use
it - the easiest way is to add Bundler to our build-environment and tell it 
to take care of everything for us.

Edit your project's `Rakefile` and add the following just under `require 'motion/project'`:

```ruby
require 'bundler'
Bundler.setup
Bundler.require
```

Now when you build your project by running `rake` you will see the BubbleWrap files
being compiled into your project.

## Customising BubbleWrap requires

By default BubbleWrap will include all the bubble wrappers into your project, but often
you won't need them all - perhaps you only want to use BubbleWrap's `http` wrappers?
You can change your bubble-wrap line in your `Gemfile` as follows:

```ruby
gem 'bubble-wrap', '~> 1.0.0', :require => 'bubble-wrap/http'
```

If you just want core, the change is similarly easy:

```ruby
gem 'bubble-wrap', '~> 1.0.0', :require => 'bubble-wrap/core'
```

Also, if you don't want any of BubbleWrap loaded by default, and you just want to use
it's ability to add projects to your build system you can change it to:

```ruby
gem 'bubble-wrap', '~> 1.0.0', :require => 'bubble-wrap/loader'
```

And modify your `Rakefile` to include one or more `BW.require` lines:

```ruby
BW.require '/path/to/some/files/**/*.rb'
```

For more information in using `BW.require` take a look at
[the bubblewrap hacking guide](HACKING.md).

## Go forth and conquer!

The developers wish to thank you for using BubbleWrap.
Please feel free to open issues or pull requests on 
[GitHub](https://www.github.com/mattetti/BubbleWrap), join our
[mailing list](https://groups.google.com/forum/#!forum/bubblewrap)
or join us on `#bubblewrap` on `irc.freenode.net`.


================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'

# Specify your gem's dependencies in bubble-wrap.gemspec
gemspec


================================================
FILE: HACKING.md
================================================
# Hacking on BubbleWrap

## A library in two parts

RubyMotion forces a certain background-radiation of schizophrenia
due to the fact that it's build tools run using the system ruby
via Rake.  BubbleWrap manipulates the build environment in order
to make it possible to include itself (and other code) into the
build process from outside the project hierarchy.

### Part the first: `lib/`

This is where [RubyGems](http://rubygems.org) goes looking for
code when you call

```ruby
require 'bubble-wrap'
```

When `bubble-wrap` is required it immediately requires `bubble-wrap/loader`
which sets up the infrastructure needed to manipulate the `Rakefile` build process.
Once that is done we can freely call

```ruby
BubbleWrap.require 'motion/core/**/*.rb'
```

`BubbleWrap.require` (or simply `BW.require`) is used to include
library code into the Rake build process used by RubyMotion. 
`BW.require` is similar to ruby's standard `require` method with
two major changes:

  - it can take a file pattern as used by [`Dir.glob`](http://ruby-doc.org/core-1.9.3/Dir.html#method-c-glob).
  - it can be passed a block to manipulate dependencies.

If a block is passed to `BW.require` it is evaluated in the context
of `BW::Requirement` and thus has access to all it's class methods.
The most common use cases are setting file dependencies:

```ruby
BW.require('motion/core/**/*.rb') do
  file('motion/core/device/screen.rb').depends_on 'motion/core/device.rb'
end
```

and specifying frameworks that need to be included at build time:

```ruby
BW.require('motion/**/*.rb') do
  file('motion/address_book.rb').uses_framework 'Addressbook'
end
```

### Part the second: `motion/`

Inside the `motion` directory you'll see the actual implementation code
which is compiled into RubyMotion projects that are using BubbleWrap.

  - `motion/core` contains "core" extension, things that the developers
    reasonably think should be included in every BubbleWrap using project.
    Careful consideration should be taken when making changes to the 
    contents and test coverage (in `spec/core`) must be updated to match.
    This can be included in your project by requiring `bubble-wrap` or 
    `bubble-wrap/core` in your project `Rakefile`.
  - `motion/http` contains the "http" extension.  This can be included
    by requiring `bubble-wrap/http` in your project `Rakefile`.
  - `motion/test_suite_delegate` contains a simple `AppDelegate` which
    can be used to enable the `rake spec` to run when developing a
    BubbleWrap gem.  Using `require 'bubble-wrap/test'` will include
    it in the build process and also configure the app delegate to point
    to `TestSuiteDelegate`. See the [BubbleWrap gem guide](gem.html) for
    more information.

#### Your project here

If you think that your project would be of interest to the large number 
of RubyMotion users that use BubbleWrap in their daily development then
feel free to fork [the repository on GitHub](https://github.com/mattetti/BubbleWrap)
and send us a pull request.

You should place your implementation files in a subdirectory of `motion`
(eg `motion/my_awesome_project`), your tests in a subdirectory of `spec`
(eg `spec/my_awesome_project`) and you can create a require file in
`lib/bubble-wrap` for example `lib/bubble-wrap/my_awesome_project.rb`:

```ruby
require 'bubble-wrap/loader'
BW.require 'motion/my_awesome_project.rb'
```

People will then be able to use it by adding:

```ruby
require 'bubble-wrap/my_awesome_project'
```

to their project's `Rakefile`

## Go forth and conquer!

The developers wish to thank you so much for taking the time
to improve BubbleWrap and by extension the RubyMotion
ecosystem. You're awesome!


================================================
FILE: LICENSE
================================================
LICENCE

MIT: http://mattaimonetti.mit-license.org

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

The MIT License (MIT)
Copyright © 2012 Matt Aimonetti <matt.aimonetti@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: README.md
================================================
# BubbleWrap for RubyMotion

A collection of (tested) helpers and wrappers used to wrap Cocoa Touch and AppKit code and provide more Ruby like APIs.

[![Code Climate](https://codeclimate.com/github/rubymotion/BubbleWrap.svg)](https://codeclimate.com/github/rubymotion/BubbleWrap)
[![Build Status](https://travis-ci.org/rubymotion/BubbleWrap.svg?branch=master)](https://travis-ci.org/rubymotion/BubbleWrap)
[![Gem Version](https://badge.fury.io/rb/bubble-wrap.png)](http://badge.fury.io/rb/bubble-wrap)

## Installation

```ruby
gem install bubble-wrap
```

## Setup

1. Edit the `Rakefile` of your RubyMotion project and add the following require line:

```ruby
require 'bubble-wrap'
```

If you use Bundler:

```ruby
gem 'bubble-wrap', '~> 1.9.7'
```

BubbleWrap is split into multiple modules so that you can easily choose which parts are included at compile-time.

If you wish to only include the `RSS Parser` wrapper:

```ruby
require 'bubble-wrap/rss_parser'
```

If you wish to only include the `Reactor` wrapper:

```ruby
require 'bubble-wrap/reactor'
```

If you wish to only include the UI-related wrappers:

```ruby
require 'bubble-wrap/ui'
```

If you wish to only include the `Camera` wrapper:

```ruby
require 'bubble-wrap/camera'
```

If you wish to only include the `Location` wrapper:

```ruby
require 'bubble-wrap/location'
```

If you wish to only include the `Media` wrapper:

```ruby
require 'bubble-wrap/media'
```

If you wish to only include the `Mail` wrapper:

```ruby
require 'bubble-wrap/mail'
```

If you wish to only include the `SMS` wrapper:

```ruby
require 'bubble-wrap/sms'
```

If you wish to only include the `Motion` (CoreMotion) wrapper:

```ruby
require 'bubble-wrap/motion'
```

If you wish to only include the `NetworkIndicator` wrapper:

```ruby
require 'bubble-wrap/network-indicator'
```

If you want to include everything (ie kitchen sink mode) you can save time and do:

```ruby
require 'bubble-wrap/all'
```

You can also do this directly in your `Gemfile` like so:

```ruby
gem 'bubble-wrap', require: %w[bubble-wrap/core bubble-wrap/location, bubble-wrap/reactor]
```

Note: **DON'T** use `app.files =` in your Rakefile to set up your files once you've required BubbleWrap.
Make sure to append onto the array or use `+=`.

2. Now, you can use BubbleWrap extension in your app:

```ruby
class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    puts "#{App.name} (#{App.documents_path})"
    true
  end
end
```

Note: You can also vendor this repository but the recommended way is to
use the versioned gem.


## Core

### Misc

UUID generator:
```ruby
BubbleWrap.create_uuid
=> "68ED21DB-82E5-4A56-ABEB-73650C0DB701"
```

Localization (using `NSBundle.mainBundle.localizedStringForKey`):
```ruby
BubbleWrap.localized_string(:foo, 'fallback')
=> "fallback"
```

Color conversion:
```ruby
BubbleWrap.rgba_color(23, 45, 12, 0.4)
=> #<UIDeviceRGBColor:0x6db6ed0>
BubbleWrap.rgb_color(23, 45, 12)
=> #<UIDeviceRGBColor:0x8ca88b0>
'blue'.to_color
=> #<UICachedDeviceRGBColor:0xda535c0>
'dark_gray'.to_color
=> #<UICachedDeviceWhiteColor:0x8bb5be0>
'#FF8A19'.to_color
=> #<UIDeviceRGBColor:0x8d54110>
'#88FF8A19'.to_color # ARGB format
=> #<UIDeviceRGBColor:0xca0fe00>
```

Debug flag:
```ruby
BubbleWrap.debug?
=> false
BubbleWrap.debug = true
=> true
BubbleWrap.debug?
=> true
```

### App

A module with useful methods related to the running application

```ruby
> App.documents_path
# "/Users/mattetti/Library/Application Support/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/Documents"
> App.resources_path
# "/Users/mattetti/Library/Application Support/iPhone Simulator/5.0/Applications/EEC6454E-1816-451E-BB9A-EE18222E1A8F/testSuite_spec.app"
> App.name
# "testSuite"
> App.identifier
# "io.bubblewrap.testSuite"
> App.alert("BubbleWrap is awesome!")
# creates and shows an alert message.
> App.alert("BubbleWrap is awesome!", {cancel_button_title: "I know it is!", message: "Like, seriously awesome."})
# creates and shows an alert message with optional parameters.
> App.run_after(0.5) {  p "It's #{Time.now}"   }
# Runs the block after 0.5 seconds.
> App.open_url("http://matt.aimonetti.net")
> App.open_url("tel://123456789")
# Opens the url using the device's browser. Can also open custom URL schemas (accepts a string url or an instance of `NSURL`.)
> App.can_open_url("tel://")
# Returns whether the app can open a given URL resource.
> App::Persistence['channels'] # application specific persistence storage
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
# ['TF1', 'France 2', 'France 3']
> App.environment
# 'test'
```

Other available methods:

* `App.notification_center`
* `App.user_cache`
* `App.states`
* `App.frame`
* `App.delegate`
* `App.shared`
* `App.window`
* `App.current_locale`
* `App.release?`
* `App.test?`
* `App.development?`


### Device

A collection of useful methods about the current device:

Examples:

```ruby
> Device.iphone?
# true
> Device.ipad?
# false
> Device.camera.front?
# true
> Device.camera.rear?
# true
> Device.orientation
# :portrait
> Device.interface_orientation
# :portrait
> Device.simulator?
# true
> Device.ios_version
# "6.0"
> Device.retina?
# false
> Device.screen.width
# 320
> Device.screen.height
# 480
> Device.screen.width_for_orientation(:landscape_left)
# 480
> Device.screen.height_for_orientation(:landscape_left)
# 320
> Device.vendor_identifier
# <NSUUID>
```

### Camera

Added interface for better camera access:

```ruby
# Uses the front camera
BW::Device.camera.front.picture(media_types: [:movie, :image]) do |result|
  image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Uses the rear camera
BW::Device.camera.rear.picture(media_types: [:movie, :image]) do |result|
  image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Uses the photo library
BW::Device.camera.any.picture(media_types: [:movie, :image]) do |result|
  image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Lets the user edit the photo (with access to the edited and original photos)
BW::Device.camera.any.picture(allows_editing: true, media_types: [:image]) do |result|
  edited_image_view = UIImageView.alloc.initWithImage(result[:edited_image])
  original_image_view = UIImageView.alloc.initWithImage(result[:original_image])
end

# Capture a low quality movie with a limit of 10 seconds
BW::Device.camera.front.picture(media_types: [:movie], video_quality: :low, video_maximum_duration: 10) do |result|
  video_file_path = result[:media_url]
end
```

Options include:

- `:allows_editing` - Boolean; whether a user can edit the photo/video before picking
- `:animated` - Boolean; whether to display the camera with an animation (default true)
- `:on_dismiss` - Lambda; called instead of the default dismissal logic
- `:media_types` - Array; containing any of `[:movie, :image]`
- `:video_quality` - Symbol; one of `:high`, `:medium`, `low`, `"640x480".to_sym`, `iframe1280x720`, or `iframe960x540`. Defaults to `:medium`
- `:video_maximum_duration` - Integer; limits movie recording length. Defaults to 600.

### JSON

`BW::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib. For apps building for iOS4, we suggest a different JSON alternative, like [AnyJSON](https://github.com/mattt/AnyJSON).

```ruby
BW::JSON.generate({'foo' => 1, 'bar' => [1,2,3], 'baz' => 'awesome'})
=> "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
BW::JSON.parse "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
=> {"foo"=>1, "bar"=>[1, 2, 3], "baz"=>"awesome"}
```

### NSIndexPath

Helper methods added to give `NSIndexPath` a bit more of a Ruby
interface.

```ruby
index_path = table_view.indexPathForCell(cell)
index_path + 1 # NSIndexPath for next cell in the same section
=> #<NSIndexPath:0x120db8e0>
```

### NSNotificationCenter

Helper methods to give NSNotificationCenter a Ruby-like interface:

```ruby
def viewWillAppear(animated)
  @foreground_observer = App.notification_center.observe UIApplicationWillEnterForegroundNotification do |notification|
    loadAndRefresh
  end

  @reload_observer = App.notification_center.observe 'ReloadNotification' do |notification|
    loadAndRefresh
  end
end

def viewWillDisappear(animated)
  App.notification_center.unobserve @foreground_observer
  App.notification_center.unobserve @reload_observer
end

def reload
  App.notification_center.post 'ReloadNotification'
end
```


### NSUserDefaults

Helper methods added to the class repsonsible for user preferences used
by the `App::Persistence` module shown below.

### Persistence

Offers a way to persist application specific information using a very
simple interface:

``` ruby
> App::Persistence['channels'] # application specific persistence storage
# ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
> App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
# ['TF1', 'France 2', 'France 3']
> App::Persistence.delete('channels')
# ['TF1', 'France 2', 'France 3']
> App::Persistence['something__new'] # something previously never stored
# nil
> App::Persistence.all
# {'all':'values', 'stored':'by', 'bubblewrap':'as a hash!'}
```

### Observers
**Since: > version 0.4**

You can observe for object's changes and trigger blocks:

``` ruby
class ExampleViewController < UIViewController
  include BW::KVO

  def viewDidLoad
    @label = UILabel.alloc.initWithFrame [[20,20],[280,44]]
    @label.text = ""
    view.addSubview @label

    observe(@label, :text) do |old_value, new_value|
      puts "Hello from viewDidLoad!"
    end
  end

  def viewDidAppear(animated)
    observe(@label, :text) do |old_value, new_value|
      puts "Hello from viewDidAppear!"
    end
  end

end
```

You can remove observers using `unobserve` method.

**Since: > version 1.9.0**

Optionally, multiple key paths can be passed to the `observer` method:

``` ruby
class ExampleViewController < UIViewController
  include BW::KVO

  def viewDidLoad
    @label = UILabel.alloc.initWithFrame [[20,20],[280,44]]
    @label.text = ""
    view.addSubview @label

    observe(@label, [:text, :textColor]) do |old_value, new_value, key_path|
      puts "Hello from viewDidLoad for #{key_path}!"
    end
  end
end
```

Also you can use `observe!` method to register observer that will immediately
return initial value. Note that in this case only new value will be passed to
the block.


### String

The Ruby `String` class was extended to add `#camelize` and
`#underscore` methods.

```ruby
> "matt_aimonetti".camelize
=> "MattAimonetti"
> "MattAimonetti".underscore
=> "matt_aimonetti"
```

### Time

The `Time` Ruby class was added a class level method to convert a
iso8601 formatted string into a Time instance.

```ruby
> Time.iso8601("2012-05-31T19:41:33Z")
=> 2012-05-31 21:41:33 +0200
```

## Location

Interface for Ruby-like GPS and compass access (the CoreLocation framework):

```ruby
> BW::Location.enabled? # Whether location services are enabled on the device
=> true
> BW::Location.authorized? # If your app is authorized to use location services
=> false
```

```ruby
BW::Location.get(purpose: 'We need to use your GPS because...') do |result|
  p "From Lat #{result[:from].latitude}, Long #{result[:from].longitude}"
  p "To Lat #{result[:to].latitude}, Long #{result[:to].longitude}"
end
```
*Note: `result[:from]` will return `nil` the first time location services are started.*

The `:previous` key in the `BW::Location.get()` result hash will always return an array of zero or more additional `CLLocation` objects aside from the locations returned from the `:to` and `:from` hash keys.  While in most scenarios this array will be empty, per [Apple's Documentation](https://developer.apple.com/library/IOs/documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/index.html#//apple_ref/occ/intfm/CLLocationManagerDelegate/locationManager:didUpdateLocations:) if there are deferred updates or multiple locations that arrived before they could be delivered, multiple locations will be returned in an order of oldest to newest.


```ruby
BW::Location.get_compass do |result|
  p result[:magnetic_heading] # Heading towards magnetic north
  p result[:true_heading] # Heading towards true north
  p result[:accuracy] # Potential error between magnetic and true heading
  p result[:timestamp] # Timestamp of the heading calculation
end
```

`BW::Location.get_significant` is also available, for monitoring significant location changes.

`BW::Location` also supports `get_once`-style methods, which will return the first result before ending the search:

```ruby
BW::Location.get_once(desired_accuracy: :three_kilometers, ...) do |result|
  if result.is_a?(CLLocation)
    p result.coordinate.latitude
    p result.coordinate.longitude
  else
    p "ERROR: #{result[:error]}"
  end
end

BW::Location.get_compass_once do |heading|
  p result[:magnetic_heading]
  p result[:true_heading]
  p result[:accuracy]
  p result[:timestamp]
end
```

### iOS 8 Location Requirements

iOS 8 introduced stricter location services requirements. Although BubbleWrap will handle most of this for you automatically, you are required to add a few key/value pairs to the `Info.plist`. Add these two lines to your `Rakefile` (with your descriptions, obviously):

```ruby
app.info_plist['NSLocationAlwaysUsageDescription'] = 'Description'
app.info_plist['NSLocationWhenInUseUsageDescription'] = 'Description'
```

*Note: you need both keys to use `get_once`, so it's probably best to just include both no matter what.* See [Apple's documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW18) on iOS 8 location services requirements for more information.

## Motion

Interface for the accelerometer, gyroscope, and magnetometer sensors (the
CoreMotion framework).  You can access each sensor individually, or you can get
data from all of them at once using the `BW::Motion.device` interface, which
delegates to `CMMotionManager#deviceMotion`.

Each sensor has an `every` and `once` method. `every` expects a time interval,
and you will need to retain the object it returns and call `#stop` on it when
you are done with the data.

The `every` and `once` methods can accept a `:queue` option. The default value
is a queue that runs on the main loop, so that UI updates can be processed in
the block. This is useful, but not recommended by Apple, since the events can
come in at a high rate. If you want to use a background queue, you can either
specify an NSOperationQueue object, or you can use one of these symbols:

- `:main` - `NSOperationQueue.mainQueue`, this is the default value.
- `:background` - BubbleWrap will create a new `NSOperationQueue`.
- `:current` - BubbleWrap will use `NSOperationQueue.currentQueue`.

If you pass a string instead, a new queue will be created and its `name`
property will be set to that string.

The `CMDeviceMotion` interface (`BW::Motion.device`) accepts a `:reference`
option, which specifies the `CMAttitudeReferenceFrame`.  The default value is
the same as the one that `CMMotionManager` uses, which is returned by the
`CMMotionManager#attitudeReferenceFrame` method.  This option should be passed
to the `repeat`, `every` or `once` methods.

###### Accelerometer
```ruby
BW::Motion.accelerometer.available?
BW::Motion.accelerometer.data  # returns CMAccelerometerData object or nil

# ask the CMMotionManager to update every 5 seconds
BW::Motion.accelerometer.every(5) do |result|
  # result contains the following data (from CMAccelerometerData#acceleration):
  p result[:data]  # the CMAccelerometerData object
  p result[:acceleration]  # the CMAcceleration struct
  p result[:x]  # acceleration in the x direction
  p result[:y]  #          "          y direction
  p result[:z]  #          "          z direction
end

# every, start, and repeat all need to be stopped later.
BW::Motion.accelerometer.stop

# repeat, but don't set the interval
BW::Motion.accelerometer.repeat do |result|
end

# you can specify a :queue where the operations will be executed.  See above for details
BW::Motion.accelerometer.every(5, queue: :background) { |result| ... }
BW::Motion.accelerometer.every(5, queue: :main) { |result| ... }
BW::Motion.accelerometer.every(5, queue: :current) { |result| ... }
BW::Motion.accelerometer.every(5, queue: 'my queue') { |result| ... }

BW::Motion.accelerometer.once do |result|
  # ...
end
```

###### Gyroscope
```ruby
BW::Motion.gyroscope.available?
BW::Motion.gyroscope.data  # returns CMGyroData object or nil

# ask the CMMotionManager to update every second.
BW::Motion.gyroscope.every(1) do |result|
  # result contains the following data (from CMGyroData#rotationRate):
  p result[:data]  # the CMGyroData object
  p result[:rotation]  # the CMRotationRate struct
  p result[:x]  # rotation in the x direction
  p result[:y]  #        "        y direction
  p result[:z]  #        "        z direction
end
BW::Motion.gyroscope.stop

BW::Motion.gyroscope.once do |result|
  # ...
end
```

###### Magnetometer
```ruby
BW::Motion.magnetometer.available?
BW::Motion.magnetometer.data  # returns CMMagnetometerData object or nil

# ask the CMMotionManager to update every second
BW::Motion.magnetometer.every(1) do |result|
  # result contains the following data (from CMMagnetometerData#magneticField):
  p result[:data]  # the CMMagnetometerData object
  p result[:field]  # the CMMagneticField struct
  p result[:x]  # magnetic field in the x direction
  p result[:y]  #           "           y direction
  p result[:z]  #           "           z direction
end
BW::Motion.magnetometer.stop

BW::Motion.magnetometer.once do |result|
  # ...
end
```

###### Device Motion

This is an amalgam of all the motion sensor data.

```ruby
BW::Motion.device.available?
BW::Motion.device.data  # returns CMDeviceMotion object or nil

BW::Motion.device.every(1) do |result|
  # result contains the following data:
  p result[:data]  # the CMDeviceMotion object
  # orientation data, from CMDeviceMotion#attitude
  p result[:attitude]  # the CMAttitude struct
  p result[:roll]
  p result[:pitch]
  p result[:yaw]
  # rotation data, from CMDeviceMotion#rotationRate
  p result[:rotation]  # the CMRotationRate struct
  p result[:rotation_x]
  p result[:rotation_y]
  p result[:rotation_z]
  # gravity+acceleration vector, from CMDeviceMotion#gravity
  p result[:gravity]  # the CMAcceleration struct
  p result[:gravity_x]
  p result[:gravity_y]
  p result[:gravity_z]
  # just the acceleration vector, from CMDeviceMotion#userAcceleration
  p result[:acceleration]  # the CMAcceleration struct
  p result[:acceleration_x]
  p result[:acceleration_y]
  p result[:acceleration_z]
  # the magnetic data, from CMDeviceMotion#magneticField
  p result[:magnetic]  # the CMCalibratedMagneticField struct
  p result[:magnetic_field]  # the CMMagneticField struct from the CMCalibratedMagneticField
  p result[:magnetic_x]
  p result[:magnetic_y]
  p result[:magnetic_z]
  p result[:magnetic_accuracy]  # this will be a symbol, :low, :medium, :high, or nil if the magnetic data is uncalibrated

  # less useful data from CMAttitude, unless you're into the whole linear algebra thing:
  p result[:matrix]  # CMAttitude#rotationMatrix
  p result[:quarternion]  # CMAttitude#quarternion
end

# the reference frame should be one of the CMAttitudeReferenceFrame constants...
ref = CMAttitudeReferenceFrameXArbitraryZVertical
# ... or one of these symbols: :arbitrary_z, :corrected_z, :magnetic_north, :true_north
ref = :corrected_z
BW::Motion.device.every(1, queue: :background, reference: ref) { |result| ... }

BW::Motion.device.once do |result|
  # ...
end
```

## Media

Added wrapper for playing remote and local media. Available are `modal` and custom presentation styles:

```ruby
# Plays in your custom frame
local_file = NSURL.fileURLWithPath(File.join(NSBundle.mainBundle.resourcePath, 'test.mp3'))
BW::Media.play(local_file) do |media_player|
  media_player.view.frame = [[10, 100], [100, 100]]
  self.view.addSubview media_player.view
end

# Plays in an independent modal controller
BW::Media.play_modal("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3")
```

## Mail

Wrapper for showing an in-app mail composer view.

You should always determine if the device your app is running on is configured to send mail before displaying a mail composer window. `BW::Mail.can_send_mail?` will return `true` or `false`.

```ruby
# Opens as a modal in the current UIViewController
BW::Mail.compose(
  delegate: self, # optional, defaults to rootViewController
  to: [ "tom@example.com" ],
  cc: [ "itchy@example.com", "scratchy@example.com" ],
  bcc: [ "jerry@example.com" ],
  html: false,
  subject: "My Subject",
  message: "This is my message. It isn't very long.",
  animated: false
) do |result, error|
  result.sent?      # => boolean
  result.canceled?  # => boolean
  result.saved?     # => boolean
  result.failed?    # => boolean
  error             # => NSError
end
```

## SMS

Wrapper for showing an in-app message (SMS) composer view.

You should always determine if the device your app is running on can send SMS messages before displaying a SMS composer window. `BW::SMS.can_send_sms?` will return `true` or `false`.

```ruby
# Opens as a modal in the current UIViewController
    BW::SMS.compose (
    {
       delegate: self, # optional, will use root view controller by default
       to: [ "1(234)567-8910" ],
       message: "This is my message. It isn't very long.",
       animated: false
    }) {|result, error|
       result.sent?      # => boolean
       result.canceled?  # => boolean
       result.failed?    # => boolean
       error             # => NSError
      }
```

## NetworkIndicator

Wrapper for showing and hiding the network indicator (the status bar spinner).

```ruby
    BW::NetworkIndicator.show  # starts the spinner
    BW::NetworkIndicator.hide  # stops it

    # the nice thing is if you call 'show' multiple times, the 'hide' method will
    # not have any effect until you've called it the same number of times.
    BW::NetworkIndicator.show
    # ...somewhere else
    BW::NetworkIndicator.show

    # ...down the line
    BW::NetworkIndicator.hide
    # indicator is still visible

    BW::NetworkIndicator.hide
    # NOW the indicator is hidden!

    # If you *really* want to hide the indicator immediately, you can call `reset!`
    # but this is in no way encouraged.
    BW::NetworkIndicator.reset!

    # and for completeness, a check to see if the indicator is visible
    BW::NetworkIndicator.visible?
```

## UI

### Gestures

Extra methods on `UIView` for working with gesture recognizers. A gesture recognizer can be added using a normal Ruby block, like so:

```ruby
    view.when_tapped do
      UIView.animateWithDuration(1,
        animations:lambda {
          # animate
          # @view.transform = ...
        })
    end
```

There are similar methods for `pinched`, `rotated`, `swiped`, `panned`, and `pressed` (for long presses). All of the methods return the actual recognizer object, so it is possible to set the delegate if more fine-grained control is needed.

In order to prevent retain cycles due to strong references within the passed block, use the use_weak_callbacks flag so the blocks do not retain a strong reference to self:

```ruby
BubbleWrap.use_weak_callbacks = true
```

### UIViewController

A custom method was added to `UIViewController` to return the content
frame of a view controller.

### UIControl / UIButton

Helper methods to give `UIButton` a Ruby-like interface. Ex:

```ruby
button.when(UIControlEventTouchUpInside) do
  self.view.backgroundColor = UIColor.redColor
end
```

The `#when` method also accepts bitwise combinations of events:

```ruby
button.when(UIControlEventTouchUpInside | UIControlEventTouchUpOutside) do
  self.view.backgroundColor = UIColor.redColor
end
```

You can use symbols for events (but won't work with the bitwise operator):

```ruby
button.when(:touch_up_inside) do
  self.view.backgroundColor = UIColor.redColor
end

button.when(:value_changed) do
  self.view.backgroundColor = UIColor.blueColor
end
```

Set the use_weak_callbacks flag so the blocks do not retain a strong reference to self:

```ruby
BubbleWrap.use_weak_callbacks = true
```

### UIBarButtonItem

`BW::UIBarButtonItem` is a subclass of `UIBarButtonItem` with an natural Ruby syntax.

#### Constructors

Instead specifying a target-action pair, each constructor method accepts an optional block.  When the button is tapped, the block is executed.

```ruby
BW::UIBarButtonItem.system(:save) do
  # ...
end

title = "Friends"
BW::UIBarButtonItem.styled(:plain, title) do
  # ...
end

image = UIImage.alloc.init
BW::UIBarButtonItem.styled(:bordered, image) do
  # ...
end

image     = UIImage.alloc.init
landscape = UIImage.alloc.init
BW::UIBarButtonItem.styled(:bordered, image, landscape) do
  # ...
end

view = UIView.alloc.init
BW::UIBarButtonItem.custom(view) do
  # ...
end
# NOTE: The block is attached to the view as a single tap gesture recognizer.
```

The `.new` constructor provides a flexible, builder-style syntax.

```ruby
options = { :system => :save }
BW::UIBarButtonItem.new(options) do
  # ...
end

options = { :styled => :plain, :title => "Friends" }
BW::UIBarButtonItem.new(options) do
  # ...
end

options = { :styled => :bordered, :image => UIImage.alloc.init }
BW::UIBarButtonItem.new(options) do
  # ...
end

options = {
  :styled    => :bordered,
  :image     => UIImage.alloc.init,
  :landscape => UIImage.alloc.init
}
BW::UIBarButtonItem.new(options) do
  # ...
end

options = { :custom => UIView.alloc.init }
BW::UIBarButtonItem.new(options) do
  # ...
end
# NOTE: The block is attached to the view as a single tap gesture recognizer.
```

#### Button types

The `.styled` button types are:

```ruby
:plain
:bordered
:done
```

And the `.system` button types are:

```ruby
:done
:cancel
:edit
:save
:add
:flexible_space
:fixed_space
:compose
:reply
:action
:organize
:bookmarks
:search
:refresh
:stop
:camera
:trash
:play
:pause
:rewind
:fast_forward
:undo
:redo
:page_curl
```

### UIActivityViewController

`BW::UIActivityViewController` is a subclass of `UIActivityViewController` with an natural Ruby syntax.

You can initiate a `UIActivityViewController` with or without a completion handler block. For more information on `UIActivityViewController`s, see [Apple's documentation](https://developer.apple.com/library/ios/documentation/uikit/reference/UIActivityViewController_Class/Reference/Reference.html).

```ruby
# Without a completion handler
BW::UIActivityViewController.new(
  items: "Some Text", # or ["Some Text", NSURL.URLWithString('http://www.rubymotion.com')] or a UIImage
  animated: true, # Defaults to true
  excluded: :add_to_reading_list # One item or an array
)

# With completion handler
BW::UIActivityViewController.new(
  items: "Some Text",
  animated: true,
  excluded: [:add_to_reading_list, :print, :air_drop]
) do |activity_type, completed|
  puts "completed with activity: #{activity_type} - finished?: #{completed}"
end
```

Built in activities that can be passed to the `excluded` option are defined as `UIActivity` class `UIActivityType` constants:

```ruby
:post_to_facebook
:post_to_twitter
:post_to_weibo
:message
:mail
:print
:copy_to_pasteboard
:assign_to_contact
:save_to_camera_roll
:add_to_reading_list
:post_to_flickr
:post_to_vimeo
:post_to_tencent_weibo
:air_drop
```

## RSS Parser
**Since: > version 1.0.0**

The RSS Parser provides an easy interface to consume RSS feeds in an
asynchronous (non blocking) way.


```ruby
feed_parser = BW::RSSParser.new("http://feeds2.feedburner.com/sdrbpodcast")
feed_parser.parse do |item|
  # called asynchronously as items get parsed
  p item.title
end
```

The yielded RSS item is of type `RSSParser::RSSItem` and has the
following attributes:

* title
* description
* link
* guid
* pubDate
* enclosure

The item can be converted into a hash by calling `to_hash` on it.

### Delegate
**Since: > version 1.0.0**

You can also designate a delegate to the parser and implement change
state callbacks:

```ruby
feed_parser = BW::RSSParser.new("http://feeds.feedburner.com/sdrbpodcast")
feed_parser.delegate = self
feed_parser.parse do |item|
  p item.title
end

# Delegate method
def when_parser_initializes
  p "The parser is ready!"
end

def when_parser_parses
  p "The parser started parsing the document"
end

def when_parser_is_done
  p "The feed is entirely parsed, congratulations!"
end

def when_parser_errors
  p "The parser encountered an error"
  ns_error = feed_parser.parserError
  p ns_error.localizedDescription
end
```

These delegate methods are optional, however, you might find the
`when_parser_is_done` callback useful if you collected all the items and
want to process all at once for instance.

### Parsing a remote content or actual data

You have the choice to initialize a parser instance with a string
representing an URL, an instance of `NSURL` or my specifying that the
passed param is some data to parse directly.

```ruby
# string representing an url:
feed_parser = BW::RSSParser.new("http://feeds2.feedburner.com/sdrbpodcast")
# a NSURL instance:
url =  NSURL.alloc.initWithString("http://matt.aimonetti.net/atom.xml")
feed_parser = BW::RSSParser.new(url)
# Some data
feed = File.read('atom.xml')
feed_parser = BW::RSSParser.new(feed, true)
```


## Reactor
**Since: > version 1.0.0**

`BW::Reactor` is a simplified, mostly complete implementation of
the [Event Machine](http://rubyeventmachine.com/) API.  In fact
`BW::Reactor` is aliased to `EM` in the runtime environment.

### Deferables

BubbleWrap provides both a `Deferrable` mixin and a `DefaultDeferrable`
class, which simply mixes in deferrable behaviour if you don't want to
implement your own.

A deferrable is an object with four states: unknown, successful, failure
and timeout.  When you initially create a deferrable it is in an unknown
state, however you can assign callbacks to be run when the object
changes to either successful or failure state.

Using `delegate`, `errback_delegate` and `callback_delegate` you can link
deferrables together.

By default, callbacks will be made on the thread that the deferrable
succeeds/fails on. For multithreaded environments, it can be useful to use
EM::ThreadAwareDeferrable so that callbacks will be made on the threads they
are declared on.

#### Success

```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x6d859a0>
> d.callback { |what| puts "Great #{what}!" }
=> [#<Proc:0x6d8a1e0>]
> d.succeed "justice"
Great justice!
=> nil
```

#### Failure

```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf3ee0>
> d.errback { |what| puts "Great #{what}!" }
=> [#<Proc:0x8bf3ef0>]
> d.fail "sadness"
Great sadness!
=> nil
```
#### Delegate

```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf3ee0>
> delegate = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf5910>
> d.delegate delegate
=> #<BW::Reactor::DefaultDeferrable:0x8bf3ee0>
> delegate.callback { |*args| puts args }
=> [#<Proc:0x8bf3ef0>]
> d.succeed :passed
=> nil
=> [:passed]
```

#### DependentDeferrable

`DependentDeferrable` depends on children deferrables. A `DependentDeferrable`
succeeds only when every child succeeds and fails immediately when any child
fails

```ruby
> d1 = EM::DefaultDeferrable.new
=> #<BubbleWrap::Reactor::DefaultDeferrable:0x10c713750>
> d2 = EM::DefaultDeferrable.new
=> #<BubbleWrap::Reactor::DefaultDeferrable:0x10370bb10>
> d = EM::DependentDeferrable.on(d1, d2)
=> #<BubbleWrap::Reactor::DependentDeferrable:0x106c17b80>
> d.callback {|a, b| puts "a: #{a} b: #{b}"}
=> [#<Proc:0x103075210>]
> d1.succeed 'one', 'one more'
> d2.succeed :two
a: ["one", "one more"] b: [:two]
```

#### ThreadAwareDeferrable

```ruby
> d = EM::ThreadAwareDeferrable.new
=> #<BW::Reactor::ThreadAwareDeferrable:0x8bf3ee0>

> queue = Dispatch::Queue.new(:deferrable.to_s)
> queue.async do
>   d.callback do |*args|
>     Dispatch::Queue.current == queue
>     => true # this is normally false
>   end
> end
> d.succeed true
```

#### Timeout

```ruby
> d = EM::DefaultDeferrable.new
=> #<BW::Reactor::DefaultDeferrable:0x8bf5910>
> d.errback { puts "Great scott!" }
=> [#<Proc:0x8bf6350>]
> d.timeout 2
=> #<BW::Reactor::Timer:0x6d920a0 @timer=#<__NSCFTimer:0x6d91990>>
# wait...
> Great scott!
```

### Timers

*All timers can be cancelled using `EM.cancel_timer`.*

#### One-shot timers

```ruby
> EM.add_timer 1.0 do
>   puts "Great scott!"
> end
=> 146335904
> Great scott!
```

#### Periodic timers

```ruby
> count = 0
=> 0
> timer = EM.add_periodic_timer 1.0 do
>   count = count + 1
>   puts "Great scott!"
>   (count < 10) || EM.cancel_timer(timer)
> end
=> 146046832
> Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
Great scott!
```

### Scheduling operations

You can use `EM.schedule` to schedule blocks to be executed
asynchronously.  BubbleWrap deviates from the EventMachine
API here in that it also provides `EM.schedule_on_main` which
makes sure that the task is run asynchronously, but on the
application's main thread - this is necessary if you are
updating the user interface.

```ruby
> EM.schedule { puts Thread.current.object_id }
146027920
=> nil
> EM.schedule_on_main { puts Thread.current.object_id }
112222480
=> nil
```

### Deferrable operations

You can also use `EM.defer` in much the same way as `EM.schedule`
with one important difference, you can pass in a second `proc`
which will be called when the first has completed, and be passed
it's result as an argument. Just like `EM.schedule`, `EM.defer`
also has an `EM.defer_on_main` version.

```ruby
> operation = proc { 88 }
=> #<Proc:0x6d763c0>
> callback = proc { |speed| puts speed >= 88 ? "Time travel!" : "Conventional travel!" }
=> #<Proc:0x8bd3910>
> EM.defer(operation, callback)
=> nil
Time travel!
```

### Events

Although not part of the EventMachine API, BubbleWrap provides
an `Eventable` mixin for use instrumenting objects with simple
event triggering behaviour. `BW::Reactor` uses this
behind the scenes in several places, and as it's a very handy
idiom it is available as a public API.

```ruby
> o = Class.new { include EM::Eventable }.new
=> #<#<Class:0xab63f00>:0xab64430>
> o.on(:november_5_1955) { puts "Ow!" }
=> [#<Proc:0xad9bf00>]
> flux = proc{ puts "Flux capacitor!" }
=> #<Proc:0xab630f0>
> o.on(:november_5_1955, &flux)
=> [#<Proc:0xad9bf00>, #<Proc:0xab630f0>]
> o.trigger(:november_5_1955)
Ow!
Flux capacitor!
=> [nil, nil]
> o.off(:november_5_1955, &flux)
=> #<Proc:0xab630f0>
> o.trigger(:november_5_1955)
Ow!
=> [nil]
> o.on(:november_5_1955) { puts "Ow!" }
> o.on(:november_5_1955) { puts "Another Ow!" }
> o.off(:november_5_1955)
=> nil
```

# Contributing

Do you have a suggestion for a specific wrapper? Feel free to open an
issue/ticket and tell us about what you are after. If you have a
wrapper/helper you are using and are thinking that others might enjoy,
please send a pull request with tests. If you need help writing the tests,
send the pull request anyways and we'll try to help you out with that.

1. Create an issue in GitHub to make sure your PR will be accepted
2. Fork the BubbleWrap repository
3. Create your feature branch (`git checkout -b my-new-feature`)
4. Commit your changes (`git commit -am 'Add some feature'`)
5. Write tests for your changes and ensure they pass locally (`bundle exec rake spec && bundle exec rake spec osx=true`)
6. Push to the branch (`git push origin my-new-feature`)
7. Create new Pull Request


================================================
FILE: Rakefile
================================================
$:.unshift("/Library/RubyMotion/lib")
$:.unshift("~/.rubymotion/rubymotion-templates")
require 'motion/project/template/gem/gem_tasks'
if ENV['osx']
  require 'motion/project/template/osx'
else
  require 'motion/project/template/ios'
end
Bundler.setup
Bundler.require

require 'bubble-wrap/all'
require 'bubble-wrap/test'

module Motion
  module Project
    class Config
      def spec_files=(spec_files)
        @spec_files = spec_files
      end
    end
  end
end

Motion::Project::App.setup do |app|
  app.name = 'testSuite'
  app.identifier = 'io.bubblewrap.testSuite'
  app.specs_dir = './spec/motion'
  app.spec_files
  if Motion::Project::App.osx?
    app.spec_files -= Dir.glob("./spec/motion/**/ios/**.rb")
    ["font", "motion", "location", "media", "ui", "mail", "sms", "network-indicator"].each do |package|
      app.spec_files -= Dir.glob("./spec/motion/#{package}/**/*.rb")
    end
  else
    app.info_plist['NSLocationAlwaysUsageDescription'] = 'Description'
    app.info_plist['NSLocationWhenInUseUsageDescription'] = 'Description'

    app.spec_files -= Dir.glob("./spec/motion/**/osx/**.rb")
  end

  app.version       = '1.2.3'
  app.short_version = '3.2.1'
end

namespace :spec do
  task :lib do
    sh "bacon #{Dir.glob("spec/lib/**/*_spec.rb").join(' ')}"
  end

  task :motion => 'spec'

  task :all => [:lib, :motion]
end


================================================
FILE: bubble-wrap.gemspec
================================================
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/bubble-wrap/version', __FILE__)

Gem::Specification.new do |gem|
  gem.authors       = ['Matt Aimonetti', 'Francis Chong', 'James Harton', 'Clay Allsopp', 'Dylan Markow', 'Jan Weinkauff', 'Marin Usalj']
  gem.email         = ['mattaimonetti@gmail.com', 'francis@ignition.hk', 'james@sociable.co.nz', 'clay.allsopp@gmail.com', 'dylan@dylanmarkow.com', 'jan@dreimannzelt.de', 'marin2211@gmail.com']
  gem.description   = 'RubyMotion wrappers and helpers (Ruby for iOS and OS X) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request.'
  gem.summary       = 'RubyMotion wrappers and helpers (Ruby for iOS and OS X) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request.'
  gem.homepage      = 'https://github.com/rubymotion-community/BubbleWrap'
  gem.license       = 'MIT'

  gem.files         = `git ls-files`.split($\)
  gem.test_files    = gem.files.grep(%r{^(test|spec|lib_spec|features)/})
  gem.name          = 'bubble-wrap'
  gem.require_paths = ['lib']
  gem.version       = BubbleWrap::VERSION

  gem.extra_rdoc_files = gem.files.grep(%r{motion})

  gem.add_development_dependency 'mocha', '~> 0.11'
  gem.add_development_dependency 'mocha-on-bacon', '~> 0.2'
  gem.add_development_dependency 'bacon', '~> 1.2'
  gem.add_development_dependency 'rake', '~> 10.0'
  gem.add_development_dependency 'webstub', '~> 1.1'
end


================================================
FILE: lib/bubble-wrap/all.rb
================================================
require File.expand_path('../loader', __FILE__)
[
  'core',
  'font',
  'location',
  'mail',
  'media',
  'motion',
  'network-indicator',
  'reactor',
  'rss_parser',
  'sms',
  'ui',
].each { |sub|
	require File.expand_path("../#{sub}", __FILE__)
}


================================================
FILE: lib/bubble-wrap/camera.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("camera") do
  BubbleWrap.require('motion/util/constants.rb')
  BubbleWrap.require('motion/core/device.rb')
  BubbleWrap.require('motion/core/device/*.rb')
  BubbleWrap.require('motion/core/device/ios/*.rb') do
    file('motion/core/device/ios/camera_wrapper.rb').depends_on 'motion/core/device/ios/camera.rb'
    file('motion/core/device/ios/camera.rb').depends_on ['motion/core/ios/device.rb', 'motion/util/constants.rb']
    file('motion/core/device/ios/camera.rb').uses_framework 'MobileCoreServices'
    file('motion/core/device/ios/screen.rb').depends_on 'motion/core/ios/device.rb'
  end
end


================================================
FILE: lib/bubble-wrap/core.rb
================================================
require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)
require 'bubble-wrap/loader'

BubbleWrap.require('motion/core.rb')
BubbleWrap.require('motion/core/*.rb') do
  file('motion/core/pollute.rb').depends_on 'motion/core/ns_index_path.rb'
end
BubbleWrap.require('motion/core/device/*.rb')

BubbleWrap.require_ios do
  BubbleWrap.require('motion/core/ios/**/*.rb')
  BubbleWrap.require('motion/core/device/ios/**/*.rb')

  require 'bubble-wrap/camera'
  require 'bubble-wrap/ui'
end

BubbleWrap.require_osx do
  BubbleWrap.require('motion/core/osx/**/*.rb')
  BubbleWrap.require('motion/core/device/osx/**/*.rb')
end


================================================
FILE: lib/bubble-wrap/ext/motion_project_app.rb
================================================
module BubbleWrap
  module Ext
    module BuildTask

      def self.extended(base)
        base.instance_eval do
          def setup_with_bubblewrap(*args, &block)
            bw_config = proc do |app|
              ::BubbleWrap.before_config(app)
              block.call(app) unless block.nil?
            end

            setup_without_bubblewrap *args, &bw_config
          end
          alias :setup_without_bubblewrap :setup
          alias :setup :setup_with_bubblewrap
        end
      end

    end

    module Config
      def config_with_bubblewrap
        config_without_bubblewrap.tap do |c|
          ::BubbleWrap.after_config(c)
        end
      end

      def self.extended(base)
        singleton_class = class << base; self; end
        singleton_class.send :alias_method, :config_without_bubblewrap, :config
        singleton_class.send :alias_method, :config, :config_with_bubblewrap
      end
    end

    module Platforms
      def osx?
        self.respond_to?(:template) && self.template == :osx
      end
    end
  end
end

Motion::Project::App.extend(BubbleWrap::Ext::BuildTask)

Motion::Project::App.extend(BubbleWrap::Ext::Platforms)

Motion::Project::App.extend(BubbleWrap::Ext::Config)


================================================
FILE: lib/bubble-wrap/ext.rb
================================================
require 'bubble-wrap/ext/motion_project_app'


================================================
FILE: lib/bubble-wrap/font.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require_ios("font") do
  BubbleWrap.require('motion/font/font.rb')
end


================================================
FILE: lib/bubble-wrap/loader.rb
================================================
unless defined?(Motion::Project::Config)
  raise 'This file must be required within a RubyMotion project Rakefile.'
end

unless defined?(BubbleWrap::LOADER_PRESENT)
  require 'bubble-wrap/version' unless defined?(VERSION)
  if Gem::Version.new(Motion::Version) < Gem::Version.new(BubbleWrap::MIN_MOTION_VERSION)
    raise "BubbleWrap #{BubbleWrap::VERSION} requires at least RubyMotion #{BubbleWrap::MIN_MOTION_VERSION}"
  end

  require 'bubble-wrap/ext'
  require 'bubble-wrap/requirement'

  module BubbleWrap

    LOADER_PRESENT = true
    module_function

    def root
      File.expand_path('../../../', __FILE__)
    end

    def require(file_spec, &block)
      Requirement.scan(caller.first, file_spec, &block)
    end

    def require_ios(requirement = nil, &callback)
      if !Motion::Project::App.osx?
        callback.call
      else
        puts "bubble-wrap/#{requirement} requires iOS to use." if requirement
      end
    end

    def require_osx(requirement = nil, &callback)
      if Motion::Project::App.osx?
        callback.call
      else
        puts "bubble-wrap/#{requirement} requires OS X to use." if requirement
      end
    end

    def before_config(app)
      app.files = ::BubbleWrap::Requirement.files(app.files)
      app.files_dependencies ::BubbleWrap::Requirement.files_dependencies
      app.frameworks = ::BubbleWrap::Requirement.frameworks(app.frameworks)
    end

    def after_config(config)
      return unless ::BubbleWrap::Requirement.frameworks.include?("CoreLocation")
      BubbleWrap.require_ios do
        ios8_files = 'motion/ios/8/location_constants.rb'
        if config.send(:deployment_target).to_f >= 8.0
          ::BubbleWrap.require(ios8_files)
          before_config(config)
        else
          config.files = config.files.reject {|s|
            s.include?(ios8_files)
          }
        end
      end
    end
  end

  BW = BubbleWrap unless defined?(BW)

  BW.require 'motion/shortcut.rb'
  BW.require 'lib/bubble-wrap/version.rb'
  BW.require 'motion/util/deprecated.rb'

end


================================================
FILE: lib/bubble-wrap/location.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("location") do
  BubbleWrap.require('motion/util/constants.rb')
  BubbleWrap.require('motion/core/string.rb')
  BubbleWrap.require('motion/location/**/*.rb') do
    file('motion/location/pollute.rb').depends_on 'motion/location/location.rb'
    file('motion/location/location.rb').depends_on 'motion/util/constants.rb'
    file('motion/location/location.rb').uses_framework('CoreLocation')
  end
end


================================================
FILE: lib/bubble-wrap/mail.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("mail") do
  BubbleWrap.require('motion/core/app.rb')
  BubbleWrap.require('motion/mail/**/*.rb') do
    file('motion/mail/mail.rb').depends_on('motion/mail/result.rb')
    file('motion/mail/mail.rb').uses_framework('MessageUI')
  end
end


================================================
FILE: lib/bubble-wrap/media.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("media") do
  BubbleWrap.require('motion/core/app.rb')
  BubbleWrap.require('motion/core/ios/app.rb')
  BubbleWrap.require('motion/core/ios/device.rb')
  BubbleWrap.require('motion/core/string.rb')
  BubbleWrap.require('motion/core/ns_notification_center.rb')
  BubbleWrap.require('motion/media/**/*.rb') do
    file('motion/media/media.rb').depends_on('motion/media/player.rb')
    file('motion/media/player.rb').depends_on 'motion/core/string.rb'
    file('motion/media/player.rb').uses_framework('MediaPlayer')
  end
end


================================================
FILE: lib/bubble-wrap/motion.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios('motion') do
  BubbleWrap.require('motion/util/constants.rb')
  BubbleWrap.require('motion/core/string.rb')
  BubbleWrap.require('motion/motion/**/*.rb') do
    file('motion/motion/motion.rb').depends_on 'motion/util/constants.rb'

    file('motion/motion/accelerometer.rb').depends_on('motion/motion/motion.rb')
    file('motion/motion/device_motion.rb').depends_on('motion/motion/motion.rb')
    file('motion/motion/gyroscope.rb').depends_on('motion/motion/motion.rb')
    file('motion/motion/magnetometer.rb').depends_on('motion/motion/motion.rb')

    file('motion/motion/motion.rb').uses_framework('CoreMotion')
  end
end


================================================
FILE: lib/bubble-wrap/network-indicator.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("network-indicator") do
  BubbleWrap.require('motion/core/app.rb')
  BubbleWrap.require('motion/network-indicator/**/*.rb')
end


================================================
FILE: lib/bubble-wrap/reactor.rb
================================================
require 'bubble-wrap/loader'

BW.require 'motion/reactor.rb'
BW.require 'motion/reactor/**/*.rb' do
  file('motion/reactor.rb').depends_on Dir.glob('motion/reactor/**/*.rb')
  file('motion/reactor/timer.rb').depends_on 'motion/reactor/eventable.rb'
  file('motion/reactor/periodic_timer.rb').depends_on 'motion/reactor/eventable.rb'
  file('motion/reactor/deferrable.rb').depends_on ['motion/reactor/timer.rb', 'motion/reactor/future.rb']
  file('motion/reactor/default_deferrable.rb').depends_on 'motion/reactor/deferrable.rb'
end


================================================
FILE: lib/bubble-wrap/requirement/path_manipulation.rb
================================================
module BubbleWrap
  class Requirement
    module PathManipulation

      def convert_caller_to_root_path(path)
        path = convert_caller_to_path path
        path = convert_to_absolute_path path
        strip_up_to_last_lib path
      end

      def convert_caller_to_path(string)
        chunks = string.split(':')
        if chunks.size >= 3
          string = chunks[0..-3].join(':')
          string = File.dirname(string)
        end
        string
      end

      def convert_to_absolute_path(path)
        File.expand_path(path)
      end

      def strip_up_to_last_lib(path)
        if path =~ /\/lib$/
          path = path.gsub(/\/lib$/, "")
        else
          path = path.split('lib')
          path = if path.size > 1
                   path[0..-2].join('lib')
                 else
                   path[0]
                 end
          path = path[0..-2] if path[-1] == '/'
        end
        path
      end

      def convert_to_relative(path,root)
        path = path.gsub(root,'')
        path = path[1..-1] if path[0] == '/'
        path
      end

    end
  end
end


================================================
FILE: lib/bubble-wrap/requirement.rb
================================================
require 'bubble-wrap/requirement/path_manipulation'

module BubbleWrap
  class Requirement
    extend PathManipulation
    include PathManipulation

    attr_accessor :file, :root
    attr_writer :file_dependencies

    def initialize(file,root)
      self.file = file
      self.root = root
    end

    def relative
      convert_to_relative(file, root)
    end

    def depends_on(file_or_paths)
      paths = file_or_paths.respond_to?(:each) ? file_or_paths : [ file_or_paths ]
      self.file_dependencies += paths.map do |f|
        f = self.class.file(f) unless f.is_a? Requirement
        f unless f.file == file
      end.compact
      self.file_dependencies.uniq!(&:to_s)
    end

    def uses_framework(framework_name)
      self.frameworks << framework_name
    end

    def dependencies
      return {} if file_dependencies.empty?
      { file => file_dependencies.map(&:to_s) }
    end

    def to_s
      file
    end

    def file_dependencies
      @file_dependencies ||= []
    end

    def frameworks
      @frameworks ||= []
    end

    class << self

      attr_accessor :paths

      def scan(caller_location, file_spec, &block)
        root = convert_caller_to_root_path caller_location
        self.paths ||= {}
        Dir.glob(File.expand_path(file_spec, root)).each do |file|
          p = new(file,root)
          self.paths[p.relative] = p
          p.depends_on('motion/shortcut.rb') unless p.relative == 'motion/shortcut.rb'
        end
        self.class_eval(&block) if block
      end

      def file(relative)
        paths.fetch(relative)
      end

      def files(app_files=nil)
        files = paths.values.map(&:to_s)
        files += app_files if app_files
        files.uniq
      end

      def clear!
        paths.select! { |k,v| v.relative == 'motion/shortcut.rb' }
      end

      def files_dependencies
        deps = {}
        paths.each_value do |file|
          deps.merge! file.dependencies
        end
        deps
      end

      def frameworks(app_frameworks=nil)
        frameworks = ['Foundation', 'CoreGraphics'] +
          paths.values.map(&:frameworks)
        frameworks += app_frameworks if app_frameworks
        frameworks.flatten.compact.sort.uniq
      end

    end
  end
end


================================================
FILE: lib/bubble-wrap/rss_parser.rb
================================================
require 'bubble-wrap/loader'
BubbleWrap.require('motion/rss_parser.rb')


================================================
FILE: lib/bubble-wrap/sms.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("sms") do
  BubbleWrap.require('motion/core/app.rb')
  BubbleWrap.require('motion/sms/**/*.rb') do
    file('motion/sms/sms.rb').depends_on('motion/sms/result.rb')
    file('motion/sms/sms.rb').uses_framework('MessageUI')
  end
end


================================================
FILE: lib/bubble-wrap/test.rb
================================================
require 'webstub'
require 'bubble-wrap/loader'
BW.require 'motion/util/*.rb'
BW.require 'motion/test_suite_delegate.rb'

Motion::Project::App.setup do |app|
  app.development do
    if Motion::Project::App.osx?
      app.delegate_class = 'TestSuiteOSXDelegate'
    else
      app.delegate_class = 'TestSuiteDelegate'
    end
  end
end


================================================
FILE: lib/bubble-wrap/ui.rb
================================================
require 'bubble-wrap/loader'

BubbleWrap.require_ios("ui") do
  BubbleWrap.require('motion/util/constants.rb')
  BubbleWrap.require('motion/ui/**/*.rb') do
    file('motion/ui/pollute.rb').depends_on %w(
      motion/ui/ui_control_wrapper.rb
      motion/ui/ui_view_wrapper.rb
      motion/ui/ui_view_controller_wrapper.rb
    )
  end
end


================================================
FILE: lib/bubble-wrap/version.rb
================================================
module BubbleWrap
  VERSION = '1.9.7' unless defined?(BubbleWrap::VERSION)
  MIN_MOTION_VERSION = '3.12'
end


================================================
FILE: lib/bubble-wrap.rb
================================================
require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)
require File.expand_path('../bubble-wrap/core', __FILE__)


================================================
FILE: motion/core/app.rb
================================================
# Provides a module to store global states
#
module BubbleWrap
  module App
    include BubbleWrap::Deprecated

    module_function

    # Returns the application's document directory path where users might be able to upload content.
    # @return [String] the path to the document directory
    def documents_path
      NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
    end

    # Returns the application resource path where resource located
    # @return [String] the application main bundle resource path
    def resources_path
      NSBundle.mainBundle.resourcePath
    end

    # Returns the default notification center
    # @return [NSNotificationCenter] the default notification center
    def notification_center
      NSNotificationCenter.defaultCenter
    end

    def user_cache
      NSUserDefaults.standardUserDefaults
    end
    deprecated :user_cache, "2.0.0"

    # Executes a block after a certain delay
    # Usage example:
    #   App.run_after(0.5) {  p "It's #{Time.now}"   }
    def run_after(delay,&block)
      NSTimer.scheduledTimerWithTimeInterval( delay,
                                              target: block,
                                              selector: "call:",
                                              userInfo: nil,
                                              repeats: false)
    end

    @states = {}

    def states
      @states
    end

    def info_plist
      NSBundle.mainBundle.infoDictionary
    end

    def name
      info_plist['CFBundleDisplayName']
    end

    def identifier
      NSBundle.mainBundle.bundleIdentifier
    end

    def version
      info_plist['CFBundleVersion']
    end

    def short_version
      info_plist['CFBundleShortVersionString']
    end

    # @return [NSLocale] locale of user settings
    def current_locale
      languages = NSLocale.preferredLanguages
      if languages.count > 0
        return NSLocale.alloc.initWithLocaleIdentifier(languages.first)
      else
        return NSLocale.currentLocale
      end
    end

    # the current application environment : development, test, release
    def environment
      RUBYMOTION_ENV
    end

    def development?
      environment == 'development'
    end

    def test?
      environment == 'test'
    end

    def release?
      environment == 'release'
    end

    def osx?
      Kernel.const_defined?(:NSApplication)
    end

    def ios?
      Kernel.const_defined?(:UIApplication)
    end
  end

end
::App = BubbleWrap::App unless defined?(::App)


================================================
FILE: motion/core/device/ios/camera.rb
================================================
# Provides a nice DSL for interacting with the standard
# UIImagePickerController
#
module BubbleWrap
  module Device
    class Camera
      module Error
        SOURCE_TYPE_NOT_AVAILABLE=0
        INVALID_MEDIA_TYPE=1
        MEDIA_TYPE_NOT_AVAILABLE=2
        INVALID_CAMERA_LOCATION=3
        CANCELED=1000
      end

      Constants.register UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeCamera,
          UIImagePickerControllerSourceTypeSavedPhotosAlbum

      Constants.register UIImagePickerControllerQualityTypeHigh,
          UIImagePickerControllerQualityTypeMedium,
          UIImagePickerControllerQualityTypeLow,
          UIImagePickerControllerQualityType640x480,
          UIImagePickerControllerQualityTypeIFrame1280x720,
          UIImagePickerControllerQualityTypeIFrame960x540

      MEDIA_TYPE_HASH = {movie: KUTTypeMovie, image: KUTTypeImage}

      CAMERA_LOCATIONS = [:front, :rear, :none]

      # The camera location; if :none, then we can't use source_type: :camera
      # in #picture
      # [:front, :rear, :none]
      attr_accessor :location

      def self.front
        return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
        @front ||= Camera.new(:front)
      end

      def self.rear
        return nil if not UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
        @rear ||= Camera.new(:rear)
      end

      def self.available?
        UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceTypeCamera)
      end

      # For uploading photos from the library.
      class << self
        def any
          @any ||= Camera.new
        end
        alias_method "photo_library", "any"
      end

      def popover_from(view)
        @popover_in_view = view
        self
      end

      def initialize(location = :none)
        self.location = location
      end

      def location=(location)
        if not CAMERA_LOCATIONS.member? location
          raise Error::INVALID_CAMERA_LOCATION, "#{location} is not a valid camera location"
        end
        @location = location
      end

      def flash?
        return false if self.location == :none
        UIImagePickerController.isFlashAvailableForCameraDevice(camera_device)
      end

      # @param [Hash] options to open the UIImagePickerController with
      # the form {
      #   source_type: :photo_library, :camera, or :saved_photos_album; default :photo_library
      #   media_types: [] containing :image and/or :movie; default [:image]
      #   allows_editing: true/false; default false
      #   animated: true/false; default true
      #   on_dismiss: lambda; default nil
      # }
      #
      # @param [UIViewController] view controller from which to present the image picker;
      #   if nil, uses the keyWindow's rootViewController.
      #
      # @block for callback. takes one argument.
      #   - On error or cancelled, is called with a hash {error: BW::Camera::Error::<Type>}
      #   - On success, is called with a hash with a possible set of keys
      #   [:media_type, :original_image, :edited_image, :crop_rect, :media_url,
      #    :reference_url, :media_metadata]
      #
      # Example
      # BW::Camera.picture(source_type: :photo_library, media_types: [:image]) do |result|
      #   image_view = UIImageView.alloc.initWithImage(result[:original_image])
      # end
      def picture(options = {}, presenting_controller = nil, &block)
        @callback = block
        @callback.weak! if @callback && BubbleWrap.use_weak_callbacks?

        @options = {
          allows_editing: false,
          animated: true,
          on_dismiss: false,
          media_types: [:image],
          dismiss_completed: nil,
          video_quality: :medium,
          video_maximum_duration: 600
        }.merge(options)

        # If we're using Camera.any, by default use photo library
        if !@options.has_key?(:source_type) and self.location == :none
          @options[:source_type] = :photo_library
        # If we're using a real Camera, by default use the camera.
        elsif !@options.has_key?(:source_type)
          @options[:source_type] = :camera
        end

        source_type_readable = options[:source_type]
        source_type = Constants.get("UIImagePickerControllerSourceType", @options[:source_type])
        if not Camera.source_type_available?(source_type)
          error(Error::SOURCE_TYPE_NOT_AVAILABLE) and return
        end

        media_types = @options[:media_types].collect { |mt| symbol_to_media_type(mt) }
        if media_types.member? nil
          error(Error::INVALID_MEDIA_TYPE) and return
        end

        media_types.each { |media_type|
          if not Camera.media_type_available?(media_type, for_source_type: source_type)
            error(Error::MEDIA_TYPE_NOT_AVAILABLE) and return
          end
        }

        self.picker.delegate = self
        self.picker.sourceType = source_type
        self.picker.mediaTypes = media_types
        self.picker.allowsEditing = @options[:allows_editing]
        self.picker.videoQuality = Constants.get("UIImagePickerControllerQualityType", @options[:video_quality])
        self.picker.videoMaximumDuration = @options[:video_maximum_duration]

        if source_type_readable == :camera && ![:front, :rear].member?(self.location)
          raise Error::INVALID_CAMERA_LOCATION, "Can't use camera location #{self.location} with source type :camera"
        end

        if source_type_readable == :camera
          self.picker.cameraDevice = camera_device
        end

        presenting_controller ||= App.window.rootViewController.presentedViewController # May be nil, but handles use case of container views
        presenting_controller ||= App.window.rootViewController

        # use popover for iPad (ignore on iPhone)
        if Device.ipad? and source_type==UIImagePickerControllerSourceTypePhotoLibrary and @popover_in_view
          @popover = UIPopoverController.alloc.initWithContentViewController(picker)
          @popover.presentPopoverFromRect(@popover_in_view.bounds, inView:@popover_in_view, permittedArrowDirections:UIPopoverArrowDirectionAny, animated:@options[:animated])
        else
          presenting_controller.presentViewController(self.picker, animated:@options[:animated], completion: lambda {})
        end
      end

      # iPad popover is dismissed
      def popoverControllerDidDismissPopover(popoverController)
        @popover = nil
      end

      ##########
      # UIImagePickerControllerDelegate Methods
      def imagePickerControllerDidCancel(picker)
        error(Error::CANCELED)
        dismiss
      end

      # Takes the default didFinishPickingMediaWithInfo hash,
      # transforms the keys to be nicer symbols of :this_form
      # instead of UIImagePickerControllerThisForm, and then sends it
      # to the callback
      def imagePickerController(picker, didFinishPickingMediaWithInfo: info)
        callback_info = {}

        info.keys.each { |k|
          nice_key = k.gsub("UIImagePickerController", "").underscore.to_sym
          val = info[k]
          callback_info[nice_key] = val
        }

        if media_type = callback_info[:media_type]
          callback_info[:media_type] = media_type_to_symbol(media_type)
        end

        @callback.call(callback_info)
        dismiss
        # iPad popover? close it
        if @popover
          @popover.dismissPopoverAnimated(@options[:animated])
          @popover = nil
        end
      end

      ##########
      # Short Helper Methods
      def picker
        @picker_klass ||= UIImagePickerController
        @picker ||= @picker_klass.alloc.init
      end

      def dismiss
        if @options[:on_dismiss]
          @options[:on_dismiss].call(self.picker)
          return
        end

        self.picker.dismissViewControllerAnimated(@options[:animated], completion: @options[:dismiss_completed])
      end

      # @param [UIImagePickerControllerSourceType] source_type to check
      def self.source_type_available?(source_type)
        UIImagePickerController.isSourceTypeAvailable(source_type)
      end

      # @param [String] (either KUTTypeMovie or KUTTypeImage)
      # @param [UIImagePickerControllerSourceType]
      def self.media_type_available?(media_type, for_source_type: source_type)
        UIImagePickerController.availableMediaTypesForSourceType(source_type).member? media_type
      end

      private
      def camera_device
        Constants.get("UIImagePickerControllerCameraDevice", self.location)
      end

      # ex media_type_to_symbol(KUTTypeMovie) => :movie
      def media_type_to_symbol(media_type)
        MEDIA_TYPE_HASH.invert[media_type]
      end

      # ex symbol_to_media_type(:movie) => :KUTTypeMovie
      def symbol_to_media_type(symbol)
        MEDIA_TYPE_HASH[symbol]
      end

      def error(type)
        @callback.call({ error: type })
      end
    end
  end
end
::Camera = BubbleWrap::Device::Camera unless defined?(::Camera)


================================================
FILE: motion/core/device/ios/camera_wrapper.rb
================================================
module BubbleWrap
  module Device
    module CameraWrapper

      module_function

      # The front-facing camera used to capture media
      # @return [Device::Camera, NilClass] a Camera will be returned if there is a front camera, nil otherwise
      def front
        @front ||= BubbleWrap::Device::Camera.front
      end

      # Verifies that the device running has a front facing camera.
      # @return [TrueClass, FalseClass] true will be returned if the device has a front facing camera, false otherwise.
      def front?
        !!front
      end

      # The rear-facing camera used to capture media
      # @return [Device::Camera, NilClass] a Camera will be returned if there is a rear camera, nil otherwise
      def rear
        @rear ||= BubbleWrap::Device::Camera.rear
      end

      # Verifies that the device running has a rear facing camera.
      # @return [TrueClass, FalseClass] true will be returned if the device has a rear facing camera, false otherwise.
      def rear?
        !!rear
      end

      # A Device::Camera used to capture media; by default it will use the :photo_library source type
      # See Device::Camera docs for more source type options.
      # @return [Device::Camera] a Camera will always be returned.
      def any
        @any ||= BubbleWrap::Device::Camera.any
      end
      # alias for any
      def photo_library
        any
      end

      # Should always return true, since picking images from *some* source is always possible
      # @return [TrueClass]
      def any?
        !!any
      end

      # Verifies that the device running has a physical camera.
      # @return [TrueClass, FalseClass] true will be returned if the device has a physical camera, false otherwise.
      def available?
        BubbleWrap::Device::Camera.available?
      end
    end
  end
end


================================================
FILE: motion/core/device/ios/screen.rb
================================================
module BubbleWrap
  module Device
    module Screen

      module_function

      # Certifies that the device running the app has a Retina display
      # @return [TrueClass, FalseClass] true will be returned if the device has a Retina display, false otherwise.
      def retina?(screen=UIScreen.mainScreen)
        if screen.respondsToSelector('displayLinkWithTarget:selector:') && screen.scale == 2.0
          true
        else
          false
        end
      end

      # Figure out the current physical orientation of the device
      # @return [:portrait, :portrait_upside_down, :landscape_left, :landscape_right, :face_up, :face_down, :unknown]
      def orientation(device_orientation=UIDevice.currentDevice.orientation, fallback=true)
        case device_orientation
        when UIDeviceOrientationPortrait then :portrait
        when UIDeviceOrientationPortraitUpsideDown then :portrait_upside_down
        when UIDeviceOrientationLandscapeLeft then :landscape_left
        when UIDeviceOrientationLandscapeRight then :landscape_right
        when UIDeviceOrientationFaceUp then :face_up
        when UIDeviceOrientationFaceDown then :face_down
        else
          # In some cases, the accelerometer can't get an accurate read of orientation so we fall back on the orientation of
          # the status bar.
          if fallback && (device_orientation != UIApplication.sharedApplication.statusBarOrientation)
            orientation(UIApplication.sharedApplication.statusBarOrientation)
          else
            :unknown
          end
        end
      end

      # Figure out the current orientation of the interface
      # @return [:portrait, :portrait_upside_down, :landscape_left, :landscape_right]
      def interface_orientation(device_orientation=UIDevice.currentDevice.orientation, fallback=true)
        case device_orientation
        when UIInterfaceOrientationPortrait then :portrait
        when UIInterfaceOrientationPortraitUpsideDown then :portrait_upside_down
        when UIInterfaceOrientationLandscapeLeft then :landscape_left
        when UIInterfaceOrientationLandscapeRight then :landscape_right
        else
          # In some cases, the accelerometer can't get an accurate read of orientation so we fall back on the orientation of
          # the status bar.
          if fallback && (device_orientation != UIApplication.sharedApplication.statusBarOrientation)
            orientation(UIApplication.sharedApplication.statusBarOrientation)
          else
            :unknown
          end
        end
      end

      # The width of the device's screen.
      # The real resolution is dependant on the scale
      # factor (see `retina?`) but the coordinate system
      # is in non-retina pixels. You can get pixel
      # accuracy by using half-coordinates.
      # This is a Float
      def width
        UIScreen.mainScreen.bounds.size.width
      end

      # The height of the device's screen.
      # The real resolution is dependant on the scale
      # factor (see `retina?`) but the coordinate system
      # is in non-retina pixels. You can get pixel
      # accuracy by using half-coordinates.
      # This is a Float
      def height
        UIScreen.mainScreen.bounds.size.height
      end

      # The same as `.width` and `.height` but
      # compensating for screen rotation (which
      # can do your head in).
      def width_for_orientation(o=orientation)
        return height if (o == :landscape_left) || (o == :landscape_right)
        width
      end

      # The same as `.width` and `.height` but
      # compensating for screen rotation (which
      # can do your head in).
      def height_for_orientation(o=orientation)
        return width if (o == :landscape_left) || (o == :landscape_right)
        height
      end
    end
  end
end


================================================
FILE: motion/core/device/osx/screen.rb
================================================
module BubbleWrap
  module Device
    module Screen

      module_function

      # Certifies that the device running the app has a Retina display
      # @return [TrueClass, FalseClass] true will be returned if the device has a Retina display, false otherwise.
      def retina?(screen=NSScreen.mainScreen)
        if screen.respondsToSelector('backingScaleFactor') && screen.backingScaleFactor == 2.0
          true
        else
          false
        end
      end
    end
  end
end


================================================
FILE: motion/core/device/screen.rb
================================================
module BubbleWrap
  module Device
    module Screen

    end
  end
end


================================================
FILE: motion/core/device.rb
================================================
module BubbleWrap
  module Device
    module_function

    # Shameless shorthand for accessing BubbleWrap::Screen
    def screen
      BubbleWrap::Device::Screen
    end

    # Delegates to BubbleWrap::Screen.retina?
    def retina?
      screen.retina?
    end
  end
end
::Device = BubbleWrap::Device unless defined?(::Device)


================================================
FILE: motion/core/ios/app.rb
================================================
module BubbleWrap
  module App
    module_function

    # Opens an url (string or instance of `NSURL`)
    # in the device's web browser or in the correspondent app for custom schemas
    # Usage Example:
    #   App.open_url("http://matt.aimonetti.net")
    #   App.open_url("fb://profile")
    def open_url(url)
      unless url.is_a?(NSURL)
        url = NSURL.URLWithString(url)
      end
      UIApplication.sharedApplication.openURL(url)
    end

    # Returns whether an app can open a given URL resource (string or instance of `NSURL`)
    # Useful to check if certain apps are installed before calling to their custom schemas.
    # Usage Example:
    #   App.open_url("fb://profile") if App.can_open_url("fb://")
    def can_open_url(url)
      unless url.is_a?(NSURL)
        url = NSURL.URLWithString(url)
      end
      UIApplication.sharedApplication.canOpenURL(url)
    end

    # Displays a UIAlertView.
    #
    # title - The title as a String.
    # args  - The title of the cancel button as a String, or a Hash of options.
    #         (Default: { cancel_button_title: 'OK' })
    #         cancel_button_title - The title of the cancel button as a String.
    #         message             - The main message as a String.
    # block - Yields the alert object if a block is given, and does so before the alert is shown.
    #
    # Returns an instance of BW::UIAlertView
    def alert(title, *args, &block)
      options = { cancel_button_title: 'OK' }
      options.merge!(args.pop) if args.last.is_a?(Hash)

      if args.size > 0 && args.first.is_a?(String)
        options[:cancel_button_title] = args.shift
      end

      options[:title]               = title
      options[:buttons]             = options[:cancel_button_title]
      options[:cancel_button_index] = 0 # FIXME: alerts don't have "Cancel" buttons

      alert = UIAlertView.default(options)

      yield(alert) if block_given?

      alert.show
      alert
    end

    # Return application frame
    def frame
      UIScreen.mainScreen.applicationFrame
    end

    # Main Screen bounds. Useful when starting the app
    def bounds
      UIScreen.mainScreen.bounds
    end

    # Application Delegate
    def delegate
      UIApplication.sharedApplication.delegate
    end

    # the Application object.
    def shared
      UIApplication.sharedApplication
    end

    def windows
      UIApplication.sharedApplication.windows
    end

    # the Application Window
    def window
      normal_windows = App.windows.select { |w|
        w.windowLevel == UIWindowLevelNormal
      }

      key_window = normal_windows.select {|w|
        w == UIApplication.sharedApplication.keyWindow
      }.first

      key_window || normal_windows.first
    end
  end
end


================================================
FILE: motion/core/ios/device.rb
================================================
module BubbleWrap
  module Device
    module_function

    # Verifies that the device running the app is an iPhone.
    # @return [TrueClass, FalseClass] true will be returned if the device is an iPhone, false otherwise.
    def iphone?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
      idiom == UIUserInterfaceIdiomPhone
    end

    # Verifies that the device running the app is an iPad.
    # @return [TrueClass, FalseClass] true will be returned if the device is an iPad, false otherwise.
    def ipad?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
      idiom == UIUserInterfaceIdiomPad
    end

    # Verifies that the device having a long screen (4 inch iPhone/iPod)
    # @return [TrueClass, FalseClass] true will be returned if the device is an iPhone/iPod with 4 inche screen, false otherwise.
    def long_screen?(idiom=UIDevice.currentDevice.userInterfaceIdiom, screen_height=UIScreen.mainScreen.bounds.size.height)
      iphone?(idiom) && screen_height == 568.0
    end

    # Use this to make a DSL-style call for picking images
    # @example Device.camera.front
    # @return [Device::Camera::CameraWrapper]
    def camera
      BubbleWrap::Device::CameraWrapper
    end

    # Verifies that the device running has a front facing camera.
    # @return [TrueClass, FalseClass] true will be returned if the device has a front facing camera, false otherwise.
    def front_camera?(picker=UIImagePickerController)
      p "This method (front_camera?) is DEPRECATED. Transition to using Device.camera.front?"
      picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceFront)
    end

    # Verifies that the device running has a rear facing camera.
    # @return [TrueClass, FalseClass] true will be returned if the device has a rear facing camera, false otherwise.
    def rear_camera?(picker=UIImagePickerController)
      p "This method (rear_camera?) is DEPRECATED. Transition to using Device.camera.rear?"
      picker.isCameraDeviceAvailable(UIImagePickerControllerCameraDeviceRear)
    end

    # Return whether app is being run in simulator
    # @return [TrueClass, FalseClass] true will be returned if simulator, false otherwise.
    def simulator?
      @simulator_state ||= begin
        if ios_version.to_i >= 9
          NSBundle.mainBundle.bundlePath !~ /^(\/private)?\/var/
        else
          !(UIDevice.currentDevice.model =~ /simulator/i).nil?
        end
      end
    end

    def force_touch?
      if defined?(UIForceTouchCapabilityAvailable) && defined?(UIScreen.mainScreen.traitCollection) && defined?(UIScreen.mainScreen.traitCollection.forceTouchCapability)
        UIScreen.mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable
      else
        false
      end
    end

    # Returns the IOS SDK version currently running (i.e. "5.1" or "6.0" etc)
    # @return [String] the IOS SDK version currently running
    def ios_version
      UIDevice.currentDevice.systemVersion
    end

    # Returns an identifier unique to the vendor across the vendors app.
    # @return [NSUUID]
    def vendor_identifier
      UIDevice.currentDevice.identifierForVendor
    end

    # Delegates to BubbleWrap::Screen.orientation
    def orientation
      screen.orientation
    end

    # Delegates to BubbleWrap::Screen.interface_orientation
    def interface_orientation
      screen.interface_orientation
    end
  end
end


================================================
FILE: motion/core/ios/ns_index_path.rb
================================================
module NSIndexPathWrap

  def +(aNumber)
    self.class.indexPathForRow(row+aNumber, inSection:section)
  end

  def -(aNumber)
    self.class.indexPathForRow(row-aNumber, inSection:section)
  end

end


================================================
FILE: motion/core/json.rb
================================================
module BubbleWrap

  # Handles JSON encoding and decoding in a similar way Ruby 1.9 does.
  module JSON

    class ParserError < StandardError; end

    # Parses a string or data object and converts it in data structure.
    #
    # @param [String, NSData] str_data the string or data to serialize.
    # @raise [ParserError] If the parsing of the passed string/data isn't valid.
    # @return [Hash, Array, NilClass] the converted data structure, nil if the incoming string isn't valid.
    #
    # TODO: support options like the C Ruby module does
    def self.parse(str_data, &block)
      return nil unless str_data
      data = str_data.respond_to?('dataUsingEncoding:') ? str_data.dataUsingEncoding(NSUTF8StringEncoding) : str_data
      opts = NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves | NSJSONReadingAllowFragments
      error = Pointer.new(:id)
      obj = NSJSONSerialization.JSONObjectWithData(data, options:opts, error:error)
      raise ParserError, error[0].description if error[0]
      if block_given?
        yield obj
      else
        obj
      end

    end

    def self.generate(obj)
      NSJSONSerialization.dataWithJSONObject(obj, options:0, error:nil).to_str
    end

  end
end


================================================
FILE: motion/core/kvo.rb
================================================
# Usage example:
#
# class ExampleViewController < UIViewController
#     include BubbleWrap::KVO
#
#     def viewDidLoad
#         @label = UILabel.alloc.initWithFrame [[20,20],[280,44]]
#         @label.text = ""
#         view.addSubview @label
#
#         observe(@label, :text) do |old_value, new_value|
#             puts "Changed #{old_value} to #{new_value}"
#         end
#     end
#
# end
#
# @see https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177i
module BubbleWrap
  module KVO
    class Registry
      COLLECTION_OPERATIONS = [ NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement ]
      OPTION_MAP = {
        new: NSKeyValueChangeNewKey,
        old: NSKeyValueChangeOldKey
      }

      attr_reader :callbacks, :keys

      def initialize(value_keys = [:old, :new])
        @keys = value_keys.inject([]) do |acc, key|
          value_change_key = OPTION_MAP[key]

          if value_change_key.nil?
            raise RuntimeError, "Unknown value change key #{key}. Possible keys: #{OPTION_MAP.keys}"
          end

          acc << value_change_key
        end

        @callbacks = Hash.new do |hash, key|
          hash[key] = Hash.new do |subhash, subkey|
            subhash[subkey] = Array.new
          end
        end
      end

      def add(target, key_path, &block)
        return if target.nil? || key_path.nil? || block.nil?

        block.weak! if BubbleWrap.use_weak_callbacks?

        callbacks[target][key_path.to_s] << block
      end

      def remove(target, key_path)
        return if target.nil? || key_path.nil?

        key_path = key_path.to_s

        callbacks[target].delete(key_path)

        # If there no key_paths left for target, remove the target key
        if callbacks[target].empty?
          callbacks.delete(target)
        end
      end

      def registered?(target, key_path)
        callbacks[target].has_key? key_path.to_s
      end

      def remove_all
        callbacks.clear
      end

      def each_key_path
        callbacks.each do |target, key_paths|
          key_paths.each_key do |key_path|
            yield target, key_path
          end
        end
      end

      private

      def observeValueForKeyPath(key_path, ofObject: target, change: change, context: context)
        key_paths = callbacks[target] || {}
        blocks = key_paths[key_path] || []

        args = change.values_at(*keys)
        args << key_path

        blocks.each do |block|
          block.call(*args)
        end
      end
    end

    DEFAULT_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
    IMMIDEATE_OPTIONS = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial

    def observe(target = self, key_paths, &block)
      key_paths = [key_paths].flatten

      key_paths.each do |key_path|
        if not observers_registry.registered?(target, key_path)
          target.addObserver(observers_registry, forKeyPath:key_path, options:DEFAULT_OPTIONS, context:nil)
        end

        # Add block even if observer is registed, so multiplie blocks can be invoked.
        observers_registry.add(target, key_path, &block)
      end
    end

    def observe!(target = self, key_paths, &block)
      key_paths = [key_paths].flatten

      key_paths.each do |key_path|
        registered = immediate_observers_registry.registered?(target, key_path)

        immediate_observers_registry.add(target, key_path, &block)

        # We need to first register the block, and then call addObserver, because
        # observeValueForKeyPath will fire immedeately.
        if not registered
          target.addObserver(immediate_observers_registry, forKeyPath:key_path, options: IMMIDEATE_OPTIONS, context:nil)
        end
      end
    end

    def unobserve(target = self, key_paths)
      remove_from_registry_if_exists(target, key_paths, observers_registry)
    end

    def unobserve!(target = self, key_paths)
      remove_from_registry_if_exists(target, key_paths, immediate_observers_registry)
    end

    def unobserve_all
      observers_registry.each_key_path do |target, key_path|
        target.removeObserver(observers_registry, forKeyPath:key_path)
      end

      immediate_observers_registry.each_key_path do |target, key_path|
        target.removeObserver(immediate_observers_registry, forKeyPath:key_path)
      end

      observers_registry.remove_all
      immediate_observers_registry.remove_all
    end

    private
    def observers_registry
      @observers_registry ||= Registry.new
    end

    def immediate_observers_registry
      @immediate_observers_registry ||= Registry.new([:new])
    end

    def remove_from_registry_if_exists(target, key_paths, registry)
      key_paths = [key_paths].flatten

      key_paths.each do |key_path|
        if registry.registered?(target, key_path)
          target.removeObserver(registry, forKeyPath:key_path)
          registry.remove(target, key_path)
        end
      end
    end
  end
end


================================================
FILE: motion/core/ns_index_path.rb
================================================
module NSIndexPathWrap

  # Gives access to an index at a given position.
  # @param [Integer] position to use to fetch the index
  # @return [Integer] the index for the given position
  def [](position)
    raise ArgumentError unless position.is_a?(Integer)
    indexAtPosition(position)
  end

  # Provides an iterator taking a block following the common Ruby idiom.
  # @param [Block]
  # @return [NSIndexPath] the iterated object itself
  def each
    i = 0
    until i == self.length
      yield self.indexAtPosition(i)
      i += 1
    end
    self
  end

end


================================================
FILE: motion/core/ns_notification_center.rb
================================================
class NSNotificationCenter
  def observers
    @observers ||= []
  end

  def observe(name, object=nil, &proc)
    proc.weak! if proc && BubbleWrap.use_weak_callbacks?
    observer = self.addObserverForName(name, object:object, queue:NSOperationQueue.mainQueue, usingBlock:proc)
    observers << observer
    observer
  end

  def unobserve(observer)
    return unless observers.include?(observer)
    removeObserver(observer)
    observers.delete(observer)
  end

  def post(name, object=nil, info=nil)
    self.postNotificationName(name, object: object, userInfo: info)
  end
end


================================================
FILE: motion/core/ns_url_request.rb
================================================
class NSURLRequest

  # Provides a to_s method so we can use inspect in instances and get
  # valuable information.
  def to_s
    "#<#{self.class}:#{self.object_id} - url: #{self.URL.description},
    headers: #{self.allHTTPHeaderFields.inspect},
    cache policy: #{self.cachePolicy}, Pipelining: #{self.HTTPShouldUsePipelining}, main doc url: #{mainDocumentURL},\
    timeout: #{self.timeoutInterval}, network service type: #{self.networkServiceType} >"
  end

end


================================================
FILE: motion/core/ns_user_defaults.rb
================================================
# Reopens the NSUserDefaults class to add Array like accessors
# @see https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html
class NSUserDefaults

  # Retrieves the object for the passed key
  def [](key)
    self.objectForKey(key.to_s)
  end

  # Sets the value for a given key and save it right away.
  def []=(key, val)
    self.setObject(val, forKey: key.to_s)
    self.synchronize
  end
end


================================================
FILE: motion/core/osx/app.rb
================================================
module BubbleWrap
  module App
    module_function

    # Opens an url (string or instance of `NSURL`)
    # in the default web browser
    # Usage Example:
    #   App.open_url("http://www.rubymotion.com")
    def open_url(url)
      url = NSURL.URLWithString(url) unless url.is_a?(NSURL)
      NSWorkspace.sharedWorkspace.openURL(url)
    end

    # Application Delegate
    def delegate
      shared.delegate
    end

    # the Application object.
    def shared
      NSApplication.sharedApplication
    end

  end
end


================================================
FILE: motion/core/osx/device.rb
================================================
module BubbleWrap
  module Device
    module_function

  end
end


================================================
FILE: motion/core/persistence.rb
================================================
# Persistence module built on top of NSUserDefaults
module BubbleWrap
  module Persistence
    module_function

    def app_key
      @app_key ||= BubbleWrap::App.identifier
    end

    def []=(key, value)
      storage.setObject(value, forKey: storage_key(key))
      storage.synchronize
    end

    def [](key)
      value = storage.objectForKey storage_key(key)

      # RubyMotion currently has a bug where the strings returned from
      # standardUserDefaults are missing some methods (e.g. to_data).
      # And because the returned object is slightly different than a normal
      # String, we can't just use `value.is_a?(String)`
      value.class.to_s == 'String' ? value.dup : value
    end

    def merge(values)
      values.each do |key, value|
        storage.setObject(value, forKey: storage_key(key))
      end
      storage.synchronize
    end

    def delete(key)
      value = storage.objectForKey storage_key(key)
      storage.removeObjectForKey(storage_key(key))
      storage.synchronize
      value
    end

    def storage
      NSUserDefaults.standardUserDefaults
    end

    def storage_key(key)
      "#{app_key}_#{key}"
    end

    def all
      hash = storage.dictionaryRepresentation.select{|k,v| k.start_with?(app_key) }
      new_hash = {}
      hash.each do |k,v|
        new_hash[k.sub("#{app_key}_", '')] = v
      end
      new_hash
    end
  end

end
::Persistence = BubbleWrap::Persistence unless defined?(::Persistence)


================================================
FILE: motion/core/pollute.rb
================================================
[
  [NSIndexPath, NSIndexPathWrap]
].each do |base, wrapper|
    base.send(:include, wrapper)
end


================================================
FILE: motion/core/string.rb
================================================
module BubbleWrap
  # This module contains simplified version of the `camelize` and
  # `underscore` methods from ActiveSupport, since these are such
  # common operations when dealing with the Cocoa API.
  module String

    # Convert 'snake_case' into 'CamelCase'
    def camelize(uppercase_first_letter = true)
      string = self.dup
      string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
        new_word = $2.downcase
        new_word[0] = new_word[0].upcase
        new_word = "/#{new_word}" if $1 == '/'
        new_word
      end
      if uppercase_first_letter && uppercase_first_letter != :lower
        string[0] = string[0].upcase
      else
        string[0] = string[0].downcase
      end
      string.gsub!('/', '::')
      string
    end

    # Convert 'CamelCase' into 'snake_case'
    def underscore
      word = self.dup
      word.gsub!(/::/, '/')
      word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
      word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
      word.tr!("-", "_")
      word.downcase!
      word
    end

    def to_url_encoded(encoding = nil, legacy = false)
      if legacy
        stringByAddingPercentEscapesUsingEncoding(encoding || NSUTF8StringEncoding)
      else
        encoding ||= KCFStringEncodingUTF8
        encoding = CFStringConvertNSStringEncodingToEncoding(encoding) unless CFStringIsEncodingAvailable(encoding)
        CFURLCreateStringByAddingPercentEscapes(nil, self, nil, "!*'();:@&=+$,/?%#[]", encoding)
      end
    end

    def to_url_decoded(encoding = nil, legacy = false)
      if legacy
        stringByReplacingPercentEscapesUsingEncoding(encoding || NSUTF8StringEncoding)
      else
        if encoding
          encoding = CFStringConvertNSStringEncodingToEncoding(encoding) unless CFStringIsEncodingAvailable(encoding)
          CFURLCreateStringByReplacingPercentEscapesUsingEncoding(nil, self, nil, encoding)
        else
          CFURLCreateStringByReplacingPercentEscapes(nil, self, nil)
        end
      end
    end

    def to_encoded_data(encoding = NSUTF8StringEncoding)
      dataUsingEncoding encoding
    end

    def to_color
      # First check if it is a color keyword
      keyword_selector = "#{self.camelize(:lower)}Color"
      color_klass = App.osx? ? NSColor : UIColor
      return color_klass.send(keyword_selector) if color_klass.respond_to? keyword_selector

      # Next attempt to convert from hex
      hex_color = self.gsub("#", "")
      case hex_color.size
        when 3
          colors = hex_color.scan(%r{[0-9A-Fa-f]}).map!{ |el| (el * 2).to_i(16) }
        when 6
          colors = hex_color.scan(%r<[0-9A-Fa-f]{2}>).map!{ |el| el.to_i(16) }
        when 8
          colors = hex_color.scan(%r<[0-9A-Fa-f]{2}>).map!{ |el| el.to_i(16) }
        else
          raise ArgumentError
      end
      if colors.size == 3
        BubbleWrap.rgb_color(colors[0], colors[1], colors[2])
      elsif colors.size == 4
        BubbleWrap.rgba_color(colors[1], colors[2], colors[3], colors[0])
      else
        raise ArgumentError
      end
    end

  end
end

NSString.send(:include, BubbleWrap::String)


================================================
FILE: motion/core/time.rb
================================================
class Time

  def self.iso8601(time)
    if time.include?(".")
      # Fractional Seconds
      if time.include?('Z')
        iso8601_with_fractional_seconds(time)
      else
        iso8601_with_fractional_seconds_and_timesone(time)
      end
    else
      # Non Fractional Seconds
      if time.include?('Z')
        iso8601_zulu(time)
      else
        iso8601_with_timezone(time)
      end
    end
  end

  def self.iso8601_zulu(time)
    cached_date_formatter("yyyy-MM-dd'T'HH:mm:ss'Z'").
      dateFromString(time)
  end

  def self.iso8601_with_timezone(time)
    cached_date_formatter("yyyy-MM-dd'T'HH:mm:ssZZZZZ").
      dateFromString(time)
  end

  def self.iso8601_with_fractional_seconds(time)
    cached_date_formatter("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").
      dateFromString(time)
  end

  def self.iso8601_with_fractional_seconds_and_timesone(time)
    cached_date_formatter("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ").
      dateFromString(time)
  end

  private

  def self.cached_date_formatter(dateFormat)
    Thread.current[:date_formatters] ||= {}
    Thread.current[:date_formatters][dateFormat] ||=
      NSDateFormatter.alloc.init.tap do |formatter|
        formatter.dateFormat = dateFormat
        formatter.timeZone   = NSTimeZone.timeZoneWithAbbreviation "UTC"
      end
  end

end


================================================
FILE: motion/core.rb
================================================
module BubbleWrap
  module_function

  # @return [UIcolor]
  def rgb_color(r,g,b)
    rgba_color(r,g,b,1)
  end

  # @return [UIcolor]
  def rgba_color(r,g,b,a)
    r,g,b = [r,g,b].map { |i| i / 255.0}
    if a > 1.0
      a = a / 255.0
    end
    if App.osx?
      NSColor.colorWithDeviceRed(r, green: g, blue: b, alpha: a)
    else
      UIColor.colorWithRed(r, green: g, blue:b, alpha:a)
    end
  end

  def localized_string(key, value=nil)
    NSBundle.mainBundle.localizedStringForKey(key, value:value, table:nil)
  end

  # I had issues with #p on the device, this is a temporary workaround
  def p(arg)
    NSLog arg.inspect
  end

  def create_uuid
    uuid = CFUUIDCreate(nil)
    CFUUIDCreateString(nil, uuid)
  end

end


================================================
FILE: motion/font/font.rb
================================================
module BubbleWrap
  module Font
    module_function

    def bold(size = nil)
      Font.new(:bold, size)
    end

    def system(size = nil)
      Font.new(:system, size)
    end

    def italic(size = nil)
      Font.new(:italic, size)
    end

    # Example
    # Font.new(<# UIFont >)
    # Font.new("Helvetica")
    # Font.new("Helvetica", 12)
    # Font.new("Helvetica", size: 12)
    # Font.new(name: "Helvetica", size: 12)
    def new(params = {}, *args)
      if params.is_a?(UIFont)
        return params
      end
      _font = nil

      if params.is_a?(NSString)
        params = {name: params}
      end

      if args && !args.empty?
        case args[0]
        when NSDictionary
          params.merge!(args[0])
        else
          params.merge!({size: args[0]})
        end
      end
      params[:size] ||= UIFont.systemFontSize

      case params[:name].to_sym
      when :system
        _font = UIFont.systemFontOfSize(params[:size].to_f)
      when :bold
        _font = UIFont.boldSystemFontOfSize(params[:size].to_f)
      when :italic
        _font = UIFont.italicSystemFontOfSize(params[:size].to_f)
      else
        begin
          _font = UIFont.fontWithName(params[:name], size: params[:size])
        rescue
        end
      end

      if !_font
        raise "Invalid font for parameters: #{params.inspect} args #{args.inspect}"
      end

      _font
    end

    class << self
      alias_method :named, :new
    end

    # I.e. for UINavigationBar#titleTextAttributes
    def attributes(params = {})
      _attributes = {}

      _attributes[UITextAttributeFont] = Font.new(params[:font]) if params[:font]
      _attributes[UITextAttributeTextColor] = params[:color].to_color if params[:color]
      _attributes[UITextAttributeTextShadowColor] = params[:shadow_color].to_color if params[:shadow_color]
      _attributes[UITextAttributeTextShadowOffset] = begin
        x = params[:shadow_offset][:x]
        y = params[:shadow_offset][:y]
        offset = UIOffsetMake(x,y)
        NSValue.valueWithUIOffset(offset)
      end if params[:shadow_offset]

      _attributes
    end
  end
end


================================================
FILE: motion/ios/8/location_constants.rb
================================================
module BW
  # New additions to CLAuthorizationStatus in ios8
  # see: https://developer.apple.com/library/prerelease/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/c/tdef/CLAuthorizationStatus
  Constants.register(
    KCLAuthorizationStatusAuthorized,
    KCLAuthorizationStatusAuthorizedWhenInUse,
    KCLAuthorizationStatusAuthorizedAlways
  )

  module Location
    module_function

    def authorized?
      [
        BW::Constants.get("KCLAuthorizationStatus", :authorized),
        BW::Constants.get("KCLAuthorizationStatus", :authorized_always),
        BW::Constants.get("KCLAuthorizationStatus", :authorized_when_in_use)
      ].include?(CLLocationManager.authorizationStatus)
    end
  end
end


================================================
FILE: motion/location/location.rb
================================================
# Provides a nice DSL for interacting with the standard
# CLLocationManager
#
module BubbleWrap
  module CLLocationWrap

    def latitude
      self.coordinate.latitude
    end

    def longitude
      self.coordinate.longitude
    end
  end

  module Location
    module Error
      DISABLED=0
      PERMISSION_DENIED=1
      NETWORK_FAILURE=2
      LOCATION_UNKNOWN=3
    end

    Constants.register KCLLocationAccuracyBestForNavigation, KCLLocationAccuracyBest,
        KCLLocationAccuracyNearestTenMeters, KCLLocationAccuracyHundredMeters,
        KCLLocationAccuracyKilometer, KCLLocationAccuracyThreeKilometers

    module_function
    # Start getting locations
    # @param [Hash] options = {
    #   authorization_type: :always/:when_in_use to trigger the type of authorization you want
    #     default == uses :always
    #   significant: true/false; whether to listen for significant location changes or
    #     all location changes (see Apple docs for info); default == false
    #   distance_filter:  minimum change in distance to be updated about, in meters;
    #     default == uses KCLDistanceFilterNone,
    #   desired_accuracy: minimum accuracy for updates to arrive;
    #     any of :best_for_navigation, :best, :nearest_ten_meters,
    #     :hundred_meters, :kilometer, or :three_kilometers; default == :best
    #   purpose: string to display when the system asks user for location,
    #   retries: if location cant be found. how many errors do we retry; default == 5
    #   calibration: if the OS should display the heading calibration to the user; default == false
    # }
    # @block for callback. takes one argument, `result`.
    #   - On error or cancelled, is called with a hash {error: BW::Location::Error::<Type>}
    #   - On success, is called with a hash {to: #<CLLocation>, from: #<CLLocation>, previous: [#<CLLocation>,...]}
    #   -- :previous will return an Array of CLLocation objects, ordered from oldest to newest, excluding the 
    #        locations :to and :from, returning an empty Array if no additional locations were provided
    #
    # Example
    # BW::Location.get(distance_filter: 10, desired_accuracy: :nearest_ten_meters) do |result|
    #   result[:to].class == CLLocation
    #   result[:from].class == CLLocation
    #   result[:previous].class == NSArray<CLLocation>
    #   p "Lat #{result[:to].latitude}, Long #{result[:to].longitude}"
    # end
    def get(options = {}, &block)
      @callback = block
      @callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
      @options = {
        authorization_type: :always,
        significant: false,
        distance_filter: KCLDistanceFilterNone,
        desired_accuracy: KCLLocationAccuracyBest,
        retries: 5,
        once: false,
        calibration: false
      }.merge(options)

      @options[:significant] = false if @options[:significant].nil?
      @retries = 0
      @from_location = nil

      if not enabled?
        error(Error::DISABLED) and return
      end

      self.location_manager

      if self.location_manager.respondsToSelector('requestAlwaysAuthorization')
        @options[:authorization_type] == :always ? self.location_manager.requestAlwaysAuthorization : self.location_manager.requestWhenInUseAuthorization
      end


      self.location_manager.distanceFilter = @options[:distance_filter]
      self.location_manager.desiredAccuracy = Constants.get("KCLLocationAccuracy", @options[:desired_accuracy])
      self.location_manager.purpose = @options[:purpose] if @options[:purpose]

      @initialized = true
      start
    end

    def get_significant(options = {}, &block)
      get(options.merge(significant: true), &block)
    end

    # Get the first returned location based on your options
    # @param [Hash] options = {
    #   significant: true/false; whether to listen for significant location changes or
    #     all location changes (see Apple docs for info); default == false
    #   distance_filter:  minimum change in distance to be updated about, in meters;
    #     default == uses KCLDistanceFilterNone,
    #   desired_accuracy: minimum accuracy for updates to arrive;
    #     any of :best_for_navigation, :best, :nearest_ten_meters,
    #     :hundred_meters, :kilometer, or :three_kilometers; default == :best
    #   purpose: string to display when the system asks user for location,
    #   retries: if location cant be found. how many errors do we retry; default == 5
    # }
    # @block for callback. takes one argument, `result`.
    #   - On error or cancelled, is called with a hash {error: BW::Location::Error::<Type>}
    #   - On success, it returns a CLLocation
    #
    #
    # Example
    # BW::Location.get_once(desired_accuracy: :three_kilometers, purpose: 'We need to use your GPS to show you how fun RM is') do |result|
    #   if result.is_a?(CLLocation)
    #     p "Lat #{result.latitude}, Long #{result.longitude}"
    #   else
    #     p "ERROR: #{result[:error]"
    #   end
    # end
    def get_once(options = {}, &block)
      get(options.merge(once: true), &block)
    end

    def get_compass(options = {}, &block)
      get(options.merge(compass: true), &block)
    end

    def get_compass_once(options = {}, &block)
      get_compass(options.merge(once: true), &block)
    end

    # Start getting locations
    def start
      return unless initialized?
      if @options[:significant]
        self.location_manager.startMonitoringSignificantLocationChanges
      elsif @options[:compass]
        self.location_manager.startUpdatingHeading
      else
        self.location_manager.startUpdatingLocation
      end
    end

    # Stop getting locations
    def stop
      return unless @options
      if @options[:significant]
        self.location_manager.stopMonitoringSignificantLocationChanges
      elsif @options[:compass]
        self.location_manager.stopUpdatingHeading
      else
        self.location_manager.stopUpdatingLocation
      end
    end

    def location_manager
      @location_manager ||= CLLocationManager.alloc.init
      @location_manager.delegate ||= self
      @location_manager
    end

    # returns true/false whether services, or limited services, are enabled for the _device_
    def enabled?
      CLLocationManager.locationServicesEnabled
    end

    # returns true/false if CLLocationManager has been initialized with the provided or default options
    def initialized?
      @initialized ||= false
    end

    # returns true/false whether services are enabled for the _app_
    def authorized?
      [
        BW::Constants.get("KCLAuthorizationStatus", :authorized)
      ].include?(CLLocationManager.authorizationStatus)
    end

    def error(type)
      @callback && @callback.call({ error: type })
      @callback = nil
      self.location_manager.stopUpdatingLocation
    end

    ##########
    # CLLocationManagerDelegate Methods
    def locationManager(manager, didUpdateLocations:locations)
      if @options[:once]
        @callback && @callback.call(locations.last)
        @callback = proc { |result| }
        stop
      else
        size = locations.count
        result = {to: locations.last, 
          from: ( (size > 1) ? locations.last(2).first : @from_location ), 
          previous: ( (size > 2) ? locations.first(size - 2) : [] )
        }
        @from_location = result[:to]
        @callback && @callback.call(result)
      end
    end

    def locationManager(manager, didUpdateHeading:newHeading)
      heading = {
        magnetic_heading: newHeading.magneticHeading,
        true_heading: newHeading.trueHeading,
        accuracy: newHeading.headingAccuracy,
        timestamp: newHeading.timestamp,
      }

      if @options[:once]
        @callback && @callback.call(heading)
        @callback = proc { |result| }
        stop
      else
        @callback && @callback.call(heading)
      end
    end

    def locationManager(manager, didFailWithError:error)
      if error.domain == KCLErrorDomain
        case error.code
        when KCLErrorDenied
          error(Error::PERMISSION_DENIED)
        when KCLErrorLocationUnknown
          # Docs specify that this is a temporary error,
          # so we stop/start updating to try again.
          @retries += 1
          if @retries > @options[:retries]
            error(Error::LOCATION_UNKNOWN)
          else
            stop
            start
          end
        when KCLErrorNetwork
          error(Error::NETWORK_FAILURE)
        end
      end
    end

    def locationManager(manager, didChangeAuthorizationStatus:status)
      case status
      when KCLAuthorizationStatusRestricted
        error(Error::PERMISSION_DENIED)
      when KCLAuthorizationStatusDenied
        error(Error::PERMISSION_DENIED)
      end
    end

    def locationManagerShouldDisplayHeadingCalibration(manager)
      @options[:calibration] ? @options[:calibration] : false
    end
  end
end
::Location = BubbleWrap::Location unless defined?(::Location)


================================================
FILE: motion/location/pollute.rb
================================================
[
  [CLLocation, BubbleWrap::CLLocationWrap],
].each do |base, wrapper|
    base.send(:include, wrapper)
end


================================================
FILE: motion/mail/mail.rb
================================================
module BubbleWrap
  module Mail

    module_function

    # Base method to create your in-app mail
    # ---------------------------------------
    # EX
    #   BW::Mail.compose(
    #     delegate: self, # optional, will use root view controller by default
    #     to: [ "tom@example.com" ],
    #     cc: [ "itchy@example.com", "scratchy@example.com" ],
    #     bcc: [ "jerry@example.com" ],
    #     html: false,
    #     subject: "My Subject",
    #     message: "This is my message. It isn't very long.",
    #     animated: false
    #   ) do |result, error|
    #     result.sent?      # => boolean
    #     result.canceled?  # => boolean
    #     result.saved?     # => boolean
    #     result.failed?    # => boolean
    #     error             # => NSError
    #   end
    def compose(options = {}, &callback)
      options = {
        delegate: App.window.rootViewController,
        animated: true,
        html: false,
        to: [],
        cc: [],
        bcc: [],
        subject: 'Contact'
      }.merge(options)

      @delegate = options[:delegate]
      @mailer_is_animated = options[:animated]
      @callback = callback
      @callback.weak! if @callback && BubbleWrap.use_weak_callbacks?

      @mail_controller = create_mail_controller(options)

      @delegate.presentViewController(@mail_controller, animated: @mailer_is_animated, completion: options[:completion])
    end

    def create_mail_controller(options = {})
      unless can_send_mail?
        controller = UIAlertController.alertControllerWithTitle("Email", message:"Cannot compose an email. Please run on device.", preferredStyle:UIAlertControllerStyleAlert)
        controller.addAction(UIAlertAction.actionWithTitle:"OK",style:UIAlertActionStyleDefault, handler:@callback)
        return controller
      end

      mail_controller = MFMailComposeViewController.alloc.init

      mail_controller.mailComposeDelegate = self
      mail_controller.setToRecipients(Array(options[:to]))
      mail_controller.setCcRecipients(Array(options[:cc]))
      mail_controller.setBccRecipients(Array(options[:bcc]))
      mail_controller.setSubject(options[:subject])
      mail_controller.setMessageBody(options[:message], isHTML: !!options[:html])

      mail_controller
    end

    def can_send_mail?
      !!MFMailComposeViewController.canSendMail
    end

    # Event when the MFMailComposeViewController is closed
    # -------------------------------------------------------------
    # the callback is fired if it was present in the constructor

    def mailComposeController(controller, didFinishWithResult: result, error: error)
      @delegate.dismissModalViewControllerAnimated(@mailer_is_animated)
      @callback.call Result.new(result, error) if @callback
    end
  end
end


================================================
FILE: motion/mail/result.rb
================================================
module BubbleWrap
  module Mail
    class Result
      attr_accessor :result, :error

      def initialize(result, error)
        self.result = result
        self.error = error
      end

      def sent?
        self.result == MFMailComposeResultSent
      end

      def canceled?
        self.result == MFMailComposeResultCancelled
      end

      def saved?
        self.result == MFMailComposeResultSaved
      end

      def failed?
        self.result == MFMailComposeResultFailed || self.error
      end

    end
  end
end


================================================
FILE: motion/media/media.rb
================================================
module BubbleWrap
  module Media
    module_function

    def play_modal(*args, &block)
      Media::Player.new.retain.send(:play_modal, *args, &block)
    end

    def play(*args, &block)
      Media::Player.new.retain.send(:play, *args, &block)
    end
  end
end

::Media = BubbleWrap::Media unless defined?(::Media)


================================================
FILE: motion/media/player.rb
================================================
module BubbleWrap
  module Media
    module Error
      class InvalidPlayerType < StandardError; end
      class NilPlayerCallback < StandardError; end
    end

    class Player
      attr_reader :media_player
      ############
      # Playing Media

      # Plays media in the system-default modal controller
      # Takes same parameters as #play
      # NOTE: If you don't supply a :controller option,
      # the rootViewController will be used.
      def play_modal(content_url, options = {})
        play(content_url, options.merge(modal: true))
      end

      # @param [String, NSURL] content_url is either a local or remote string
      #   for the location of the media you're playing.
      #   NOTE: if you're playing a remote file, your server needs to support
      #   range requests for that URL.
      #
      # @param [Hash] options to open the MPMoviePlayerController with
      # the form {
      #   ### These are properties of MPMoviePlayerController
      #   allows_air_play: true/false; default false,
      #   control_style: [MPMovieControlStyle]; default MPMovieControlStyleDefault,
      #   end_playback_time: [Integer] end time (in seconds) for media; default is -1,
      #   initial_playback_time: [Integer] start time (in seconds) for media; default is -1,
      #   movie_source_type: [MPMovieSourceType] a "hint" so the player knows how to load the data type;
      #     either MPMovieSourceTypeFile or MPMovieSourceTypeStreaming; default is MPMovieSourceTypeUnknown
      #     which may delay playback,
      #   repeat_mode: [MPMovieRepeatMode] how the player repeats at the end of playback; defautl is
      #     MPMovieRepeatModeNone
      #   scaling_mode: [MPMovieScalingMode] scaling mode for movies; default is MPMovieScalingModeAspectFit
      #   should_autoplay: true/false; default true,
      #   use_application_audio_session: true/false; default true.
      #
      #   ### These are properties of just the ::Player
      #   delay_play: true/false, default false. If false then you have to manually call
      #     @media_player.play in your code
      #   modal: true/false; default false,
      #   controller: [UIViewController] used to present the player modally;
      #     default uses root view controller of window
      # }
      #
      # @block for when setup is done; use this block to present
      #   @media_player.view if options[:modal] == false
      #
      # EX
      #  From a local URL:
      #    file = File.join(App.resources_path, 'test.mp3')
      #    BW::Media::Player.play(NSURL.fileURLWithPath(file)) do |media_player|
      #      media_player.view.frame = some_view.bounds
      #      self.view.addSubview media_player.view
      #    end
      #
      #  From a remote URL:
      #    BW::Media::Player.play("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3") do |media_player|
      #      media_player.view.frame = some_view.bounds
      #      self.view.addSubview media_player.view
      #    end
      def play(content_url, options = {}, &block)
        options = {
          delay_play: false
        }.merge(options)

        display_modal = !!options[:modal]

        klass = display_modal ? MPMoviePlayerViewController : MPMoviePlayerController

        content_url = content_url.is_a?(NSURL) ? content_url : NSURL.URLWithString(content_url)
        @media_player = klass.alloc.init

        self.media_player.prepareToPlay if not display_modal

        set_player_options(options)
        self.media_player.setContentURL(content_url)

        NSNotificationCenter.defaultCenter.observe MPMoviePlayerPlaybackDidFinishNotification do |notification|
          h = notification.userInfo
          error = h["error"]
          if error
            p "BW::Media::Player error: #{error.userInfo.inspect}"
            p "Code: #{error.code}, Domain: #{error.domain}"
          end
        end

        if display_modal
          @presenting_controller = options[:controller]
          @presenting_controller ||= App.window.rootViewController
          if Device.ios_version < "7.0"
            @presenting_controller.presentMoviePlayerViewControllerAnimated(@media_player)
          else
            @presenting_controller.presentViewController(@media_player, animated:true, completion:nil)
          end
        else
          if block.nil?
            raise Error::NilPlayerCallback, "no block callback given in #play; you need\
                                              to supply one if options[:modal] == false"
          end
          block.call(@media_player)
        end

        if not display_modal and not options[:delay_play]
          @media_player.play
        end
      end

      # Stops playback for a Media::Player
      def stop
        if @media_player.is_a? MPMoviePlayerViewController
          if Device.ios_version < "7.0"
            @presenting_controller.dismissMoviePlayerViewControllerAnimated
          else
            @presenting_controller.dismissViewControllerAnimated(true, completion:nil)
          end
          @presenting_controller = nil
        else
          @media_player.stop
        end
        @media_player = nil
      end

      def media_player
        if @media_player.is_a? MPMoviePlayerViewController
          return @media_player.moviePlayer
        end
        @media_player
      end

      private
      # RubyMotion has a problem calling some objective-c methods at runtime, so we can't
      # do any cool `camelize` tricks.
      def set_player_options(options)
        self.media_player.allowsAirPlay = options[:allows_air_play] if options.has_key? :allows_air_play
        self.media_player.controlStyle = options[:control_style] if options.has_key? :control_style
        self.media_player.endPlaybackTime = options[:end_playback_time] if options.has_key? :end_playback_time
        self.media_player.initialPlaybackTime = options[:initial_playback_time] if options.has_key? :initial_playback_time
        self.media_player.movieSourceType = options[:movie_source_type] if options.has_key? :movie_source_type
        self.media_player.repeatMode = options[:repeat_mode] if options.has_key? :repeat_mode
        self.media_player.scalingMode = options[:scaling_mode] if options.has_key? :scaling_mode
        self.media_player.shouldAutoplay = options[:should_autoplay] if options.has_key? :should_autoplay
        self.media_player.useApplicationAudioSession = options[:use_application_audio_session] if options.has_key? :use_application_audio_session
      end
    end
  end
end


================================================
FILE: motion/motion/accelerometer.rb
================================================
module BubbleWrap
  module Motion
    class Accelerometer < GenericMotionInterface

      def start(options={}, &handler)
        if options.key?(:interval)
          @manager.accelerometerUpdateInterval = options[:interval]
        end

        if handler
          queue = convert_queue(options[:queue])
          @manager.startAccelerometerUpdatesToQueue(queue, withHandler: internal_handler(handler))
        else
          @manager.startAccelerometerUpdates
        end

        return self
      end

      private def handle_result(result_data, error, handler)
        if result_data
          result = {
            data: result_data,
            acceleration: result_data.acceleration,
            x: result_data.acceleration.x,
            y: result_data.acceleration.y,
            z: result_data.acceleration.z,
          }
        else
          result = nil
        end

        handler.call(result, error)
      end

      def available?
        @manager.accelerometerAvailable?
      end

      def active?
        @manager.accelerometerActive?
      end

      def data
        @manager.accelerometerData
      end

      def stop
        @manager.stopAccelerometerUpdates
      end

    end

  end
end


================================================
FILE: motion/motion/device_motion.rb
================================================
module BubbleWrap
  module Motion
    class DeviceMotion < GenericMotionInterface

      def start(options={}, &handler)
        if options.key?(:interval)
          @manager.deviceMotionUpdateInterval = options[:interval]
        end

        if options.key?(:reference)
          reference_frame = convert_reference_frame(options[:reference])
        else
          reference_frame = nil
        end

        if handler
          queue = convert_queue(options[:queue])

          if reference_frame
              @manager.startDeviceMotionUpdatesUsingReferenceFrame(reference_frame, toQueue: queue, withHandler: internal_handler(handler))
          else
              @manager.startDeviceMotionUpdatesToQueue(queue, withHandler: internal_handler(handler))
          end
        else
          if reference_frame
            @manager.startDeviceMotionUpdatesUsingReferenceFrame(reference_frame)
          else
            @manager.startDeviceMotionUpdates
          end
        end

        return self
      end

      private def handle_result(result_data, error, handler)
        if result_data
          result = {
            data: result_data,
            attitude: result_data.attitude,
            rotation: result_data.rotationRate,
            gravity: result_data.gravity,
            acceleration: result_data.userAcceleration,
            magnetic: result_data.magneticField,
          }

          if result_data.attitude
            result.merge!({
              roll: result_data.attitude.roll,
              pitch: result_data.attitude.pitch,
              yaw: result_data.attitude.yaw,
              matrix: result_data.attitude.rotationMatrix,
              quaternion: result_data.attitude.quaternion,
            })
          end

          if result_data.rotationRate
            result.merge!({
              rotation_x: result_data.rotationRate.x,
              rotation_y: result_data.rotationRate.y,
              rotation_z: result_data.rotationRate.z,
            })
          end

          if result_data.gravity
            result.merge!({
              gravity_x: result_data.gravity.x,
              gravity_y: result_data.gravity.y,
              gravity_z: result_data.gravity.z,
            })
          end

          if result_data.userAcceleration
            result.merge!({
              acceleration_x: result_data.userAcceleration.x,
              acceleration_y: result_data.userAcceleration.y,
              acceleration_z: result_data.userAcceleration.z,
            })
          end

          if result_data.magneticField
            case result_data.magneticField.accuracy
            when CMMagneticFieldCalibrationAccuracyLow
              accuracy = :low
            when CMMagneticFieldCalibrationAccuracyMedium
              accuracy = :medium
            when CMMagneticFieldCalibrationAccuracyHigh
              accuracy = :high
            end

            result.merge!({
              field: result_data.magneticField.field,
              magnetic_x: result_data.magneticField.field.x,
              magnetic_y: result_data.magneticField.field.y,
              magnetic_z: result_data.magneticField.field.z,
              magnetic_accuracy: accuracy,
            })
          end
        else
          result = nil
        end

        handler.call(result, error)
      end

      def convert_reference_frame(reference_frame)
        case reference_frame
        when :arbitrary_z
          CMAttitudeReferenceFrameXArbitraryZVertical
        when :corrected_z
          CMAttitudeReferenceFrameXArbitraryCorrectedZVertical
        when :magnetic_north
          CMAttitudeReferenceFrameXMagneticNorthZVertical
        when :true_north
          CMAttitudeReferenceFrameXTrueNorthZVertical
        else
          reference_frame
        end
      end

      def available?
        @manager.deviceMotionAvailable?
      end

      def active?
        @manager.deviceMotionActive?
      end

      def data
        @manager.deviceMotion
      end

      def stop
        @manager.stopDeviceMotionUpdates
      end

    end

  end
end


================================================
FILE: motion/motion/gyroscope.rb
================================================
module BubbleWrap
  module Motion
    class Gyroscope < GenericMotionInterface

      def start(options={}, &handler)
        if options.key?(:interval)
          @manager.gyroUpdateInterval = options[:interval]
        end

        if handler
          queue = convert_queue(options[:queue])
          @manager.startGyroUpdatesToQueue(queue, withHandler: internal_handler(handler))
        else
          @manager.startGyroUpdates
        end

        return self
      end

      private def handle_result(result_data, error, handler)
        if result_data
          result = {
            data: result_data,
            rotation: result_data.rotationRate,
            x: result_data.rotationRate.x,
            y: result_data.rotationRate.y,
            z: result_data.rotationRate.z,
          }
        else
          result = nil
        end

        handler.call(result, error)
      end

      def available?
        @manager.gyroAvailable?
      end

      def active?
        @manager.gyroActive?
      end

      def data
        @manager.gyroData
      end

      def stop
        @manager.stopGyroUpdates
      end

    end

  end
end


================================================
FILE: motion/motion/magnetometer.rb
================================================
module BubbleWrap
  module Motion
    class Magnetometer < GenericMotionInterface

      def start(options={}, &handler)
        if options.key?(:interval)
          @manager.magnetometerUpdateInterval = options[:interval]
        end

        if handler
          queue = convert_queue(options[:queue])
          @manager.startMagnetometerUpdatesToQueue(queue, withHandler: internal_handler(handler))
        else
          @manager.startMagnetometerUpdates
        end

        return self
      end

      private def handle_result(result_data, error, handler)
        if result_data
          result = {
            data: result_data,
            field: result_data.magneticField,
            x: result_data.magneticField.x,
            y: result_data.magneticField.y,
            z: result_data.magneticField.z,
          }
        else
          result = nil
        end

        handler.call(result, error)
      end

      def available?
        @manager.magnetometerAvailable?
      end

      def active?
        @manager.magnetometerActive?
      end

      def data
        @manager.magnetometerData
      end

      def stop
        @manager.stopMagnetometerUpdates
      end

    end

  end
end


================================================
FILE: motion/motion/motion.rb
================================================
# Provides a nice DSL for interacting with the standard CMMotionManager from
# CoreMotion
module BubbleWrap
  # These module methods provide the main interface.  It uses a shared manager
  # (per Apple's recommendation), and they all have a common set of supported
  # methods:
  #     available?
  #     active?
  #     repeat(opts)
  #     once(opts)
  #     every(time_interval, opts)
  #
  # @example
  #     if BW::Motion.accelerometer.available?
  #       BW::Motion.accelerometer.every(5) do |result|
  #         # see the README for the keys that are available in result.
  #       end
  #     end
  #
  # If you insist on using your own manager, or you want more than one
  # BW::Motion::Whatever running at the same time, you'll need to instantiate
  # them yourself.
  #
  # @example
  #     mgr = CMMotionManager.alloc.init
  #     accel = BW::Motion::Accelerometer.new(mgr)
  #     accel.once do |result_data|
  #     end
  #     # => BW::Motion::accelerometer.once do |result_data| ... end
  module Motion
    module_function

    def manager
      @manager ||= CMMotionManager.alloc.init
    end

    def accelerometer
      @accelerometer ||= Accelerometer.new(self.manager)
    end

    def gyroscope
      @gyroscope ||= Gyroscope.new(self.manager)
    end

    def magnetometer
      @magnetometer ||= Magnetometer.new(self.manager)
    end

    def device
      @device ||= DeviceMotion.new(self.manager)
    end
  end


  module Motion
    module Error
    end

    class GenericMotionInterface

      def initialize(manager)
        @manager = manager
      end

      def repeat(options={}, &blk)
        raise "A block is required" unless blk
        blk.weak! if BubbleWrap.use_weak_callbacks?

        self.start(options, &blk)
        return self
      end

      def every(time=nil, options={}, &blk)
        raise "A block is required" unless blk
        blk.weak! if BubbleWrap.use_weak_callbacks?

        if time.is_a?(NSDictionary)
          options = time
        elsif time
          options = options.merge(interval: time)
        end

        self.start(options, &blk)
        return self
      end

      def once(options={}, &blk)
        raise "A block is required" unless blk
        blk.weak! if BubbleWrap.use_weak_callbacks?

        @called_once = false
        every(options) do |result, error|
          unless @called_once
            @called_once = true
            blk.call(result, error)
          end
          self.stop
        end

        return self
      end

      private def convert_queue(queue_name)
        case queue_name
        when :main, nil
          return NSOperationQueue.mainQueue
        when :background
          queue = NSOperationQueue.new
          queue.name = 'com.bubble-wrap.core-motion.background-queue'
          return queue
        when :current
          return NSOperationQueue.currentQueue
        when String
          queue = NSOperationQueue.new
          queue.name = queue_name
          return queue
        else
          queue_name
        end
      end

      private def internal_handler(handler)
        retval = -> (result_data, error) do
          handle_result(result_data, error, handler)
        end
        retval.weak! if BubbleWrap.use_weak_callbacks?
        retval
      end

    end

  end
end


================================================
FILE: motion/network-indicator/network-indicator.rb
================================================
module BubbleWrap
  module NetworkIndicator
    DELAY = 0.2

    module_function

    def counter
      @counter ||= 0
    end

    def show
      if Dispatch::Queue.current.to_s == 'com.apple.main-thread'
        @counter = self.counter + 1
        self.update_spinner
      else
        Dispatch::Queue.main.async do
          self.show
        end
      end
    end

    def hide
      if Dispatch::Queue.current.to_s == 'com.apple.main-thread'
        @counter = [self.counter - 1, 0].max
        if self.counter == 0
          if @hide_indicator_timer
            @hide_indicator_timer.invalidate
          end
          @hide_indicator_timer = NSTimer.timerWithTimeInterval(DELAY - 0.01, target: self, selector: :update_spinner_timer, userInfo: nil, repeats: false)
          NSRunLoop.mainRunLoop.addTimer(@hide_indicator_timer, forMode:NSRunLoopCommonModes)
        end
      else
        Dispatch::Queue.main.async do
          self.hide
        end
      end
    end

    def update_spinner_timer
      update_spinner
    end

    def update_spinner
      if Dispatch::Queue.current.to_s == 'com.apple.main-thread'
        if @hide_indicator_timer
          @hide_indicator_timer.invalidate
          @hide_indicator_timer = nil
        end
        UIApplication.sharedApplication.networkActivityIndicatorVisible = (@counter > 0)
      else
        Dispatch::Queue.main.async do
          self.update_spinner
        end
      end
    end

    def visible?
      UIApplication.sharedApplication.networkActivityIndicatorVisible?
    end

    def reset!
      @counter = 0
      self.update_spinner
    end

  end
end


================================================
FILE: motion/reactor/default_deferrable.rb
================================================
module BubbleWrap
  module Reactor
    # A basic class which includes Deferrable when all
    # you need is a deferrable without any added behaviour.
    class DefaultDeferrable
      include ::BubbleWrap::Reactor::Deferrable
    end
  end
end


================================================
FILE: motion/reactor/deferrable.rb
================================================
module BubbleWrap
  module Reactor
    # Provides a mixin for deferrable jobs.
    module Deferrable

      # def self.included(base)
      #   base.extend ::BubbleWrap::Reactor::Future
      # end

      # Specify a block to be executed if and when the Deferrable object
      # receives a status of :succeeded. See set_deferred_status for more
      # information.
      # Calling this method on a Deferrable object whose status is not yet
      # known will cause the callback block to be stored on an internal
      # list. If you call this method on a Deferrable whose status is
      # :succeeded, the block will be executed immediately, receiving
      # the parameters given to the prior set_deferred_status call.
      def callback(&blk)
        return unless blk
        @deferred_status ||= :unknown
        if @deferred_status == :succeeded
          execute_block(&blk)
        elsif @deferred_status != :failed
          @callbacks ||= []
          @callbacks.unshift blk
        end
      end

      # Cancels an outstanding timeout if any. Undoes the action of timeout.
      def cancel_timeout
        @deferred_timeout ||= nil
        if @deferred_timeout
          @deferred_timeout.cancel
          @deferred_timeout = nil
        end
      end

      # Specify a block to be executed if and when the Deferrable object
      # receives a status of :failed. See set_deferred_status for more
      # information.
      def errback(&blk)
        return unless blk
        @deferred_status ||= :unknown
        if @deferred_status == :failed
          execute_block(&blk)
          blk.call(*@deferred_args)
        elsif @deferred_status != :succeeded
          @errbacks ||= []
          @errbacks.unshift blk
        end
      end

      def execute_block(&blk)
        return unless blk
        blk.call(*@deferred_args)
      end

      def delegate(delegate)
        callback_delegate(delegate)
        errback_delegate(delegate)
        self
      end

      def errback_delegate(delegate)
        errback do |*args|
          delegate.fail *args
        end
        self
      end

      def callback_delegate(delegate)
        callback do |*args|
          delegate.succeed *args
        end
        self
      end

      # Sugar for set_deferred_status(:failed, …)
      def fail(*args)
        set_deferred_status :failed, *args
      end
      alias set_deferred_failure fail

      # Sets the “disposition” (status) of the Deferrable object. See also
      # the large set of sugarings for this method. Note that if you call
      # this method without arguments, no arguments will be passed to the
      # callback/errback. If the user has coded these with arguments,
      # then the user code will throw an argument exception. Implementors
      # of deferrable classes must document the arguments they will supply
      # to user callbacks.
      # OBSERVE SOMETHING VERY SPECIAL here: you may call this method even
      # on the INSIDE of a callback. This is very useful when a
      # previously-registered callback wants to change the parameters that
      # will be passed to subsequently-registered ones.
      # You may give either :succeeded or :failed as the status argument.
      # If you pass :succeeded, then all of the blocks passed to the object
      # using the callback method (if any) will be executed BEFORE the
      # set_deferred_status method returns. All of the blocks passed to the
      # object using errback will be discarded.
      # If you pass :failed, then all of the blocks passed to the object
      # using the errback method (if any) will be executed BEFORE the
      # set_deferred_status method returns. All of the blocks passed to the
      # object using # callback will be discarded.
      # If you pass any arguments to set_deferred_status in addition to the
      # status argument, they will be passed as arguments to any callbacks
      # or errbacks that are executed. It’s your responsibility to ensure
      # that the argument lists specified in your callbacks and errbacks match
      # the arguments given in calls to set_deferred_status, otherwise Ruby
      # will raise an ArgumentError.
      def set_deferred_status(status, *args)
        cancel_timeout
        @errbacks ||= nil
        @callbacks ||= nil
        @deferred_status = status
        @deferred_args = args
        case @deferred_status
        when :succeeded
          if @callbacks
            while cb = @callbacks.pop
              execute_block(&cb)
            end
          end
          @errbacks.clear if @errbacks
        when :failed
          if @errbacks
            while eb = @errbacks.pop
              execute_block(&eb)
            end
          end
          @callbacks.clear if @callbacks
        end
      end

      # Sugar for set_deferred_status(:succeeded, …)
      def succeed(*args)
        set_deferred_status :succeeded, *args
      end
      alias set_deferred_success succeed

      # Setting a timeout on a Deferrable causes it to go into the failed
      # state after the Timeout expires (passing no arguments to the object’s
      # errbacks). Setting the status at any time prior to a call to the
      # expiration of the timeout will cause the timer to be cancelled.
      def timeout(seconds)
        cancel_timeout
        me = self
        @deferred_timeout = Timer.new(seconds) {me.fail}
      end

      def deferred_status
        @deferred_status ||= :unknown
      end

      def deferred_args
        @deferred_args
      end

    end
  end
end


================================================
FILE: motion/reactor/dependent_deferrable.rb
================================================
module BubbleWrap
  module Reactor
    class DependentDeferrable < DefaultDeferrable
      # args are Deferrable(s) which the returned Deferrable depends on.
      # returns a Deferrable that depends on args.
      # which:
      #   succeeds only when every Deferrable in args succeeds
      #   fails immediately when any Deferrable in args fails
      # Have to be careful that #deferred_args for DependentDeferrable is a list of #deferred_args from its children Deferrable(s).
      def self.on(*args)
        deferrable = self.new
        @children_deferrables = args
        @children_deferrables.each do |e|
          e.callback do |result|
            if @children_deferrables.all? {|a| a.deferred_status == :succeeded}
              deferrable.succeed(*@children_deferrables.map(&:deferred_args))
            end
          end
          e.errback do |result|
            deferrable.fail(*e.deferred_args)
          end
        end
        deferrable
      end
    end
  end
end


================================================
FILE: motion/reactor/eventable.rb
================================================
module BubbleWrap
  module Reactor
    # A simple mixin that adds events to your object.
    module Eventable

      # When `event` is triggered the block will execute
      # and be passed the arguments that are passed to
      # `trigger`.
      def on(event, method = nil, &blk)
        events = _events_for_key(event)
        method_or_block = method ? method : blk
        events.push method_or_block
      end

      # When `event` is triggered, do not call the given
      # block any more
      def off(event, method = nil, &blk)
        events = _events_for_key(event)
        if method
          events.delete_if { |m| m.receiver == method.receiver and m.name == method.name }
        elsif blk
          events.delete_if { |b| b == blk }
        else
          __events__[event] = Array.new
        end
        blk
      end

      # Trigger an event
      def trigger(event, *args)
        blks = _events_for_key(event).clone
        blks.map do |blk|
          blk.call(*args)
        end
      end

      private

      def __events__
        @__events__ ||= Hash.new
      end

      def _events_for_key(event)
        __events__[event] ||= Array.new
      end
    end
  end
end


================================================
FILE: motion/reactor/future.rb
================================================
module BubbleWrap
  module Reactor
    module Future

      # A future is a sugaring of a typical deferrable usage.
      def future arg, cb=nil, eb=nil, &blk
        arg = arg.call if arg.respond_to?(:call)

        if arg.respond_to?(:set_deferred_status)
          if cb || eb
            arg.callback(&cb) if cb
            arg.errback(&eb) if eb
          else
            arg.callback(&blk) if blk
          end
        end

        arg
      end
    end
  end
end


================================================
FILE: motion/reactor/periodic_timer.rb
================================================
module BubbleWrap
  module Reactor
    # Creates a repeating timer.
    class PeriodicTimer
      include Eventable

      attr_accessor :interval

      # Create a new timer that fires after a given number of seconds
      def initialize(interval, *args, &blk)
        callback = args.first.respond_to?(:call) ? args.first : blk
        raise ArgumentError, "No callback or block supplied to periodic timer" unless callback
        callback.weak! if callback && BubbleWrap.use_weak_callbacks?

        options = args.last.is_a?(Hash) ? args.last : {}
        if options[:common_modes]
          NSLog "[DEPRECATED - Option :common_modes] a Run Loop Mode is no longer needed."
        end

        self.interval = interval

        leeway = interval
        queue  = Dispatch::Queue.current
        @timer = Dispatch::Source.timer(leeway, interval, 0.0, queue) do
          callback.call
          trigger(:fired)
        end
      end

      # Cancel the timer
      def cancel
        @timer.cancel!
        trigger(:cancelled)
      end

    end
  end
end


================================================
FILE: motion/reactor/queue.rb
================================================
module BubbleWrap
  module Reactor
    # A GCD scheduled, linear queue.
    #
    # This class provides a simple “Queue” like abstraction on top of the
    # GCD scheduler.
    #
    # Useful as an API sugar for stateful protocols
    #
    #  q = BubbleWrap::Reactor::Queue.new
    #  q.push('one', 'two', 'three')
    #  3.times do
    #    q.pop{ |msg| puts(msg) }
    #  end
    class Queue

      # Create a new queue
      def initialize
        @items = []
      end

      # Is the queue empty?
      def empty?
        @items.empty?
      end

      # The size of the queue
      def size
        @items.size
      end

      # Push items onto the work queue. The items will not appear in the queue
      # immediately, but will be scheduled for addition.
      def push(*items)
        ::BubbleWrap::Reactor.schedule do
          @items.push(*items)
          @popq.shift.call @items.shift until @items.empty? || @popq.empty?
        end
      end

      # Pop items off the queue, running the block on the work queue. The pop
      # will not happen immediately, but at some point in the future, either
      # in the next tick, if the queue has data, or when the queue is populated.
      def pop(*args, &blk)
        cb = proc do
          blk.call(*args)
        end
        ::BubbleWrap::Reactor.schedule do
          if @items.empty?
            @popq << cb
          else
            cb.call @items.shift
          end
        end
        nil # Always returns nil
      end

    end
  end
end


================================================
FILE: motion/reactor/thread_aware_deferrable.rb
================================================
module BubbleWrap
  module Reactor
    class ThreadAwareDeferrable < DefaultDeferrable
      include ::BubbleWrap::Reactor::Deferrable


      # need to store the the queue in callback / errback
      def callback(&blk)
        return unless blk
        cache_block_queue(&blk)
        super(&blk)
      end

      def errback(&blk)
        return unless blk
        cache_block_queue(&blk)
        super(&blk)
      end

      def execute_block(&blk)
        return unless blk
        queue = @queue_cache.delete(blk.object_id)
        return unless queue
        queue.async do
          blk.call(*@deferred_args)
        end
      end

      def cache_block_queue(&blk)
        return unless blk
        @queue_cache ||= {}
        @queue_cache[blk.object_id] = Dispatch::Queue.current
      end
    end
  end
end



================================================
FILE: motion/reactor/timer.rb
================================================
module BubbleWrap
  module Reactor
    # Creates a one-time timer.
    class Timer
      include Eventable

      # Create a new timer that fires after a given number of seconds
      def initialize(leeway, callback=nil, &blk)
        queue  = Dispatch::Queue.current
        @timer = Dispatch::Source.timer(leeway, Dispatch::TIME_FOREVER, 0.0, queue) do |src|
          begin
            (callback || blk).call
            trigger(:fired)
          ensure
            src.cancel!
          end
        end
      end

      # Cancel the timer
      def cancel
        @timer.cancel! if @timer
        trigger(:cancelled)
        true
      end

    end
  end
end


================================================
FILE: motion/reactor.rb
================================================
module BubbleWrap
  module Reactor
    module_function

    # Always returns true - for compatibility with EM
    def reactor_running?
      true
    end
    alias reactor_thread? reactor_running?

    # Call `callback` or the passed block in `interval` seconds.
    # Returns a timer signature that can be passed into
    # `cancel_timer`
    def add_timer(interval, callback=nil, &blk)
      @timers ||= {}
      timer = Timer.new(interval,callback,&blk)
      timer.on(:fired) do
        @timers.delete(timer.object_id)
      end
      timer.on(:cancelled) do
        @timers.delete(timer.object_id)
      end
      @timers[timer.object_id] = timer
      timer.object_id
    end

    # Cancel a timer by passing in either a Timer object or
    # a timer id (as returned by `add_timer` and
    # `add_periodic_timer`).
    def cancel_timer(timer)
      return timer.cancel if timer.respond_to?(:cancel)
      @timers ||= {}
      return @timers[timer].cancel if @timers[timer]
      false
    end

    # Call `callback` or the passed block every `interval` seconds.
    # Returns a timer signature that can be passed into
    # `cancel_timer`
    # Optionally supply a callback as a second argument instead of a block
    # (as per EventMachine API)
    # Optionally supply :common_modes => true in args to schedule the timer
    # for the runloop "common modes" (NSRunLoopCommonModes) instead of
    # the default runloop mode.
    def add_periodic_timer(interval, *args, &blk)
      @timers ||= {}
      timer = PeriodicTimer.new(interval,*args,&blk)
      timer.on(:cancelled) do
        @timers.delete(timer)
      end
      @timers[timer.object_id] = timer
      timer.object_id
    end

    # Defer is for integrating blocking operations into the reactor's control
    # flow.
    # Call defer with one or two blocks, the second block is optional.
    #     operation = proc do
    #       # perform a long running operation here
    #       "result"
    #     end
    #     callback = proc do |result|
    #       # do something with the result here, such as trigger a UI change
    #     end
    #     BubbleWrap::Reactor.defer(operation,callback)
    # The action of `defer` is to take the block specified in the first
    # parameter (the "operation") and schedule it for asynchronous execution
    # on a GCD concurrency queue. When the operation completes the result (if any)
    # is passed into the callback (if present).
    def defer(op=nil,cb=nil,&blk)
      schedule do
        result = (op||blk).call
        schedule(result, &cb) if cb
      end
    end

    # A version of `defer` which schedules both the operator
    # and callback operations on the application's main thread.
    def defer_on_main(op=nil,cb=nil,&blk)
      schedule_on_main do
        result = (op||blk).call
        schedule_on_main(result, &cb) if cb
      end
    end

    # Schedule a block for execution on the reactor queue.
    def schedule(*args, &blk)
      @queue ||= ::Dispatch::Queue.concurrent("#{NSBundle.mainBundle.bundleIdentifier}.reactor")
      blk.weak! if blk && BubbleWrap.use_weak_callbacks?

      cb = proc do
        blk.call(*args)
      end
      @queue.async &cb
      nil
    end

    # Schedule a block for execution on your application's main thread.
    # This is useful as UI updates need to be executed from the main
    # thread.
    def schedule_on_main(*args, &blk)
      blk.weak! if blk && BubbleWrap.use_weak_callbacks?
      cb = proc do
        blk.call(*args)
      end
      ::Dispatch::Queue.main.async &cb
    end

  end
end

::EM = ::BubbleWrap::Reactor unless defined?(::EM) # Yes I dare!


================================================
FILE: motion/rss_parser.rb
================================================
# Asynchronous and non blocking RSS Parser based on NSXMLParser.
# The parser will progressively parse a feed and yield each item to the provided block.
#
# The parser can also trigger delegate methods, you can define the following delegate method on the receiving object:
# def when_parser_initializes; end
# def when_parser_parses; end
# def when_parser_is_done; end
# def when_parser_errors; end
#
# @see https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html
#
# @usage example:
#   feed = RSSParser.new(URL)
#   feed.delegate = self
#   feed.parse do |item|
#     print item.link
#   end
#   def when_parser_is_done
#     App.alert('parsing complete')
#   end
#
module BubbleWrap
  class RSSParser

    attr_accessor :parser, :source, :doc, :debug, :delegate, :parser_error
    attr_reader :state

    # RSSItem is a simple class that holds all of RSS items.
    # Extend this class to display/process the item differently.
    class RSSItem
      attr_accessor :title, :description, :link, :guid, :pubDate, :creator, :category, :encoded, :enclosure

      def initialize
        @title, @description, @link, @pubDate, @guid, @creator, @category, @encoded = '', '', '', '', ''
      end

      def to_hash
        {
          :title        => title,
          :description  => description,
          :link         => link,
          :pubDate      => pubDate,
          :guid         => guid,
          :enclosure    => enclosure,
          :category     => category,
          :encoded      => encoded,
        }
      end
    end

    def initialize(input, data=false)
      if data
        data_to_parse = input.respond_to?(:to_data) ? input.to_data : input
        @source = data_to_parse
        @source_type = :data
      else
        url = input.is_a?(NSURL) ? input : NSURL.alloc.initWithString(input)
        @source = url
        @source_type = :url
      end
      self
    end

    def state=(new_state)
      @state = new_state
      callback_meth = "when_parser_#{new_state}"
      if self.delegate && self.delegate.respond_to?(callback_meth)
        self.delegate.send(callback_meth)
      end
    end

    # Starts the parsing and send each parsed item through its block.
    #
    # Usage:
    #   feed.parse do |item|
    #     puts item.link
    #   end
    def parse(&block)
      @block = block

      if @source_type == :url
        @parser = NSXMLParser.alloc.initWithContentsOfURL(@source)
      else
        @parser = NSXMLParser.alloc.initWithData(@source)
      end

      @parser.shouldProcessNamespaces = true
      @parser.delegate ||= self
      self.state = :initializes
      @parser.parse
    end

    # Delegate getting called when parsing starts
    def parserDidStartDocument(parser)
      puts "starting parsing.." if debug
      self.state = :parses
    end

    # Delegate being called when an element starts being processed
    def parser(parser, didStartElement:element, namespaceURI:uri, qualifiedName:name, attributes:attrs)
      if element == 'item'
        @current_item = RSSItem.new
      elsif element == 'enclosure'
        @current_item.enclosure = attrs
      end
      @current_element = element
    end

    # as the parser finds characters, this method is being called
    def parser(parser, foundCharacters:string)
      if @current_element && @current_item && @current_item.respond_to?(@current_element)
        el = @current_item.send(@current_element)
        el << string if el.respond_to?(:<<)
      end
    end

    # method called when an element is done being parsed
    def parser(parser, didEndElement:element, namespaceURI:uri, qualifiedName:name)
      if element == 'item'
        @block.call(@current_item) if @block
      else
        @current_element = nil
      end
    end

    # method called when the parser encounters an error
    # error can be retrieved with parserError
    def parser(parser, parseErrorOccurred:parse_error)
      puts "parseErrorOccurred" if debug
      @parser_error = parse_error

      self.state = :errors
    end

    # delegate getting called when the parsing is done
    # If a block was set, it will be called on each parsed items
    def parserDidEndDocument(parser)
      puts "done parsing" if debug
      self.state = :is_done unless self.state == :errors
    end

    def parserError
      @parser_error || @parser.parserError
    end

    # TODO: implement
    # parser:validationErrorOccurred:
    # parser:foundCDATA:

  end
end


================================================
FILE: motion/shortcut.rb
================================================
# Make sure that
# Both BubbleWrap and BW are defined.  This file is depended on by everything
# else in BubbleWrap, so don't stuff anything in here unless you know why
# you're doing it.
module BubbleWrap
  SETTINGS = {}

  def self.debug=(val)
    BubbleWrap::SETTINGS[:debug] = val
  end

  def self.debug?
    BubbleWrap::SETTINGS[:debug]
  end

  def self.use_weak_callbacks=(val)
    BubbleWrap::SETTINGS[:use_weak_callbacks] = val
  end

  def self.use_weak_callbacks?
    BubbleWrap::SETTINGS[:use_weak_callbacks]
  end

  def version
    BubbleWrap::VERSION
  end
end

BW = BubbleWrap unless defined?(BW)


================================================
FILE: motion/sms/result.rb
================================================
module BubbleWrap
  module SMS
    class Result
      attr_accessor :result

      def initialize(result)
        self.result = result
      end

      def sent?
        self.result == MessageComposeResultSent
      end

      def canceled?
        self.result == MessageComposeResultCancelled
      end

      def failed?
        self.result == MessageComposeResultFailed
      end

    end
  end
end


================================================
FILE: motion/sms/sms.rb
================================================
module BubbleWrap
  module SMS

    module_function

    # Base method to create your in-app mail
    # ---------------------------------------
    # EX
    # BW::SMS.compose (
    # {
    #   delegate: self, # optional, will use root view controller by default
    #   to: [ "1(234)567-8910" ],
    #   message: "This is my message. It isn't very long.",
    #   animated: false
    # }) {|result, error|
    #   result.sent?      # => boolean
    #   result.canceled?  # => boolean
    #   result.failed?    # => boolean
    #   error             # => NSError
    #   }

    def compose(options = {}, &callback)
      @delegate = options[:delegate] || App.window.rootViewController
      @callback = callback
      @callback.weak! if @callback && BubbleWrap.use_weak_callbacks?

      @message_controller = create_message_controller(options)
      @message_is_animated = options[:animated] == false ? false : true
      @delegate.presentModalViewController(@message_controller, animated: @message_is_animated)
    end

    def create_message_controller(options = {})
      message_controller = MFMessageComposeViewController.alloc.init
      message_controller.messageComposeDelegate = self
      message_controller.body = options[:message]
      message_controller.recipients = Array(options[:to])
      message_controller
    end

    def can_send_sms?
      !!MFMessageComposeViewController.canSendText
    end

    # Event when the MFMessageComposeViewController is closed
    # -------------------------------------------------------------
    # the callback is fired if it was present in the constructor

    def messageComposeViewController(controller, didFinishWithResult: result)
      @delegate.dismissModalViewControllerAnimated(@message_is_animated)
      @callback.call Result.new(result) if @callback
    end
  end
end


================================================
FILE: motion/test_suite_delegate.rb
================================================
class TestSuiteDelegate
  attr_accessor :window

  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
    @window.rootViewController = UIViewController.alloc.init
    @window.makeKeyAndVisible
    true
  end
end

class TestSuiteOSXDelegate
  def applicationDidFinishLaunching(notification)
    buildMenu
    buildWindow
  end

  def buildWindow
    @mainWindow = NSWindow.alloc.initWithContentRect([[240, 180], [480, 360]],
      styleMask: NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask,
      backing: NSBackingStoreBuffered,
      defer: false)
    @mainWindow.title = "BubbleWrap Tests"
  end

  def buildMenu
    @mainMenu = NSMenu.new

    appName = "BubbleWrap Tests"
    addMenu(appName) do
      addItemWithTitle("About #{appName}", action: 'orderFrontStandardAboutPanel:', keyEquivalent: '')
      addItem(NSMenuItem.separatorItem)
      addItemWithTitle('Preferences', action: 'openPreferences:', keyEquivalent: ',')
      addItem(NSMenuItem.separatorItem)
      servicesItem = addItemWithTitle('Services', action: nil, keyEquivalent: '')
      NSApp.servicesMenu = servicesItem.submenu = NSMenu.new
      addItem(NSMenuItem.separatorItem)
      addItemWithTitle("Hide #{appName}", action: 'hide:', keyEquivalent: 'h')
      item = addItemWithTitle('Hide Others', action: 'hideOtherApplications:', keyEquivalent: 'H')
      item.keyEquivalentModifierMask = NSCommandKeyMask|NSAlternateKeyMask
      addItemWithTitle('Show All', action: 'unhideAllApplications:', keyEquivalent: '')
      addItem(NSMenuItem.separatorItem)
      addItemWithTitle("Quit #{appName}", action: 'terminate:', keyEquivalent: 'q')
    end

    NSApp.helpMenu = addMenu('Help') do
      addItemWithTitle("#{appName} Help", action: 'showHelp:', keyEquivalent: '?')
    end.menu

    NSApp.mainMenu = @mainMenu
  end

  private

  def addMenu(title, &b)
    item = createMenu(title, &b)
    @mainMenu.addItem item
    item
  end

  def createMenu(title, &b)
    menu = NSMenu.alloc.initWithTitle(title)
    menu.instance_eval(&b) if b
    item = NSMenuItem.alloc.initWithTitle(title, action: nil, keyEquivalent: '')
    item.submenu = menu
    item
  end
end


================================================
FILE: motion/ui/pollute.rb
================================================
# Please, no more!  It'll hurt BubbleWrap's compatibility with other libraries.
[
  [UIControl,         BW::UIControlWrapper],
  [UIView,            BW::UIViewWrapper],
  [UIViewController,  BW::UIViewControllerWrapper],
].each do |base, wrapper|
    base.send(:include, wrapper)
end


================================================
FILE: motion/ui/ui_activity_view_controller_wrapper.rb
================================================
module BW
  class UIActivityViewController < ::UIActivityViewController
    class << self
      def new(options = {}, presenting_controller = nil, &block)
        options = {
          activities: nil,
          animated: true
        }.merge(options)

        if options[:item] || options[:items]
          items = Array(options[:item] || options[:items])
        else
          raise ArgumentError, "You must specify at least one item - #{options.inspect}"
        end

        vc = alloc.initWithActivityItems(items, applicationActivities:options[:activities])
        vc.excludedActivityTypes = BW::Constants.get("UIActivityType", Array(options[:excluded])) if options[:excluded]

        unless block.nil?
          block.weak! if BubbleWrap.use_weak_callbacks?
          vc.setCompletionHandler block
        end

        presenting_controller ||= App.window.rootViewController.presentedViewController # May be nil, but handles use case of container views
        presenting_controller ||= App.window.rootViewController

        presenting_controller.presentViewController(vc, animated:options[:animated], completion: lambda {})
        vc
      end

    end
  end

  # UIActivityTypes
  Constants.register(
    UIActivityTypePostToFacebook,
    UIActivityTypePostToTwitter,
    UIActivityTypePostToWeibo,
    UIActivityTypeMessage,
    UIActivityTypeMail,
    UIActivityTypePrint,
    UIActivityTypeCopyToPasteboard,
    UIActivityTypeAssignToContact,
    UIActivityTypeSaveToCameraRoll,
    UIActivityTypeAddToReadingList,
    UIActivityTypePostToFlickr,
    UIActivityTypePostToVimeo,
    UIActivityTypePostToTencentWeibo,
    UIActivityTypeAirDrop
  )
end


================================================
FILE: motion/ui/ui_alert_view.rb
================================================
module BW
  class UIAlertView < ::UIAlertView
    @callbacks = [
      :will_present,
      :did_present,
      :on_system_cancel,
      :enable_first_other_button?,
      :on_click,
      :will_dismiss,
      :did_dismiss
    ]

    KEYBOARD_TYPES = {
      default: UIKeyboardTypeDefault,
      ascii: UIKeyboardTypeASCIICapable,
      numbers_punctuation: UIKeyboardTypeNumbersAndPunctuation,
      url: UIKeyboardTypeURL,
      number_pad: UIKeyboardTypeNumberPad,
      phone_pad: UIKeyboardTypePhonePad,
      name_phone_pad: UIKeyboardTypeNamePhonePad,
      email_address: UIKeyboardTypeEmailAddress,
      email: UIKeyboardTypeEmailAddress, # Duplicate to help developers
      decimal_pad: UIKeyboardTypeDecimalPad,
      twitter: UIKeyboardTypeTwitter,
      web_search: UIKeyboardTypeWebSearch,
      alphabet: UIKeyboardTypeASCIICapable
    }

    class << self
      attr_reader :callbacks

      def new(options = {}, &block)
        view = alloc.initWithTitle(options[:title],
          message: options[:message],
          delegate: nil,
          cancelButtonTitle: nil,
          otherButtonTitles: nil
        )

        Array(options[:buttons]).each { |title| view.addButtonWithTitle(title) }

        view.style               = options[:style]
        view.delegate            = view
        view.cancel_button_index = options[:cancel_button_index]

        view.instance_variable_set(:@handlers, {})
        block.weak! if block && BubbleWrap.use_weak_callbacks?

        options[:on_click] ||= block

        callbacks.each do |callback|
          view.send(callback, &options[callback]) if options[callback]
        end

        view
      end

      def default(options = {}, &block)
        options = {buttons: "OK"}.merge!(options)
        options[:style] = :default
        new(options, &block)
      end

      def plain_text_input(options = {}, &block)
        options = {buttons: ["Cancel", "OK"],
                   cancel_button_index: 0}.merge!(options)
        options[:style] = :plain_text_input
        new(options, &block).tap do |view|
          view.textFieldAtIndex(0).tap do |tf|
            tf.text = options[:text] if options[:text]
            tf.placeholder = options[:placeholder] if options[:placeholder]
            tf.keyboardType = (KEYBOARD_TYPES[options[:keyboard_type]] || options[:keyboard_type]) if options[:keyboard_type]
          end
        end
      end

      def secure_text_input(options = {}, &block)
        options = {buttons: ["Cancel", "OK"],
                   cancel_button_index: 0}.merge!(options)
        options[:style] = :secure_text_input
        new(options, &block)
      end

      def login_and_password_input(options = {}, &block)
        options = {buttons: ["Cancel", "Log in"],
                   cancel_button_index: 0}.merge!(options)
        options[:style] = :login_and_password_input
        new(options, &block)
      end
    end

    def style
      alertViewStyle
    end

    def style=(value)
      self.alertViewStyle = Constants.get("UIAlertViewStyle", value) if value
    end

    def cancel_button_index
      cancelButtonIndex
    end

    def cancel_button_index=(value)
      self.cancelButtonIndex = value if value
    end

    ###############################################################################################

    attr_accessor :clicked_button
    protected     :clicked_button=

    class ClickedButton
      def initialize(alert, index)
        @index  = index
        @title  = alert.buttonTitleAtIndex(index)
        @cancel = alert.cancelButtonIndex == index
      end

      attr_reader :index, :title
      def cancel?; @cancel end
    end

    ###############################################################################################

    attr_reader :handlers
    protected   :handlers

    callbacks.each do |callback|
      define_method(callback) do |&block|
        return handlers[callback] unless block

        handlers[callback] = block if block
        self
      end
    end

    # UIAlertViewDelegate protocol ################################################################

    def willPresentAlertView(alert)
      alert.clicked_button = nil
      handlers[:will_present].call(alert) if handlers[:will_present]
    end

    def didPresentAlertView(alert)
      alert.clicked_button = nil
      handlers[:did_present].call(alert) if handlers[:did_present]
    end

    def alertViewCancel(alert)
      alert.clicked_button = nil
      handlers[:on_system_cancel].call(alert) if handlers[:on_system_cancel]
    end

    def alertViewShouldEnableFirstOtherButton(alert)
      alert.clicked_button = nil
      handlers[:enable_first_other_button?].call(alert) if handlers[:enable_first_other_button?]
    end

    def alertView(alert, clickedButtonAtIndex:index)
      alert.clicked_button = ClickedButton.new(alert, index)
      handlers[:on_click].call(alert) if handlers[:on_click]
    end

    def alertView(alert, willDismissWithButtonIndex:index)
      alert.clicked_button = ClickedButton.new(alert, index)
      handlers[:will_dismiss].call(alert) if handlers[:will_dismiss]
    end

    def alertView(alert, didDismissWithButtonIndex:index)
      alert.clicked_button = ClickedButton.new(alert, index)
      handlers[:did_dismiss].call(alert) if handlers[:did_dismiss]
    end

    ###############################################################################################

    def plain_text_field
      textFieldAtIndex(0) if style == UIAlertViewStylePlainTextInput
    end

    def secure_text_field
      textFieldAtIndex(0) if style == UIAlertViewStyleSecureTextInput
    end

    def login_text_field
      textFieldAtIndex(0) if style == UIAlertViewStyleLoginAndPasswordInput
    end

    def password_text_field
      textFieldAtIndex(1) if style == UIAlertViewStyleLoginAndPasswordInput
    end
  end

  Constants.register(
    UIAlertViewStyleDefault,
    UIAlertViewStylePlainTextInput,
    UIAlertViewStyleSecureTextInput,
    UIAlertViewStyleLoginAndPasswordInput
  )
end


================================================
FILE: motion/ui/ui_bar_button_item.rb
================================================
module BW
  class UIBarButtonItem < ::UIBarButtonItem
    class << self
      def styled(type, *objects, &block)
        if block.nil?
          action = nil
        else
          block.weak! if BubbleWrap.use_weak_callbacks?
          action = :call
        end
        object = objects.size == 1 ? objects.first : objects
        style  = Constants.get("UIBarButtonItemStyle", type)

        item = if object.is_a?(String)
          alloc.initWithTitle(object,
            style:style,
            target:block,
            action:action
          )
        elsif object.is_a?(UIImage)
          alloc.initWithImage(object,
            style:style,
            target:block,
            action:action
          )
        elsif object.is_a?(Array) && object.size == 2 && object.all? { |o| o.is_a?(UIImage) }
          alloc.initWithImage(object[0],
            landscapeImagePhone:object[1],
            style:style,
            target:block,
            action:action
          )
        else
          raise ArgumentError, "invalid object - #{object.inspect}"
        end

        item.instance_variable_set(:@target, block)
        item
      end

      def system(type, &block)
        if block.nil?
          action = nil
        else
          block.weak! if BubbleWrap.use_weak_callbacks?
          action = :call
        end
        system_item = Constants.get("UIBarButtonSystemItem", type)

        item = alloc.initWithBarButtonSystemItem(system_item, target:block, action:action)
        item.instance_variable_set(:@target, block)
        item
      end

      def custom(view, &block)
        view.when_tapped(true, &block) if block
        alloc.initWithCustomView(view)
      end

      def new(options = {}, &block)
        if options[:styled]
          args = options.values_at(:title, :image, :landscape).compact
          return styled(options[:styled], *args, &block)
        end

        return system(options[:system], &block) if options[:system]

        return custom(options[:custom], &block) if options[:custom]
        return custom(options[:view],   &block) if options[:view]

        raise ArgumentError, "invalid options - #{options.inspect}"
      end

      def build(options = {}, &block)
        NSLog "[DEPRECATED - BW::UIBarButtonItem.build] please use .new instead."
        new(options, &block)
      end
    end
  end

  Constants.register(
    UIBarButtonItemStylePlain,
    UIBarButtonItemStyleBordered,
    UIBarButtonItemStyleDone,

    UIBarButtonSystemItemDone,
    UIBarButtonSystemItemCancel,
    UIBarButtonSystemItemEdit,
    UIBarButtonSystemItemSave,
    UIBarButtonSystemItemAdd,
    UIBarButtonSystemItemFlexibleSpace,
    UIBarButtonSystemItemFixedSpace,
    UIBarButtonSystemItemCompose,
    UIBarButtonSystemItemReply,
    UIBarButtonSystemItemAction,
    UIBarButtonSystemItemOrganize,
    UIBarButtonSystemItemBookmarks,
    UIBarButtonSystemItemSearch,
    UIBarButtonSystemItemRefresh,
    UIBarButtonSystemItemStop,
    UIBarButtonSystemItemCamera,
    UIBarButtonSystemItemTrash,
    UIBarButtonSystemItemPlay,
    UIBarButtonSystemItemPause,
    UIBarButtonSystemItemRewind,
    UIBarButtonSystemItemFastForward,
    UIBarButtonSystemItemUndo,
    UIBarButtonSystemItemRedo,
    UIBarButtonSystemItemPageCurl,
  )
end


================================================
FILE: motion/ui/ui_control_wrapper.rb
================================================
module BubbleWrap
  module UIControlWrapper
    def when(events, options = {}, &block)
      events = BW::Constants.get("UIControlEvent", events)

      @callback ||= {}
      @callback[events] ||= []

      unless options[:append]
        @callback[events] = []
        removeTarget(nil, action: nil, forControlEvents: events)
      end

      @callback[events] << block
      block.weak! if BubbleWrap.use_weak_callbacks?
      addTarget(@callback[events].last, action:'call', forControlEvents: events)
    end
  end

  Constants.register(
    UIControlEventTouchDown,
    UIControlEventTouchDownRepeat,
    UIControlEventTouchDragInside,
    UIControlEventTouchDragOutside,
    UIControlEventTouchDragEnter,
    UIControlEventTouchDragExit,
    UIControlEventTouchUpInside,
    UIControlEventTouchUpOutside,
    UIControlEventTouchCancel,

    UIControlEventValueChanged,

    UIControlEventEditingDidBegin,
    UIControlEventEditingChanged,
    UIControlEventEditingDidEnd,
    UIControlEventEditingDidEndOnExit,

    UIControlEventAllTouchEvents,
    UIControlEventAllEditingEvents,
    # UIControlEventApplicationReserved,
    
Download .txt
gitextract_83mw8g5j/

├── .gitignore
├── .travis.yml
├── .yardopts
├── CHANGELOG.md
├── GEM.md
├── GETTING_STARTED.md
├── Gemfile
├── HACKING.md
├── LICENSE
├── README.md
├── Rakefile
├── bubble-wrap.gemspec
├── lib/
│   ├── bubble-wrap/
│   │   ├── all.rb
│   │   ├── camera.rb
│   │   ├── core.rb
│   │   ├── ext/
│   │   │   └── motion_project_app.rb
│   │   ├── ext.rb
│   │   ├── font.rb
│   │   ├── loader.rb
│   │   ├── location.rb
│   │   ├── mail.rb
│   │   ├── media.rb
│   │   ├── motion.rb
│   │   ├── network-indicator.rb
│   │   ├── reactor.rb
│   │   ├── requirement/
│   │   │   └── path_manipulation.rb
│   │   ├── requirement.rb
│   │   ├── rss_parser.rb
│   │   ├── sms.rb
│   │   ├── test.rb
│   │   ├── ui.rb
│   │   └── version.rb
│   └── bubble-wrap.rb
├── motion/
│   ├── core/
│   │   ├── app.rb
│   │   ├── device/
│   │   │   ├── ios/
│   │   │   │   ├── camera.rb
│   │   │   │   ├── camera_wrapper.rb
│   │   │   │   └── screen.rb
│   │   │   ├── osx/
│   │   │   │   └── screen.rb
│   │   │   └── screen.rb
│   │   ├── device.rb
│   │   ├── ios/
│   │   │   ├── app.rb
│   │   │   ├── device.rb
│   │   │   └── ns_index_path.rb
│   │   ├── json.rb
│   │   ├── kvo.rb
│   │   ├── ns_index_path.rb
│   │   ├── ns_notification_center.rb
│   │   ├── ns_url_request.rb
│   │   ├── ns_user_defaults.rb
│   │   ├── osx/
│   │   │   ├── app.rb
│   │   │   └── device.rb
│   │   ├── persistence.rb
│   │   ├── pollute.rb
│   │   ├── string.rb
│   │   └── time.rb
│   ├── core.rb
│   ├── font/
│   │   └── font.rb
│   ├── ios/
│   │   └── 8/
│   │       └── location_constants.rb
│   ├── location/
│   │   ├── location.rb
│   │   └── pollute.rb
│   ├── mail/
│   │   ├── mail.rb
│   │   └── result.rb
│   ├── media/
│   │   ├── media.rb
│   │   └── player.rb
│   ├── motion/
│   │   ├── accelerometer.rb
│   │   ├── device_motion.rb
│   │   ├── gyroscope.rb
│   │   ├── magnetometer.rb
│   │   └── motion.rb
│   ├── network-indicator/
│   │   └── network-indicator.rb
│   ├── reactor/
│   │   ├── default_deferrable.rb
│   │   ├── deferrable.rb
│   │   ├── dependent_deferrable.rb
│   │   ├── eventable.rb
│   │   ├── future.rb
│   │   ├── periodic_timer.rb
│   │   ├── queue.rb
│   │   ├── thread_aware_deferrable.rb
│   │   └── timer.rb
│   ├── reactor.rb
│   ├── rss_parser.rb
│   ├── shortcut.rb
│   ├── sms/
│   │   ├── result.rb
│   │   └── sms.rb
│   ├── test_suite_delegate.rb
│   ├── ui/
│   │   ├── pollute.rb
│   │   ├── ui_activity_view_controller_wrapper.rb
│   │   ├── ui_alert_view.rb
│   │   ├── ui_bar_button_item.rb
│   │   ├── ui_control_wrapper.rb
│   │   ├── ui_view_controller_wrapper.rb
│   │   └── ui_view_wrapper.rb
│   └── util/
│       ├── constants.rb
│       └── deprecated.rb
├── resources/
│   ├── Localizable.strings
│   └── atom.xml
├── samples/
│   ├── alert/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   └── controllers/
│   │   │       └── alert_view_controller.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── camera/
│   │   ├── Gemfile
│   │   ├── README.md
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   └── controllers/
│   │   │       └── camera_controller.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── gesture/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── README.md
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   ├── controllers/
│   │   │   │   └── drawing_view_controller.rb
│   │   │   ├── helpers/
│   │   │   │   └── drawing_helper.rb
│   │   │   └── views/
│   │   │       └── drawing/
│   │   │           ├── gesture_view.rb
│   │   │           └── rect_view.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── location/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── README.md
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   ├── controllers/
│   │   │   │   └── places_list_controller.rb
│   │   │   └── models/
│   │   │       └── places.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   ├── media/
│   │   ├── .gitignore
│   │   ├── Gemfile
│   │   ├── Rakefile
│   │   ├── app/
│   │   │   ├── app_delegate.rb
│   │   │   └── controllers/
│   │   │       └── play_controller.rb
│   │   └── spec/
│   │       └── main_spec.rb
│   └── osx/
│       ├── Gemfile
│       ├── Rakefile
│       ├── app/
│       │   ├── app_delegate.rb
│       │   └── menu.rb
│       ├── resources/
│       │   └── Credits.rtf
│       └── spec/
│           └── main_spec.rb
└── spec/
    ├── lib/
    │   ├── bubble-wrap/
    │   │   ├── ext/
    │   │   │   ├── motion_project_app_spec.rb
    │   │   │   └── motion_project_config_spec.rb
    │   │   ├── requirement/
    │   │   │   └── path_manipulation_spec.rb
    │   │   └── requirement_spec.rb
    │   ├── bubble-wrap_spec.rb
    │   └── motion_stub.rb
    └── motion/
        ├── core/
        │   ├── app_spec.rb
        │   ├── device/
        │   │   ├── ios/
        │   │   │   ├── camera_spec.rb
        │   │   │   ├── camera_wrapper_spec.rb
        │   │   │   ├── device_spec.rb
        │   │   │   └── screen_spec.rb
        │   │   └── osx/
        │   │       └── screen_spec.rb
        │   ├── device_spec.rb
        │   ├── ios/
        │   │   ├── app_spec.rb
        │   │   └── ns_index_path_spec.rb
        │   ├── json_spec.rb
        │   ├── kvo_spec.rb
        │   ├── ns_index_path_spec.rb
        │   ├── ns_notification_center_spec.rb
        │   ├── osx/
        │   │   └── app_spec.rb
        │   ├── persistence_spec.rb
        │   ├── string_spec.rb
        │   └── time_spec.rb
        ├── core_spec.rb
        ├── font/
        │   └── font_spec.rb
        ├── location/
        │   └── location_spec.rb
        ├── mail/
        │   ├── mail_spec.rb
        │   └── result_spec.rb
        ├── media/
        │   └── player_spec.rb
        ├── motion/
        │   └── core_motion_spec.rb
        ├── network-indicator/
        │   └── network_indicator_spec.rb
        ├── reactor/
        │   ├── deferrable_spec.rb
        │   ├── dependent_deferrable_spec.rb
        │   ├── eventable_spec.rb
        │   └── thread_aware_deferrable_spec.rb
        ├── reactor_spec.rb
        ├── rss_parser_spec.rb
        ├── sms/
        │   ├── result_spec.rb
        │   └── sms_spec.rb
        ├── ui/
        │   ├── pollute_spec.rb
        │   ├── ui_activity_view_controller_wrapper_spec.rb
        │   ├── ui_alert_view_spec.rb
        │   ├── ui_bar_button_item_spec.rb
        │   ├── ui_control_wrapper_spec.rb
        │   ├── ui_view_controller_wrapper_spec.rb
        │   └── ui_view_wrapper_spec.rb
        └── util/
            ├── constants_spec.rb
            └── deprecated_spec.rb
Download .txt
SYMBOL INDEX (690 symbols across 99 files)

FILE: lib/bubble-wrap/ext/motion_project_app.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Ext (line 2) | module Ext
      type BuildTask (line 3) | module BuildTask
        function extended (line 5) | def self.extended(base)
      type Config (line 22) | module Config
        function config_with_bubblewrap (line 23) | def config_with_bubblewrap
        function extended (line 29) | def self.extended(base)
      type Platforms (line 36) | module Platforms
        function osx? (line 37) | def osx?

FILE: lib/bubble-wrap/loader.rb
  type BubbleWrap (line 14) | module BubbleWrap
    function root (line 19) | def root
    function require (line 23) | def require(file_spec, &block)
    function require_ios (line 27) | def require_ios(requirement = nil, &callback)
    function require_osx (line 35) | def require_osx(requirement = nil, &callback)
    function before_config (line 43) | def before_config(app)
    function after_config (line 49) | def after_config(config)

FILE: lib/bubble-wrap/requirement.rb
  type BubbleWrap (line 3) | module BubbleWrap
    class Requirement (line 4) | class Requirement
      method initialize (line 11) | def initialize(file,root)
      method relative (line 16) | def relative
      method depends_on (line 20) | def depends_on(file_or_paths)
      method uses_framework (line 29) | def uses_framework(framework_name)
      method dependencies (line 33) | def dependencies
      method to_s (line 38) | def to_s
      method file_dependencies (line 42) | def file_dependencies
      method frameworks (line 46) | def frameworks
      method scan (line 54) | def scan(caller_location, file_spec, &block)
      method file (line 65) | def file(relative)
      method files (line 69) | def files(app_files=nil)
      method clear! (line 75) | def clear!
      method files_dependencies (line 79) | def files_dependencies
      method frameworks (line 87) | def frameworks(app_frameworks=nil)

FILE: lib/bubble-wrap/requirement/path_manipulation.rb
  type BubbleWrap (line 1) | module BubbleWrap
    class Requirement (line 2) | class Requirement
      type PathManipulation (line 3) | module PathManipulation
        function convert_caller_to_root_path (line 5) | def convert_caller_to_root_path(path)
        function convert_caller_to_path (line 11) | def convert_caller_to_path(string)
        function convert_to_absolute_path (line 20) | def convert_to_absolute_path(path)
        function strip_up_to_last_lib (line 24) | def strip_up_to_last_lib(path)
        function convert_to_relative (line 39) | def convert_to_relative(path,root)

FILE: lib/bubble-wrap/version.rb
  type BubbleWrap (line 1) | module BubbleWrap

FILE: motion/core.rb
  type BubbleWrap (line 1) | module BubbleWrap
    function rgb_color (line 5) | def rgb_color(r,g,b)
    function rgba_color (line 10) | def rgba_color(r,g,b,a)
    function localized_string (line 22) | def localized_string(key, value=nil)
    function p (line 27) | def p(arg)
    function create_uuid (line 31) | def create_uuid

FILE: motion/core/app.rb
  type BubbleWrap (line 3) | module BubbleWrap
    type App (line 4) | module App
      function documents_path (line 11) | def documents_path
      function resources_path (line 17) | def resources_path
      function notification_center (line 23) | def notification_center
      function user_cache (line 27) | def user_cache
      function run_after (line 35) | def run_after(delay,&block)
      function states (line 45) | def states
      function info_plist (line 49) | def info_plist
      function name (line 53) | def name
      function identifier (line 57) | def identifier
      function version (line 61) | def version
      function short_version (line 65) | def short_version
      function current_locale (line 70) | def current_locale
      function environment (line 80) | def environment
      function development? (line 84) | def development?
      function test? (line 88) | def test?
      function release? (line 92) | def release?
      function osx? (line 96) | def osx?
      function ios? (line 100) | def ios?

FILE: motion/core/device.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device
      function screen (line 6) | def screen
      function retina? (line 11) | def retina?

FILE: motion/core/device/ios/camera.rb
  type BubbleWrap (line 4) | module BubbleWrap
    type Device (line 5) | module Device
      class Camera (line 6) | class Camera
        type Error (line 7) | module Error
        method front (line 34) | def self.front
        method rear (line 39) | def self.rear
        method available? (line 44) | def self.available?
        method any (line 50) | def any
        method popover_from (line 56) | def popover_from(view)
        method initialize (line 61) | def initialize(location = :none)
        method location= (line 65) | def location=(location)
        method flash? (line 72) | def flash?
        method picture (line 99) | def picture(options = {}, presenting_controller = nil, &block)
        method popoverControllerDidDismissPopover (line 166) | def popoverControllerDidDismissPopover(popoverController)
        method imagePickerControllerDidCancel (line 172) | def imagePickerControllerDidCancel(picker)
        method imagePickerController (line 181) | def imagePickerController(picker, didFinishPickingMediaWithInfo: i...
        method picker (line 205) | def picker
        method dismiss (line 210) | def dismiss
        method source_type_available? (line 220) | def self.source_type_available?(source_type)
        method media_type_available? (line 226) | def self.media_type_available?(media_type, for_source_type: source...
        method camera_device (line 231) | def camera_device
        method media_type_to_symbol (line 236) | def media_type_to_symbol(media_type)
        method symbol_to_media_type (line 241) | def symbol_to_media_type(symbol)
        method error (line 245) | def error(type)

FILE: motion/core/device/ios/camera_wrapper.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device
      type CameraWrapper (line 3) | module CameraWrapper
        function front (line 9) | def front
        function front? (line 15) | def front?
        function rear (line 21) | def rear
        function rear? (line 27) | def rear?
        function any (line 34) | def any
        function photo_library (line 38) | def photo_library
        function any? (line 44) | def any?
        function available? (line 50) | def available?

FILE: motion/core/device/ios/screen.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device
      type Screen (line 3) | module Screen
        function retina? (line 9) | def retina?(screen=UIScreen.mainScreen)
        function orientation (line 19) | def orientation(device_orientation=UIDevice.currentDevice.orientat...
        function interface_orientation (line 40) | def interface_orientation(device_orientation=UIDevice.currentDevic...
        function width (line 63) | def width
        function height (line 73) | def height
        function width_for_orientation (line 80) | def width_for_orientation(o=orientation)
        function height_for_orientation (line 88) | def height_for_orientation(o=orientation)

FILE: motion/core/device/osx/screen.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device
      type Screen (line 3) | module Screen
        function retina? (line 9) | def retina?(screen=NSScreen.mainScreen)

FILE: motion/core/device/screen.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device
      type Screen (line 3) | module Screen

FILE: motion/core/ios/app.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type App (line 2) | module App
      function open_url (line 10) | def open_url(url)
      function can_open_url (line 21) | def can_open_url(url)
      function alert (line 38) | def alert(title, *args, &block)
      function frame (line 59) | def frame
      function bounds (line 64) | def bounds
      function delegate (line 69) | def delegate
      function shared (line 74) | def shared
      function windows (line 78) | def windows
      function window (line 83) | def window

FILE: motion/core/ios/device.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device
      function iphone? (line 7) | def iphone?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
      function ipad? (line 13) | def ipad?(idiom=UIDevice.currentDevice.userInterfaceIdiom)
      function long_screen? (line 19) | def long_screen?(idiom=UIDevice.currentDevice.userInterfaceIdiom, sc...
      function camera (line 26) | def camera
      function front_camera? (line 32) | def front_camera?(picker=UIImagePickerController)
      function rear_camera? (line 39) | def rear_camera?(picker=UIImagePickerController)
      function simulator? (line 46) | def simulator?
      function force_touch? (line 56) | def force_touch?
      function ios_version (line 66) | def ios_version
      function vendor_identifier (line 72) | def vendor_identifier
      function orientation (line 77) | def orientation
      function interface_orientation (line 82) | def interface_orientation

FILE: motion/core/ios/ns_index_path.rb
  type NSIndexPathWrap (line 1) | module NSIndexPathWrap
    function + (line 3) | def +(aNumber)
    function - (line 7) | def -(aNumber)

FILE: motion/core/json.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type JSON (line 4) | module JSON
      class ParserError (line 6) | class ParserError < StandardError; end
      function parse (line 15) | def self.parse(str_data, &block)
      function generate (line 30) | def self.generate(obj)

FILE: motion/core/kvo.rb
  type BubbleWrap (line 19) | module BubbleWrap
    type KVO (line 20) | module KVO
      class Registry (line 21) | class Registry
        method initialize (line 30) | def initialize(value_keys = [:old, :new])
        method add (line 48) | def add(target, key_path, &block)
        method remove (line 56) | def remove(target, key_path)
        method registered? (line 69) | def registered?(target, key_path)
        method remove_all (line 73) | def remove_all
        method each_key_path (line 77) | def each_key_path
        method observeValueForKeyPath (line 87) | def observeValueForKeyPath(key_path, ofObject: target, change: cha...
      function observe (line 103) | def observe(target = self, key_paths, &block)
      function observe! (line 116) | def observe!(target = self, key_paths, &block)
      function unobserve (line 132) | def unobserve(target = self, key_paths)
      function unobserve! (line 136) | def unobserve!(target = self, key_paths)
      function unobserve_all (line 140) | def unobserve_all
      function observers_registry (line 154) | def observers_registry
      function immediate_observers_registry (line 158) | def immediate_observers_registry
      function remove_from_registry_if_exists (line 162) | def remove_from_registry_if_exists(target, key_paths, registry)

FILE: motion/core/ns_index_path.rb
  type NSIndexPathWrap (line 1) | module NSIndexPathWrap
    function [] (line 6) | def [](position)
    function each (line 14) | def each

FILE: motion/core/ns_notification_center.rb
  class NSNotificationCenter (line 1) | class NSNotificationCenter
    method observers (line 2) | def observers
    method observe (line 6) | def observe(name, object=nil, &proc)
    method unobserve (line 13) | def unobserve(observer)
    method post (line 19) | def post(name, object=nil, info=nil)

FILE: motion/core/ns_url_request.rb
  class NSURLRequest (line 1) | class NSURLRequest
    method to_s (line 5) | def to_s

FILE: motion/core/ns_user_defaults.rb
  class NSUserDefaults (line 3) | class NSUserDefaults
    method [] (line 6) | def [](key)
    method []= (line 11) | def []=(key, val)

FILE: motion/core/osx/app.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type App (line 2) | module App
      function open_url (line 9) | def open_url(url)
      function delegate (line 15) | def delegate
      function shared (line 20) | def shared

FILE: motion/core/osx/device.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Device (line 2) | module Device

FILE: motion/core/persistence.rb
  type BubbleWrap (line 2) | module BubbleWrap
    type Persistence (line 3) | module Persistence
      function app_key (line 6) | def app_key
      function []= (line 10) | def []=(key, value)
      function [] (line 15) | def [](key)
      function merge (line 25) | def merge(values)
      function delete (line 32) | def delete(key)
      function storage (line 39) | def storage
      function storage_key (line 43) | def storage_key(key)
      function all (line 47) | def all

FILE: motion/core/string.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type String (line 5) | module String
      function camelize (line 8) | def camelize(uppercase_first_letter = true)
      function underscore (line 26) | def underscore
      function to_url_encoded (line 36) | def to_url_encoded(encoding = nil, legacy = false)
      function to_url_decoded (line 46) | def to_url_decoded(encoding = nil, legacy = false)
      function to_encoded_data (line 59) | def to_encoded_data(encoding = NSUTF8StringEncoding)
      function to_color (line 63) | def to_color

FILE: motion/core/time.rb
  class Time (line 1) | class Time
    method iso8601 (line 3) | def self.iso8601(time)
    method iso8601_zulu (line 21) | def self.iso8601_zulu(time)
    method iso8601_with_timezone (line 26) | def self.iso8601_with_timezone(time)
    method iso8601_with_fractional_seconds (line 31) | def self.iso8601_with_fractional_seconds(time)
    method iso8601_with_fractional_seconds_and_timesone (line 36) | def self.iso8601_with_fractional_seconds_and_timesone(time)
    method cached_date_formatter (line 43) | def self.cached_date_formatter(dateFormat)

FILE: motion/font/font.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Font (line 2) | module Font
      function bold (line 5) | def bold(size = nil)
      function system (line 9) | def system(size = nil)
      function italic (line 13) | def italic(size = nil)
      function new (line 23) | def new(params = {}, *args)
      function attributes (line 69) | def attributes(params = {})

FILE: motion/ios/8/location_constants.rb
  type BW (line 1) | module BW
    type Location (line 10) | module Location
      function authorized? (line 13) | def authorized?

FILE: motion/location/location.rb
  type BubbleWrap (line 4) | module BubbleWrap
    type CLLocationWrap (line 5) | module CLLocationWrap
      function latitude (line 7) | def latitude
      function longitude (line 11) | def longitude
    type Location (line 16) | module Location
      type Error (line 17) | module Error
      function get (line 57) | def get(options = {}, &block)
      function get_significant (line 93) | def get_significant(options = {}, &block)
      function get_once (line 122) | def get_once(options = {}, &block)
      function get_compass (line 126) | def get_compass(options = {}, &block)
      function get_compass_once (line 130) | def get_compass_once(options = {}, &block)
      function start (line 135) | def start
      function stop (line 147) | def stop
      function location_manager (line 158) | def location_manager
      function enabled? (line 165) | def enabled?
      function initialized? (line 170) | def initialized?
      function authorized? (line 175) | def authorized?
      function error (line 181) | def error(type)
      function locationManager (line 189) | def locationManager(manager, didUpdateLocations:locations)
      function locationManager (line 205) | def locationManager(manager, didUpdateHeading:newHeading)
      function locationManager (line 222) | def locationManager(manager, didFailWithError:error)
      function locationManager (line 243) | def locationManager(manager, didChangeAuthorizationStatus:status)
      function locationManagerShouldDisplayHeadingCalibration (line 252) | def locationManagerShouldDisplayHeadingCalibration(manager)

FILE: motion/mail/mail.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Mail (line 2) | module Mail
      function compose (line 25) | def compose(options = {}, &callback)
      function create_mail_controller (line 46) | def create_mail_controller(options = {})
      function can_send_mail? (line 65) | def can_send_mail?
      function mailComposeController (line 73) | def mailComposeController(controller, didFinishWithResult: result, e...

FILE: motion/mail/result.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Mail (line 2) | module Mail
      class Result (line 3) | class Result
        method initialize (line 6) | def initialize(result, error)
        method sent? (line 11) | def sent?
        method canceled? (line 15) | def canceled?
        method saved? (line 19) | def saved?
        method failed? (line 23) | def failed?

FILE: motion/media/media.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Media (line 2) | module Media
      function play_modal (line 5) | def play_modal(*args, &block)
      function play (line 9) | def play(*args, &block)

FILE: motion/media/player.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Media (line 2) | module Media
      type Error (line 3) | module Error
        class InvalidPlayerType (line 4) | class InvalidPlayerType < StandardError; end
        class NilPlayerCallback (line 5) | class NilPlayerCallback < StandardError; end
      class Player (line 8) | class Player
        method play_modal (line 17) | def play_modal(content_url, options = {})
        method play (line 66) | def play(content_url, options = {}, &block)
        method stop (line 114) | def stop
        method media_player (line 128) | def media_player
        method set_player_options (line 138) | def set_player_options(options)

FILE: motion/motion/accelerometer.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Motion (line 2) | module Motion
      class Accelerometer (line 3) | class Accelerometer < GenericMotionInterface
        method start (line 5) | def start(options={}, &handler)
        method handle_result (line 20) | def handle_result(result_data, error, handler)
        method available? (line 36) | def available?
        method active? (line 40) | def active?
        method data (line 44) | def data
        method stop (line 48) | def stop

FILE: motion/motion/device_motion.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Motion (line 2) | module Motion
      class DeviceMotion (line 3) | class DeviceMotion < GenericMotionInterface
        method start (line 5) | def start(options={}, &handler)
        method handle_result (line 35) | def handle_result(result_data, error, handler)
        method convert_reference_frame (line 105) | def convert_reference_frame(reference_frame)
        method available? (line 120) | def available?
        method active? (line 124) | def active?
        method data (line 128) | def data
        method stop (line 132) | def stop

FILE: motion/motion/gyroscope.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Motion (line 2) | module Motion
      class Gyroscope (line 3) | class Gyroscope < GenericMotionInterface
        method start (line 5) | def start(options={}, &handler)
        method handle_result (line 20) | def handle_result(result_data, error, handler)
        method available? (line 36) | def available?
        method active? (line 40) | def active?
        method data (line 44) | def data
        method stop (line 48) | def stop

FILE: motion/motion/magnetometer.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Motion (line 2) | module Motion
      class Magnetometer (line 3) | class Magnetometer < GenericMotionInterface
        method start (line 5) | def start(options={}, &handler)
        method handle_result (line 20) | def handle_result(result_data, error, handler)
        method available? (line 36) | def available?
        method active? (line 40) | def active?
        method data (line 44) | def data
        method stop (line 48) | def stop

FILE: motion/motion/motion.rb
  type BubbleWrap (line 3) | module BubbleWrap
    type Motion (line 30) | module Motion
      function manager (line 33) | def manager
      function accelerometer (line 37) | def accelerometer
      function gyroscope (line 41) | def gyroscope
      function magnetometer (line 45) | def magnetometer
      function device (line 49) | def device
      type Error (line 56) | module Error
      class GenericMotionInterface (line 59) | class GenericMotionInterface
        method initialize (line 61) | def initialize(manager)
        method repeat (line 65) | def repeat(options={}, &blk)
        method every (line 73) | def every(time=nil, options={}, &blk)
        method once (line 87) | def once(options={}, &blk)
        method convert_queue (line 103) | def convert_queue(queue_name)
        method internal_handler (line 122) | def internal_handler(handler)
    type Motion (line 55) | module Motion
      function manager (line 33) | def manager
      function accelerometer (line 37) | def accelerometer
      function gyroscope (line 41) | def gyroscope
      function magnetometer (line 45) | def magnetometer
      function device (line 49) | def device
      type Error (line 56) | module Error
      class GenericMotionInterface (line 59) | class GenericMotionInterface
        method initialize (line 61) | def initialize(manager)
        method repeat (line 65) | def repeat(options={}, &blk)
        method every (line 73) | def every(time=nil, options={}, &blk)
        method once (line 87) | def once(options={}, &blk)
        method convert_queue (line 103) | def convert_queue(queue_name)
        method internal_handler (line 122) | def internal_handler(handler)

FILE: motion/network-indicator/network-indicator.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type NetworkIndicator (line 2) | module NetworkIndicator
      function counter (line 7) | def counter
      function show (line 11) | def show
      function hide (line 22) | def hide
      function update_spinner_timer (line 39) | def update_spinner_timer
      function update_spinner (line 43) | def update_spinner
      function visible? (line 57) | def visible?
      function reset! (line 61) | def reset!

FILE: motion/reactor.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      function reactor_running? (line 6) | def reactor_running?
      function add_timer (line 14) | def add_timer(interval, callback=nil, &blk)
      function cancel_timer (line 30) | def cancel_timer(timer)
      function add_periodic_timer (line 45) | def add_periodic_timer(interval, *args, &blk)
      function defer (line 70) | def defer(op=nil,cb=nil,&blk)
      function defer_on_main (line 79) | def defer_on_main(op=nil,cb=nil,&blk)
      function schedule (line 87) | def schedule(*args, &blk)
      function schedule_on_main (line 101) | def schedule_on_main(*args, &blk)

FILE: motion/reactor/default_deferrable.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      class DefaultDeferrable (line 5) | class DefaultDeferrable

FILE: motion/reactor/deferrable.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      type Deferrable (line 4) | module Deferrable
        function callback (line 18) | def callback(&blk)
        function cancel_timeout (line 30) | def cancel_timeout
        function errback (line 41) | def errback(&blk)
        function execute_block (line 53) | def execute_block(&blk)
        function delegate (line 58) | def delegate(delegate)
        function errback_delegate (line 64) | def errback_delegate(delegate)
        function callback_delegate (line 71) | def callback_delegate(delegate)
        function fail (line 79) | def fail(*args)
        function set_deferred_status (line 110) | def set_deferred_status(status, *args)
        function succeed (line 135) | def succeed(*args)
        function timeout (line 144) | def timeout(seconds)
        function deferred_status (line 150) | def deferred_status
        function deferred_args (line 154) | def deferred_args

FILE: motion/reactor/dependent_deferrable.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      class DependentDeferrable (line 3) | class DependentDeferrable < DefaultDeferrable
        method on (line 10) | def self.on(*args)

FILE: motion/reactor/eventable.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      type Eventable (line 4) | module Eventable
        function on (line 9) | def on(event, method = nil, &blk)
        function off (line 17) | def off(event, method = nil, &blk)
        function trigger (line 30) | def trigger(event, *args)
        function __events__ (line 39) | def __events__
        function _events_for_key (line 43) | def _events_for_key(event)

FILE: motion/reactor/future.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      type Future (line 3) | module Future
        function future (line 6) | def future arg, cb=nil, eb=nil, &blk

FILE: motion/reactor/periodic_timer.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      class PeriodicTimer (line 4) | class PeriodicTimer
        method initialize (line 10) | def initialize(interval, *args, &blk)
        method cancel (line 31) | def cancel

FILE: motion/reactor/queue.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      class Queue (line 15) | class Queue
        method initialize (line 18) | def initialize
        method empty? (line 23) | def empty?
        method size (line 28) | def size
        method push (line 34) | def push(*items)
        method pop (line 44) | def pop(*args, &blk)

FILE: motion/reactor/thread_aware_deferrable.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      class ThreadAwareDeferrable (line 3) | class ThreadAwareDeferrable < DefaultDeferrable
        method callback (line 8) | def callback(&blk)
        method errback (line 14) | def errback(&blk)
        method execute_block (line 20) | def execute_block(&blk)
        method cache_block_queue (line 29) | def cache_block_queue(&blk)

FILE: motion/reactor/timer.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Reactor (line 2) | module Reactor
      class Timer (line 4) | class Timer
        method initialize (line 8) | def initialize(leeway, callback=nil, &blk)
        method cancel (line 21) | def cancel

FILE: motion/rss_parser.rb
  type BubbleWrap (line 22) | module BubbleWrap
    class RSSParser (line 23) | class RSSParser
      class RSSItem (line 30) | class RSSItem
        method initialize (line 33) | def initialize
        method to_hash (line 37) | def to_hash
      method initialize (line 51) | def initialize(input, data=false)
      method state= (line 64) | def state=(new_state)
      method parse (line 78) | def parse(&block)
      method parserDidStartDocument (line 94) | def parserDidStartDocument(parser)
      method parser (line 100) | def parser(parser, didStartElement:element, namespaceURI:uri, qualif...
      method parser (line 110) | def parser(parser, foundCharacters:string)
      method parser (line 118) | def parser(parser, didEndElement:element, namespaceURI:uri, qualifie...
      method parser (line 128) | def parser(parser, parseErrorOccurred:parse_error)
      method parserDidEndDocument (line 137) | def parserDidEndDocument(parser)
      method parserError (line 142) | def parserError

FILE: motion/shortcut.rb
  type BubbleWrap (line 5) | module BubbleWrap
    function debug= (line 8) | def self.debug=(val)
    function debug? (line 12) | def self.debug?
    function use_weak_callbacks= (line 16) | def self.use_weak_callbacks=(val)
    function use_weak_callbacks? (line 20) | def self.use_weak_callbacks?
    function version (line 24) | def version

FILE: motion/sms/result.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type SMS (line 2) | module SMS
      class Result (line 3) | class Result
        method initialize (line 6) | def initialize(result)
        method sent? (line 10) | def sent?
        method canceled? (line 14) | def canceled?
        method failed? (line 18) | def failed?

FILE: motion/sms/sms.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type SMS (line 2) | module SMS
      function compose (line 22) | def compose(options = {}, &callback)
      function create_message_controller (line 32) | def create_message_controller(options = {})
      function can_send_sms? (line 40) | def can_send_sms?
      function messageComposeViewController (line 48) | def messageComposeViewController(controller, didFinishWithResult: re...

FILE: motion/test_suite_delegate.rb
  class TestSuiteDelegate (line 1) | class TestSuiteDelegate
    method application (line 4) | def application(application, didFinishLaunchingWithOptions:launchOptions)
  class TestSuiteOSXDelegate (line 12) | class TestSuiteOSXDelegate
    method applicationDidFinishLaunching (line 13) | def applicationDidFinishLaunching(notification)
    method buildWindow (line 18) | def buildWindow
    method buildMenu (line 26) | def buildMenu
    method addMenu (line 55) | def addMenu(title, &b)
    method createMenu (line 61) | def createMenu(title, &b)

FILE: motion/ui/ui_activity_view_controller_wrapper.rb
  type BW (line 1) | module BW
    class UIActivityViewController (line 2) | class UIActivityViewController < ::UIActivityViewController
      method new (line 4) | def new(options = {}, presenting_controller = nil, &block)

FILE: motion/ui/ui_alert_view.rb
  type BW (line 1) | module BW
    class UIAlertView (line 2) | class UIAlertView < ::UIAlertView
      method new (line 32) | def new(options = {}, &block)
      method default (line 58) | def default(options = {}, &block)
      method plain_text_input (line 64) | def plain_text_input(options = {}, &block)
      method secure_text_input (line 77) | def secure_text_input(options = {}, &block)
      method login_and_password_input (line 84) | def login_and_password_input(options = {}, &block)
      method style (line 92) | def style
      method style= (line 96) | def style=(value)
      method cancel_button_index (line 100) | def cancel_button_index
      method cancel_button_index= (line 104) | def cancel_button_index=(value)
      class ClickedButton (line 113) | class ClickedButton
        method initialize (line 114) | def initialize(alert, index)
        method cancel? (line 121) | def cancel?; @cancel end
      method willPresentAlertView (line 140) | def willPresentAlertView(alert)
      method didPresentAlertView (line 145) | def didPresentAlertView(alert)
      method alertViewCancel (line 150) | def alertViewCancel(alert)
      method alertViewShouldEnableFirstOtherButton (line 155) | def alertViewShouldEnableFirstOtherButton(alert)
      method alertView (line 160) | def alertView(alert, clickedButtonAtIndex:index)
      method alertView (line 165) | def alertView(alert, willDismissWithButtonIndex:index)
      method alertView (line 170) | def alertView(alert, didDismissWithButtonIndex:index)
      method plain_text_field (line 177) | def plain_text_field
      method secure_text_field (line 181) | def secure_text_field
      method login_text_field (line 185) | def login_text_field
      method password_text_field (line 189) | def password_text_field

FILE: motion/ui/ui_bar_button_item.rb
  type BW (line 1) | module BW
    class UIBarButtonItem (line 2) | class UIBarButtonItem < ::UIBarButtonItem
      method styled (line 4) | def styled(type, *objects, &block)
      method system (line 41) | def system(type, &block)
      method custom (line 55) | def custom(view, &block)
      method new (line 60) | def new(options = {}, &block)
      method build (line 74) | def build(options = {}, &block)

FILE: motion/ui/ui_control_wrapper.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type UIControlWrapper (line 2) | module UIControlWrapper
      function when (line 3) | def when(events, options = {}, &block)

FILE: motion/ui/ui_view_controller_wrapper.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type UIViewControllerWrapper (line 2) | module UIViewControllerWrapper
      function content_frame (line 6) | def content_frame

FILE: motion/ui/ui_view_wrapper.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type UIViewWrapper (line 2) | module UIViewWrapper
      function when_tapped (line 3) | def when_tapped(enableInteraction=true, &proc)
      function when_pinched (line 7) | def when_pinched(enableInteraction=true, &proc)
      function when_rotated (line 11) | def when_rotated(enableInteraction=true, &proc)
      function when_swiped (line 15) | def when_swiped(enableInteraction=true, &proc)
      function when_panned (line 19) | def when_panned(enableInteraction=true, &proc)
      function when_screen_edge_panned (line 23) | def when_screen_edge_panned(enableInteraction=true, &proc)
      function when_pressed (line 27) | def when_pressed(enableInteraction=true, &proc)
      function deprecated_methods (line 31) | def self.deprecated_methods
      function handle_gesture (line 44) | def handle_gesture(recognizer)
      function add_gesture_recognizer_helper (line 49) | def add_gesture_recognizer_helper(recognizer, enableInteraction, proc)

FILE: motion/util/constants.rb
  type BubbleWrap (line 2) | module BubbleWrap
    type Constants (line 3) | module Constants
      function register (line 12) | def register(*ui_constants)
      function get (line 26) | def get(base, *values)

FILE: motion/util/deprecated.rb
  type BubbleWrap (line 1) | module BubbleWrap
    type Deprecated (line 2) | module Deprecated
      class DeprecatedError (line 4) | class DeprecatedError < StandardError; end
      function deprecated (line 6) | def deprecated(method_sym, version)
      function included (line 38) | def self.included(base)

FILE: samples/alert/app/app_delegate.rb
  class AppDelegate (line 1) | class AppDelegate
    method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)

FILE: samples/alert/app/controllers/alert_view_controller.rb
  class AlertViewController (line 1) | class AlertViewController < UIViewController
    method init (line 6) | def init
    method viewDidLoad (line 20) | def viewDidLoad
    method build_text_view (line 34) | def build_text_view
    method build_button (line 41) | def build_button(title)
    method built_alert (line 51) | def built_alert(method)
    method build_callback (line 63) | def build_callback(name, method)

FILE: samples/camera/app/app_delegate.rb
  class AppDelegate (line 1) | class AppDelegate
    method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)

FILE: samples/camera/app/controllers/camera_controller.rb
  class CameraController (line 1) | class CameraController < UIViewController
    method init (line 4) | def init
    method viewDidLoad (line 10) | def viewDidLoad
    method build_button (line 18) | def build_button(title, camera_method)
    method build_image_view (line 40) | def build_image_view(image)

FILE: samples/gesture/app/app_delegate.rb
  class AppDelegate (line 1) | class AppDelegate
    method application (line 4) | def application(application, didFinishLaunchingWithOptions:launchOptions)
    method setup_window (line 10) | def setup_window

FILE: samples/gesture/app/controllers/drawing_view_controller.rb
  class DrawingViewController (line 1) | class DrawingViewController < UIViewController
    method loadView (line 4) | def loadView

FILE: samples/gesture/app/helpers/drawing_helper.rb
  type DrawingHelper (line 1) | module DrawingHelper

FILE: samples/gesture/app/views/drawing/gesture_view.rb
  class GestureView (line 1) | class GestureView < UIView
    method initWithCoder (line 4) | def initWithCoder(coder)
    method initWithFrame (line 10) | def initWithFrame(coder)
    method gestureRecognizer (line 19) | def gestureRecognizer(recognizer, shouldRecognizeSimultaneouslyWithGes...
    method setup (line 35) | def setup
    method setup_gesture (line 42) | def setup_gesture
    method reset_transformation (line 85) | def reset_transformation

FILE: samples/gesture/app/views/drawing/rect_view.rb
  class RectView (line 1) | class RectView < GestureView
    method drawRect (line 2) | def drawRect(rect)

FILE: samples/location/app/app_delegate.rb
  class AppDelegate (line 1) | class AppDelegate
    method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)

FILE: samples/location/app/controllers/places_list_controller.rb
  class PlacesListController (line 1) | class PlacesListController < UITableViewController
    method viewDidLoad (line 4) | def viewDidLoad
    method viewWillAppear (line 10) | def viewWillAppear(animated)
    method tableView (line 14) | def tableView(tableView, numberOfRowsInSection:section)
    method reloadData (line 18) | def reloadData
    method tableView (line 23) | def tableView(tableView, cellForRowAtIndexPath:indexPath)

FILE: samples/location/app/models/places.rb
  class Places (line 1) | class Places
    method load (line 5) | def self.load(places_list_controller)

FILE: samples/media/app/app_delegate.rb
  class AppDelegate (line 1) | class AppDelegate
    method application (line 2) | def application(application, didFinishLaunchingWithOptions:launchOptions)

FILE: samples/media/app/controllers/play_controller.rb
  class PlayController (line 1) | class PlayController < UIViewController
    method init (line 4) | def init
    method viewDidLoad (line 10) | def viewDidLoad
    method build_button (line 18) | def build_button(title, callback)
    method local_file (line 32) | def local_file
    method tapped_modal (line 36) | def tapped_modal
    method tapped_frame (line 40) | def tapped_frame

FILE: samples/osx/app/app_delegate.rb
  class AppDelegate (line 1) | class AppDelegate
    method applicationDidFinishLaunching (line 2) | def applicationDidFinishLaunching(notification)
    method buildWindow (line 7) | def buildWindow
    method fetch_ip (line 34) | def fetch_ip
    method make_button (line 43) | def make_button(title)
    method make_label (line 52) | def make_label(text)
    method add_constraint (line 64) | def add_constraint(ascii, params = {})

FILE: samples/osx/app/menu.rb
  class AppDelegate (line 1) | class AppDelegate
    method buildMenu (line 2) | def buildMenu
    method addMenu (line 95) | def addMenu(title, &b)
    method createMenu (line 101) | def createMenu(title, &b)

FILE: spec/lib/bubble-wrap/ext/motion_project_app_spec.rb
  function setup (line 9) | def self.setup; end
  function configs (line 10) | def self.configs

FILE: spec/lib/bubble-wrap/ext/motion_project_config_spec.rb
  function initialize (line 9) | def initialize
  function files_dependencies (line 14) | def files_dependencies

FILE: spec/lib/motion_stub.rb
  type Motion (line 2) | module Motion
    type Project (line 3) | module Project
      class App (line 4) | class App
        method setup (line 5) | def self.setup
      class Config (line 9) | class Config
        method files_dependencies (line 10) | def files_dependencies

FILE: spec/motion/core/app_spec.rb
  class DelayedRunAfterTest (line 70) | class DelayedRunAfterTest; attr_accessor :test_value end
  function url (line 91) | def application.url; @url end
  function openURL (line 92) | def application.openURL(url); @url = url end

FILE: spec/motion/core/device/ios/camera_spec.rb
  function camera_picker (line 1) | def camera_picker
  function example_info (line 5) | def example_info
  function presentViewController (line 15) | def presentViewController(*args)
  function isCameraDeviceAvailable (line 25) | def self.isCameraDeviceAvailable(c)
  function isFlashAvailableForCameraDevice (line 29) | def self.isFlashAvailableForCameraDevice(c)
  class FakePickerClass (line 58) | class FakePickerClass
    method isCameraDeviceAvailable (line 59) | def self.isCameraDeviceAvailable(c)
    method isSourceTypeAvailable (line 63) | def self.isSourceTypeAvailable(c)
    method availableMediaTypesForSourceType (line 67) | def self.availableMediaTypesForSourceType(c)
    method dismissViewControllerAnimated (line 71) | def dismissViewControllerAnimated(*args)
    method method_missing (line 75) | def self.method_missing(*args)

FILE: spec/motion/core/device/ios/camera_wrapper_spec.rb
  function isCameraDeviceAvailable (line 11) | def isCameraDeviceAvailable(c)
  function isSourceTypeAvailable (line 14) | def isSourceTypeAvailable(c)
  function isCameraDeviceAvailable (line 42) | def isCameraDeviceAvailable(c)
  function isSourceTypeAvailable (line 45) | def isSourceTypeAvailable(c)
  function isCameraDeviceAvailable (line 73) | def isCameraDeviceAvailable(c)
  function isSourceTypeAvailable (line 76) | def isSourceTypeAvailable(c)

FILE: spec/motion/core/device/ios/screen_spec.rb
  function respondsToSelector (line 6) | def o.respondsToSelector(selector)
  function scale (line 10) | def o.scale
  function method_missing (line 13) | def o.method_missing(*args)
  function respondsToSelector (line 29) | def o.respondsToSelector(selector)
  function scale (line 33) | def o.scale
  function method_missing (line 36) | def o.method_missing(*args)

FILE: spec/motion/core/device/osx/screen_spec.rb
  function respondsToSelector (line 6) | def o.respondsToSelector(selector)
  function backingScaleFactor (line 10) | def o.backingScaleFactor
  function method_missing (line 13) | def o.method_missing(*args)

FILE: spec/motion/core/ios/app_spec.rb
  class DelayedRunAfterTest (line 181) | class DelayedRunAfterTest; attr_accessor :test_value end
  function url (line 198) | def application.url; @url end
  function canOpenURL (line 199) | def application.canOpenURL(url); @url = url; super; end

FILE: spec/motion/core/kvo_spec.rb
  class KvoExample (line 3) | class KvoExample
    method initialize (line 10) | def initialize
    method get_text (line 21) | def get_text
    method set_text (line 25) | def set_text(text)
    method observe_label (line 29) | def observe_label(&block)
    method observe_label! (line 33) | def observe_label!(&block)
    method observe_collection (line 37) | def observe_collection(&block)
    method unobserve_label (line 41) | def unobserve_label
    method unobserve_label! (line 45) | def unobserve_label!
    method text_method_name (line 49) | def text_method_name
    method text_class (line 53) | def text_class
    method update_collection (line 57) | def update_collection

FILE: spec/motion/core/persistence_spec.rb
  function synchronize (line 28) | def storage.synchronize; @sync_was_called = true; end
  function synchronize (line 48) | def storage.synchronize; @sync_was_called = true; end
  function synchronize (line 99) | def storage.synchronize; @sync_was_called = true; end

FILE: spec/motion/location/location_spec.rb
  class BWCLHeading (line 10) | class BWCLHeading
  class CLLocationManager (line 14) | class CLLocationManager
    method enable (line 15) | def self.enable(enable)
    method authorize (line 19) | def self.authorize(authorize)
    method locationServicesEnabled (line 23) | def self.locationServicesEnabled
    method authorizationStatus (line 28) | def self.authorizationStatus
    method startUpdatingLocation (line 33) | def startUpdatingLocation
    method stopUpdatingLocation (line 37) | def stopUpdatingLocation
    method startUpdatingHeading (line 41) | def startUpdatingHeading
    method stopUpdatingHeading (line 45) | def stopUpdatingHeading
    method startMonitoringSignificantLocationChanges (line 49) | def startMonitoringSignificantLocationChanges
    method stopMonitoringSignificantLocationChanges (line 53) | def stopMonitoringSignificantLocationChanges
  function location_manager (line 58) | def location_manager
  function reset (line 62) | def reset

FILE: spec/motion/mail/mail_spec.rb
  class MailViewController (line 2) | class MailViewController < UIViewController
    method presentViewController (line 5) | def presentViewController(modal, animated: animated, completion: compl...
  class MFMailComposeViewController (line 14) | class MFMailComposeViewController
    method setToRecipients (line 17) | def setToRecipients(r)
    method setCcRecipients (line 21) | def setCcRecipients(r)
    method setBccRecipients (line 25) | def setBccRecipients(r)
    method setSubject (line 29) | def setSubject(r)
    method setMessageBody (line 33) | def setMessageBody(message, isHTML: html)

FILE: spec/motion/reactor/eventable_spec.rb
  function bar (line 20) | def bar; end
  function bar (line 43) | def bar; end
  function bar (line 52) | def bar; end
  function bar (line 105) | def bar(r)
  function bar (line 124) | def bar(r)
  function bar (line 142) | def bar(r); @proxy.proof += r; end
  function baz (line 143) | def baz(r); @proxy.proof += r; end
  class TestUIViewControllerWithEventable (line 151) | class TestUIViewControllerWithEventable
    method test_on (line 153) | def test_on
    method bar (line 159) | def bar
    method dealloc (line 162) | def dealloc

FILE: spec/motion/sms/sms_spec.rb
  class MessageViewController (line 2) | class MessageViewController < UIViewController
    method presentModalViewController (line 5) | def presentModalViewController(modal, animated: animated)
  class MFMessageComposeViewController (line 14) | class MFMessageComposeViewController
    method init (line 19) | def init

FILE: spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb
  function presentViewController (line 5) | def presentViewController(*args)

FILE: spec/motion/ui/ui_bar_button_item_spec.rb
  class NavigationItemContainingBarButtonItem (line 2) | class NavigationItemContainingBarButtonItem < UINavigationItem
    method init_with_styled (line 3) | def init_with_styled
    method tag= (line 12) | def tag=(value)
    method init_with_system (line 16) | def init_with_system
    method dealloc (line 25) | def dealloc

FILE: spec/motion/ui/ui_control_wrapper_spec.rb
  class ControlSuperView (line 42) | class ControlSuperView < UIView
    method initWithFrame (line 43) | def initWithFrame(frame)
    method dealloc (line 53) | def dealloc

FILE: spec/motion/ui/ui_view_wrapper_spec.rb
  class ViewSuperView (line 67) | class ViewSuperView < UIView
    method initWithFrame (line 68) | def initWithFrame(frame)
    method dealloc (line 78) | def dealloc

FILE: spec/motion/util/deprecated_spec.rb
  type ModuleExample (line 1) | module ModuleExample
    function a_method (line 6) | def a_method
  class ClassExample (line 13) | class ClassExample
    method a_method (line 16) | def a_method
  type BubbleWrap (line 22) | module BubbleWrap
    function set_version (line 23) | def self.set_version(version)
Condensed preview — 186 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (599K chars).
[
  {
    "path": ".gitignore",
    "chars": 50,
    "preview": ".rake_tasks~\npkg/*\nbuild/\n.DS_Store\n.repl_history\n"
  },
  {
    "path": ".travis.yml",
    "chars": 281,
    "preview": "language: objective-c\nosx_image: xcode8\nbefore_install:\n  - sudo motion update\n  - motion repo\nscript:\n  - bundle exec r"
  },
  {
    "path": ".yardopts",
    "chars": 26,
    "preview": "lib/**/*.rb\nmotion/**/*.rb"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 12943,
    "preview": "## Unreleased\n\n[Commit history](https://github.com/rubymotion-community/BubbleWrap/compare/v1.9.7...master)\n\n## 1.9.7\n\n["
  },
  {
    "path": "GEM.md",
    "chars": 2510,
    "preview": "# Creating a RubyMotion gem with BubbleWrap\n\nLet's say we want to develop a simple library gem that lists the\npeople in "
  },
  {
    "path": "GETTING_STARTED.md",
    "chars": 3320,
    "preview": "# Getting Started with BubbleWrap\n\nA short guide to starting a RubyMotion application using the bubble wrappers.\n\n## A q"
  },
  {
    "path": "Gemfile",
    "chars": 96,
    "preview": "source 'https://rubygems.org'\n\n# Specify your gem's dependencies in bubble-wrap.gemspec\ngemspec\n"
  },
  {
    "path": "HACKING.md",
    "chars": 3694,
    "preview": "# Hacking on BubbleWrap\n\n## A library in two parts\n\nRubyMotion forces a certain background-radiation of schizophrenia\ndu"
  },
  {
    "path": "LICENSE",
    "chars": 1207,
    "preview": "LICENCE\n\nMIT: http://mattaimonetti.mit-license.org\n\n------------------------------------------------\n\nThe MIT License (M"
  },
  {
    "path": "README.md",
    "chars": 35837,
    "preview": "# BubbleWrap for RubyMotion\n\nA collection of (tested) helpers and wrappers used to wrap Cocoa Touch and AppKit code and "
  },
  {
    "path": "Rakefile",
    "chars": 1347,
    "preview": "$:.unshift(\"/Library/RubyMotion/lib\")\n$:.unshift(\"~/.rubymotion/rubymotion-templates\")\nrequire 'motion/project/template/"
  },
  {
    "path": "bubble-wrap.gemspec",
    "chars": 1460,
    "preview": "# -*- encoding: utf-8 -*-\nrequire File.expand_path('../lib/bubble-wrap/version', __FILE__)\n\nGem::Specification.new do |g"
  },
  {
    "path": "lib/bubble-wrap/all.rb",
    "chars": 252,
    "preview": "require File.expand_path('../loader', __FILE__)\n[\n  'core',\n  'font',\n  'location',\n  'mail',\n  'media',\n  'motion',\n  '"
  },
  {
    "path": "lib/bubble-wrap/camera.rb",
    "chars": 652,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"camera\") do\n  BubbleWrap.require('motion/util/constants.rb')\n  Bub"
  },
  {
    "path": "lib/bubble-wrap/core.rb",
    "chars": 628,
    "preview": "require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)\nrequire 'bubble-wrap/loader'\n\nBubbleWrap.require('mot"
  },
  {
    "path": "lib/bubble-wrap/ext/motion_project_app.rb",
    "chars": 1217,
    "preview": "module BubbleWrap\n  module Ext\n    module BuildTask\n\n      def self.extended(base)\n        base.instance_eval do\n       "
  },
  {
    "path": "lib/bubble-wrap/ext.rb",
    "chars": 45,
    "preview": "require 'bubble-wrap/ext/motion_project_app'\n"
  },
  {
    "path": "lib/bubble-wrap/font.rb",
    "chars": 111,
    "preview": "require 'bubble-wrap/loader'\nBubbleWrap.require_ios(\"font\") do\n  BubbleWrap.require('motion/font/font.rb')\nend\n"
  },
  {
    "path": "lib/bubble-wrap/loader.rb",
    "chars": 2047,
    "preview": "unless defined?(Motion::Project::Config)\n  raise 'This file must be required within a RubyMotion project Rakefile.'\nend\n"
  },
  {
    "path": "lib/bubble-wrap/location.rb",
    "chars": 453,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"location\") do\n  BubbleWrap.require('motion/util/constants.rb')\n  B"
  },
  {
    "path": "lib/bubble-wrap/mail.rb",
    "chars": 292,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"mail\") do\n  BubbleWrap.require('motion/core/app.rb')\n  BubbleWrap."
  },
  {
    "path": "lib/bubble-wrap/media.rb",
    "chars": 577,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"media\") do\n  BubbleWrap.require('motion/core/app.rb')\n  BubbleWrap"
  },
  {
    "path": "lib/bubble-wrap/motion.rb",
    "chars": 680,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios('motion') do\n  BubbleWrap.require('motion/util/constants.rb')\n  Bub"
  },
  {
    "path": "lib/bubble-wrap/network-indicator.rb",
    "chars": 181,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"network-indicator\") do\n  BubbleWrap.require('motion/core/app.rb')\n"
  },
  {
    "path": "lib/bubble-wrap/reactor.rb",
    "chars": 532,
    "preview": "require 'bubble-wrap/loader'\n\nBW.require 'motion/reactor.rb'\nBW.require 'motion/reactor/**/*.rb' do\n  file('motion/react"
  },
  {
    "path": "lib/bubble-wrap/requirement/path_manipulation.rb",
    "chars": 1099,
    "preview": "module BubbleWrap\n  class Requirement\n    module PathManipulation\n\n      def convert_caller_to_root_path(path)\n        p"
  },
  {
    "path": "lib/bubble-wrap/requirement.rb",
    "chars": 2247,
    "preview": "require 'bubble-wrap/requirement/path_manipulation'\n\nmodule BubbleWrap\n  class Requirement\n    extend PathManipulation\n "
  },
  {
    "path": "lib/bubble-wrap/rss_parser.rb",
    "chars": 72,
    "preview": "require 'bubble-wrap/loader'\nBubbleWrap.require('motion/rss_parser.rb')\n"
  },
  {
    "path": "lib/bubble-wrap/sms.rb",
    "chars": 285,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"sms\") do\n  BubbleWrap.require('motion/core/app.rb')\n  BubbleWrap.r"
  },
  {
    "path": "lib/bubble-wrap/test.rb",
    "chars": 335,
    "preview": "require 'webstub'\nrequire 'bubble-wrap/loader'\nBW.require 'motion/util/*.rb'\nBW.require 'motion/test_suite_delegate.rb'\n"
  },
  {
    "path": "lib/bubble-wrap/ui.rb",
    "chars": 339,
    "preview": "require 'bubble-wrap/loader'\n\nBubbleWrap.require_ios(\"ui\") do\n  BubbleWrap.require('motion/util/constants.rb')\n  BubbleW"
  },
  {
    "path": "lib/bubble-wrap/version.rb",
    "chars": 109,
    "preview": "module BubbleWrap\n  VERSION = '1.9.7' unless defined?(BubbleWrap::VERSION)\n  MIN_MOTION_VERSION = '3.12'\nend\n"
  },
  {
    "path": "lib/bubble-wrap.rb",
    "chars": 125,
    "preview": "require 'bubble-wrap/version' unless defined?(BubbleWrap::VERSION)\nrequire File.expand_path('../bubble-wrap/core', __FIL"
  },
  {
    "path": "motion/core/app.rb",
    "chars": 2547,
    "preview": "# Provides a module to store global states\n#\nmodule BubbleWrap\n  module App\n    include BubbleWrap::Deprecated\n\n    modu"
  },
  {
    "path": "motion/core/device/ios/camera.rb",
    "chars": 9083,
    "preview": "# Provides a nice DSL for interacting with the standard\n# UIImagePickerController\n#\nmodule BubbleWrap\n  module Device\n  "
  },
  {
    "path": "motion/core/device/ios/camera_wrapper.rb",
    "chars": 1835,
    "preview": "module BubbleWrap\n  module Device\n    module CameraWrapper\n\n      module_function\n\n      # The front-facing camera used "
  },
  {
    "path": "motion/core/device/ios/screen.rb",
    "chars": 3813,
    "preview": "module BubbleWrap\n  module Device\n    module Screen\n\n      module_function\n\n      # Certifies that the device running th"
  },
  {
    "path": "motion/core/device/osx/screen.rb",
    "chars": 487,
    "preview": "module BubbleWrap\n  module Device\n    module Screen\n\n      module_function\n\n      # Certifies that the device running th"
  },
  {
    "path": "motion/core/device/screen.rb",
    "chars": 71,
    "preview": "module BubbleWrap\n  module Device\n    module Screen\n\n    end\n  end\nend\n"
  },
  {
    "path": "motion/core/device.rb",
    "chars": 328,
    "preview": "module BubbleWrap\n  module Device\n    module_function\n\n    # Shameless shorthand for accessing BubbleWrap::Screen\n    de"
  },
  {
    "path": "motion/core/ios/app.rb",
    "chars": 2754,
    "preview": "module BubbleWrap\n  module App\n    module_function\n\n    # Opens an url (string or instance of `NSURL`)\n    # in the devi"
  },
  {
    "path": "motion/core/ios/device.rb",
    "chars": 3402,
    "preview": "module BubbleWrap\n  module Device\n    module_function\n\n    # Verifies that the device running the app is an iPhone.\n    "
  },
  {
    "path": "motion/core/ios/ns_index_path.rb",
    "chars": 202,
    "preview": "module NSIndexPathWrap\n\n  def +(aNumber)\n    self.class.indexPathForRow(row+aNumber, inSection:section)\n  end\n\n  def -(a"
  },
  {
    "path": "motion/core/json.rb",
    "chars": 1222,
    "preview": "module BubbleWrap\n\n  # Handles JSON encoding and decoding in a similar way Ruby 1.9 does.\n  module JSON\n\n    class Parse"
  },
  {
    "path": "motion/core/kvo.rb",
    "chars": 5068,
    "preview": "# Usage example:\n#\n# class ExampleViewController < UIViewController\n#     include BubbleWrap::KVO\n#\n#     def viewDidLoa"
  },
  {
    "path": "motion/core/ns_index_path.rb",
    "chars": 566,
    "preview": "module NSIndexPathWrap\n\n  # Gives access to an index at a given position.\n  # @param [Integer] position to use to fetch "
  },
  {
    "path": "motion/core/ns_notification_center.rb",
    "chars": 582,
    "preview": "class NSNotificationCenter\n  def observers\n    @observers ||= []\n  end\n\n  def observe(name, object=nil, &proc)\n    proc."
  },
  {
    "path": "motion/core/ns_url_request.rb",
    "chars": 468,
    "preview": "class NSURLRequest\n\n  # Provides a to_s method so we can use inspect in instances and get\n  # valuable information.\n  de"
  },
  {
    "path": "motion/core/ns_user_defaults.rb",
    "chars": 477,
    "preview": "# Reopens the NSUserDefaults class to add Array like accessors\n# @see https://developer.apple.com/library/ios/#documenta"
  },
  {
    "path": "motion/core/osx/app.rb",
    "chars": 523,
    "preview": "module BubbleWrap\n  module App\n    module_function\n\n    # Opens an url (string or instance of `NSURL`)\n    # in the defa"
  },
  {
    "path": "motion/core/osx/device.rb",
    "chars": 65,
    "preview": "module BubbleWrap\n  module Device\n    module_function\n\n  end\nend\n"
  },
  {
    "path": "motion/core/persistence.rb",
    "chars": 1465,
    "preview": "# Persistence module built on top of NSUserDefaults\nmodule BubbleWrap\n  module Persistence\n    module_function\n\n    def "
  },
  {
    "path": "motion/core/pollute.rb",
    "chars": 98,
    "preview": "[\n  [NSIndexPath, NSIndexPathWrap]\n].each do |base, wrapper|\n    base.send(:include, wrapper)\nend\n"
  },
  {
    "path": "motion/core/string.rb",
    "chars": 3082,
    "preview": "module BubbleWrap\n  # This module contains simplified version of the `camelize` and\n  # `underscore` methods from Active"
  },
  {
    "path": "motion/core/time.rb",
    "chars": 1300,
    "preview": "class Time\n\n  def self.iso8601(time)\n    if time.include?(\".\")\n      # Fractional Seconds\n      if time.include?('Z')\n  "
  },
  {
    "path": "motion/core.rb",
    "chars": 733,
    "preview": "module BubbleWrap\n  module_function\n\n  # @return [UIcolor]\n  def rgb_color(r,g,b)\n    rgba_color(r,g,b,1)\n  end\n\n  # @re"
  },
  {
    "path": "motion/font/font.rb",
    "chars": 2129,
    "preview": "module BubbleWrap\n  module Font\n    module_function\n\n    def bold(size = nil)\n      Font.new(:bold, size)\n    end\n\n    d"
  },
  {
    "path": "motion/ios/8/location_constants.rb",
    "chars": 746,
    "preview": "module BW\n  # New additions to CLAuthorizationStatus in ios8\n  # see: https://developer.apple.com/library/prerelease/ios"
  },
  {
    "path": "motion/location/location.rb",
    "chars": 8990,
    "preview": "# Provides a nice DSL for interacting with the standard\n# CLLocationManager\n#\nmodule BubbleWrap\n  module CLLocationWrap\n"
  },
  {
    "path": "motion/location/pollute.rb",
    "chars": 109,
    "preview": "[\n  [CLLocation, BubbleWrap::CLLocationWrap],\n].each do |base, wrapper|\n    base.send(:include, wrapper)\nend\n"
  },
  {
    "path": "motion/mail/mail.rb",
    "chars": 2778,
    "preview": "module BubbleWrap\n  module Mail\n\n    module_function\n\n    # Base method to create your in-app mail\n    # ---------------"
  },
  {
    "path": "motion/mail/result.rb",
    "chars": 532,
    "preview": "module BubbleWrap\n  module Mail\n    class Result\n      attr_accessor :result, :error\n\n      def initialize(result, error"
  },
  {
    "path": "motion/media/media.rb",
    "chars": 319,
    "preview": "module BubbleWrap\n  module Media\n    module_function\n\n    def play_modal(*args, &block)\n      Media::Player.new.retain.s"
  },
  {
    "path": "motion/media/player.rb",
    "chars": 6558,
    "preview": "module BubbleWrap\n  module Media\n    module Error\n      class InvalidPlayerType < StandardError; end\n      class NilPlay"
  },
  {
    "path": "motion/motion/accelerometer.rb",
    "chars": 1220,
    "preview": "module BubbleWrap\n  module Motion\n    class Accelerometer < GenericMotionInterface\n\n      def start(options={}, &handler"
  },
  {
    "path": "motion/motion/device_motion.rb",
    "chars": 4094,
    "preview": "module BubbleWrap\n  module Motion\n    class DeviceMotion < GenericMotionInterface\n\n      def start(options={}, &handler)"
  },
  {
    "path": "motion/motion/gyroscope.rb",
    "chars": 1149,
    "preview": "module BubbleWrap\n  module Motion\n    class Gyroscope < GenericMotionInterface\n\n      def start(options={}, &handler)\n  "
  },
  {
    "path": "motion/motion/magnetometer.rb",
    "chars": 1209,
    "preview": "module BubbleWrap\n  module Motion\n    class Magnetometer < GenericMotionInterface\n\n      def start(options={}, &handler)"
  },
  {
    "path": "motion/motion/motion.rb",
    "chars": 3305,
    "preview": "# Provides a nice DSL for interacting with the standard CMMotionManager from\n# CoreMotion\nmodule BubbleWrap\n  # These mo"
  },
  {
    "path": "motion/network-indicator/network-indicator.rb",
    "chars": 1626,
    "preview": "module BubbleWrap\n  module NetworkIndicator\n    DELAY = 0.2\n\n    module_function\n\n    def counter\n      @counter ||= 0\n "
  },
  {
    "path": "motion/reactor/default_deferrable.rb",
    "chars": 244,
    "preview": "module BubbleWrap\n  module Reactor\n    # A basic class which includes Deferrable when all\n    # you need is a deferrable"
  },
  {
    "path": "motion/reactor/deferrable.rb",
    "chars": 5547,
    "preview": "module BubbleWrap\n  module Reactor\n    # Provides a mixin for deferrable jobs.\n    module Deferrable\n\n      # def self.i"
  },
  {
    "path": "motion/reactor/dependent_deferrable.rb",
    "chars": 987,
    "preview": "module BubbleWrap\n  module Reactor\n    class DependentDeferrable < DefaultDeferrable\n      # args are Deferrable(s) whic"
  },
  {
    "path": "motion/reactor/eventable.rb",
    "chars": 1194,
    "preview": "module BubbleWrap\n  module Reactor\n    # A simple mixin that adds events to your object.\n    module Eventable\n\n      # W"
  },
  {
    "path": "motion/reactor/future.rb",
    "chars": 471,
    "preview": "module BubbleWrap\n  module Reactor\n    module Future\n\n      # A future is a sugaring of a typical deferrable usage.\n    "
  },
  {
    "path": "motion/reactor/periodic_timer.rb",
    "chars": 1059,
    "preview": "module BubbleWrap\n  module Reactor\n    # Creates a repeating timer.\n    class PeriodicTimer\n      include Eventable\n\n   "
  },
  {
    "path": "motion/reactor/queue.rb",
    "chars": 1510,
    "preview": "module BubbleWrap\n  module Reactor\n    # A GCD scheduled, linear queue.\n    #\n    # This class provides a simple “Queue”"
  },
  {
    "path": "motion/reactor/thread_aware_deferrable.rb",
    "chars": 818,
    "preview": "module BubbleWrap\n  module Reactor\n    class ThreadAwareDeferrable < DefaultDeferrable\n      include ::BubbleWrap::React"
  },
  {
    "path": "motion/reactor/timer.rb",
    "chars": 663,
    "preview": "module BubbleWrap\n  module Reactor\n    # Creates a one-time timer.\n    class Timer\n      include Eventable\n\n      # Crea"
  },
  {
    "path": "motion/reactor.rb",
    "chars": 3631,
    "preview": "module BubbleWrap\n  module Reactor\n    module_function\n\n    # Always returns true - for compatibility with EM\n    def re"
  },
  {
    "path": "motion/rss_parser.rb",
    "chars": 4526,
    "preview": "# Asynchronous and non blocking RSS Parser based on NSXMLParser.\n# The parser will progressively parse a feed and yield "
  },
  {
    "path": "motion/shortcut.rb",
    "chars": 614,
    "preview": "# Make sure that\n# Both BubbleWrap and BW are defined.  This file is depended on by everything\n# else in BubbleWrap, so "
  },
  {
    "path": "motion/sms/result.rb",
    "chars": 402,
    "preview": "module BubbleWrap\n  module SMS\n    class Result\n      attr_accessor :result\n\n      def initialize(result)\n        self.r"
  },
  {
    "path": "motion/sms/sms.rb",
    "chars": 1835,
    "preview": "module BubbleWrap\n  module SMS\n\n    module_function\n\n    # Base method to create your in-app mail\n    # ----------------"
  },
  {
    "path": "motion/test_suite_delegate.rb",
    "chars": 2277,
    "preview": "class TestSuiteDelegate\n  attr_accessor :window\n\n  def application(application, didFinishLaunchingWithOptions:launchOpti"
  },
  {
    "path": "motion/ui/pollute.rb",
    "chars": 284,
    "preview": "# Please, no more!  It'll hurt BubbleWrap's compatibility with other libraries.\n[\n  [UIControl,         BW::UIControlWra"
  },
  {
    "path": "motion/ui/ui_activity_view_controller_wrapper.rb",
    "chars": 1666,
    "preview": "module BW\n  class UIActivityViewController < ::UIActivityViewController\n    class << self\n      def new(options = {}, pr"
  },
  {
    "path": "motion/ui/ui_alert_view.rb",
    "chars": 6044,
    "preview": "module BW\n  class UIAlertView < ::UIAlertView\n    @callbacks = [\n      :will_present,\n      :did_present,\n      :on_syst"
  },
  {
    "path": "motion/ui/ui_bar_button_item.rb",
    "chars": 3284,
    "preview": "module BW\n  class UIBarButtonItem < ::UIBarButtonItem\n    class << self\n      def styled(type, *objects, &block)\n       "
  },
  {
    "path": "motion/ui/ui_control_wrapper.rb",
    "chars": 1201,
    "preview": "module BubbleWrap\n  module UIControlWrapper\n    def when(events, options = {}, &block)\n      events = BW::Constants.get("
  },
  {
    "path": "motion/ui/ui_view_controller_wrapper.rb",
    "chars": 449,
    "preview": "module BubbleWrap\n  module UIViewControllerWrapper\n    # Short hand to get the content frame\n    #\n    # Return content "
  },
  {
    "path": "motion/ui/ui_view_wrapper.rb",
    "chars": 2421,
    "preview": "module BubbleWrap\n  module UIViewWrapper\n    def when_tapped(enableInteraction=true, &proc)\n      add_gesture_recognizer"
  },
  {
    "path": "motion/util/constants.rb",
    "chars": 1692,
    "preview": "# Stupid hack because the RubyMotion dependency detection has a bug.\nmodule BubbleWrap\n  module Constants\n    module_fun"
  },
  {
    "path": "motion/util/deprecated.rb",
    "chars": 1344,
    "preview": "module BubbleWrap\n  module Deprecated\n\n    class DeprecatedError < StandardError; end\n\n    def deprecated(method_sym, ve"
  },
  {
    "path": "resources/Localizable.strings",
    "chars": 24,
    "preview": "\"real_key\" = \"Real Key\";"
  },
  {
    "path": "resources/atom.xml",
    "chars": 161863,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<?xml-stylesheet type=\"text/xsl\" media=\"screen\" href=\"/~d/styles/rss2enclosuresf"
  },
  {
    "path": "samples/alert/.gitignore",
    "chars": 169,
    "preview": ".repl_history\nbuild\ntags\napp/pixate_code.rb\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n.DS_Store\nnbproject"
  },
  {
    "path": "samples/alert/Gemfile",
    "chars": 79,
    "preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"bubble-wrap\", :path => \"../../\"\n"
  },
  {
    "path": "samples/alert/Rakefile",
    "chars": 252,
    "preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bundler'\nBu"
  },
  {
    "path": "samples/alert/app/app_delegate.rb",
    "chars": 278,
    "preview": "class AppDelegate\n  def application(application, didFinishLaunchingWithOptions:launchOptions)\n    @window = UIWindow.all"
  },
  {
    "path": "samples/alert/app/controllers/alert_view_controller.rb",
    "chars": 2073,
    "preview": "class AlertViewController < UIViewController\n  attr_reader :text_view\n  attr_reader :buttons\n  attr_reader :alerts\n\n  de"
  },
  {
    "path": "samples/alert/spec/main_spec.rb",
    "chars": 165,
    "preview": "describe \"Application 'alert'\" do\n  before do\n    @app = UIApplication.sharedApplication\n  end\n\n  it \"has one window\" do"
  },
  {
    "path": "samples/camera/Gemfile",
    "chars": 79,
    "preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"bubble-wrap\", :path => \"../../\"\n"
  },
  {
    "path": "samples/camera/README.md",
    "chars": 67,
    "preview": "## Camera Demo\n\nA bubble-wrap demo to show how to use camera API.\n\n"
  },
  {
    "path": "samples/camera/Rakefile",
    "chars": 219,
    "preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bubble-wrap"
  },
  {
    "path": "samples/camera/app/app_delegate.rb",
    "chars": 308,
    "preview": "class AppDelegate\n  def application(application, didFinishLaunchingWithOptions:launchOptions)\n    @window = UIWindow.all"
  },
  {
    "path": "samples/camera/app/controllers/camera_controller.rb",
    "chars": 1393,
    "preview": "class CameraController < UIViewController\n  attr_accessor :buttons\n\n  def init\n    super.tap do\n      @buttons = []\n    "
  },
  {
    "path": "samples/camera/spec/main_spec.rb",
    "chars": 175,
    "preview": "describe \"Application 'google_location'\" do\n  before do\n    @app = UIApplication.sharedApplication\n  end\n\n  it \"has one "
  },
  {
    "path": "samples/gesture/.gitignore",
    "chars": 77,
    "preview": ".repl_history\nbuild\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n"
  },
  {
    "path": "samples/gesture/Gemfile",
    "chars": 98,
    "preview": "source \"https://rubygems.org\"\n\ngem 'rake'\ngem \"bubble-wrap\", :path => \"../../\"\ngem 'motion-dryer'\n"
  },
  {
    "path": "samples/gesture/README.md",
    "chars": 198,
    "preview": "## Gesture Demo\n\nA bubble-wrap demo to show how to use gesture API.\n\n![](http://f.cl.ly/items/0e1J3W0Y0p3n3S2a0k2K/%E8%9"
  },
  {
    "path": "samples/gesture/Rakefile",
    "chars": 207,
    "preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bundler'\nBu"
  },
  {
    "path": "samples/gesture/app/app_delegate.rb",
    "chars": 419,
    "preview": "class AppDelegate\n  attr_reader :window\n\n  def application(application, didFinishLaunchingWithOptions:launchOptions)\n   "
  },
  {
    "path": "samples/gesture/app/controllers/drawing_view_controller.rb",
    "chars": 392,
    "preview": "class DrawingViewController < UIViewController\n  attr_reader :drawing_view\n\n  def loadView\n    screen = UIScreen.mainScr"
  },
  {
    "path": "samples/gesture/app/helpers/drawing_helper.rb",
    "chars": 24,
    "preview": "module DrawingHelper\nend"
  },
  {
    "path": "samples/gesture/app/views/drawing/gesture_view.rb",
    "chars": 2556,
    "preview": "class GestureView < UIView\n  attr_accessor :rotation, :scale, :translation\n\n  def initWithCoder(coder)\n    super\n    set"
  },
  {
    "path": "samples/gesture/app/views/drawing/rect_view.rb",
    "chars": 448,
    "preview": "class RectView < GestureView\n  def drawRect(rect)\n    super(rect)\n\n    context = UIGraphicsGetCurrentContext()\n    CGCon"
  },
  {
    "path": "samples/gesture/spec/main_spec.rb",
    "chars": 167,
    "preview": "describe \"Application 'gesture'\" do\n  before do\n    @app = UIApplication.sharedApplication\n  end\n\n  it \"has one window\" "
  },
  {
    "path": "samples/location/.gitignore",
    "chars": 77,
    "preview": ".repl_history\nbuild\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n"
  },
  {
    "path": "samples/location/Gemfile",
    "chars": 102,
    "preview": "source \"https://rubygems.org\"\n\ngem 'rake'\ngem \"bubble-wrap\", :path => \"../../\"\ngem 'bubble-wrap-http'\n"
  },
  {
    "path": "samples/location/README.md",
    "chars": 71,
    "preview": "## Location Demo\n\nA bubble-wrap demo to show how to use location API.\n\n"
  },
  {
    "path": "samples/location/Rakefile",
    "chars": 258,
    "preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\nrequire 'bubble-wrap"
  },
  {
    "path": "samples/location/app/app_delegate.rb",
    "chars": 322,
    "preview": "class AppDelegate\n  def application(application, didFinishLaunchingWithOptions:launchOptions)\n    @window = UIWindow.all"
  },
  {
    "path": "samples/location/app/controllers/places_list_controller.rb",
    "chars": 726,
    "preview": "class PlacesListController < UITableViewController\n  attr_accessor :places_list\n\n  def viewDidLoad\n    @places_list = []"
  },
  {
    "path": "samples/location/app/models/places.rb",
    "chars": 634,
    "preview": "class Places\n  API_KEY = \"\"\n  #See google places documentation at https://developers.google.com/places/documentation/ to"
  },
  {
    "path": "samples/location/spec/main_spec.rb",
    "chars": 175,
    "preview": "describe \"Application 'google_location'\" do\n  before do\n    @app = UIApplication.sharedApplication\n  end\n\n  it \"has one "
  },
  {
    "path": "samples/media/.gitignore",
    "chars": 169,
    "preview": ".repl_history\nbuild\ntags\napp/pixate_code.rb\nresources/*.nib\nresources/*.momd\nresources/*.storyboardc\n.DS_Store\nnbproject"
  },
  {
    "path": "samples/media/Gemfile",
    "chars": 79,
    "preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem \"bubble-wrap\", :path => \"../../\"\n"
  },
  {
    "path": "samples/media/Rakefile",
    "chars": 271,
    "preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/ios'\n\n$:.unshift(\"../../l"
  },
  {
    "path": "samples/media/app/app_delegate.rb",
    "chars": 306,
    "preview": "class AppDelegate\n  def application(application, didFinishLaunchingWithOptions:launchOptions)\n    @window = UIWindow.all"
  },
  {
    "path": "samples/media/app/controllers/play_controller.rb",
    "chars": 1222,
    "preview": "class PlayController < UIViewController\n  attr_accessor :buttons\n\n  def init\n    super.tap do\n      @buttons = []\n    en"
  },
  {
    "path": "samples/media/spec/main_spec.rb",
    "chars": 165,
    "preview": "describe \"Application 'media'\" do\n  before do\n    @app = UIApplication.sharedApplication\n  end\n\n  it \"has one window\" do"
  },
  {
    "path": "samples/osx/Gemfile",
    "chars": 102,
    "preview": "source \"https://rubygems.org\"\n\ngem \"rake\"\ngem 'bubble-wrap', :path => \"../../\"\ngem 'bubble-wrap-http'\n"
  },
  {
    "path": "samples/osx/Rakefile",
    "chars": 260,
    "preview": "# -*- coding: utf-8 -*-\n$:.unshift(\"/Library/RubyMotion/lib\")\nrequire 'motion/project/template/osx'\n\nrequire 'bundler'\nB"
  },
  {
    "path": "samples/osx/app/app_delegate.rb",
    "chars": 2077,
    "preview": "class AppDelegate\n  def applicationDidFinishLaunching(notification)\n    buildMenu\n    buildWindow\n  end\n\n  def buildWind"
  },
  {
    "path": "samples/osx/app/menu.rb",
    "chars": 4953,
    "preview": "class AppDelegate\n  def buildMenu\n    @mainMenu = NSMenu.new\n\n    appName = NSBundle.mainBundle.infoDictionary['CFBundle"
  },
  {
    "path": "samples/osx/resources/Credits.rtf",
    "chars": 436,
    "preview": "{\\rtf0\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;}\n\\paperw9840\\paperh8400\n\\pard\\tx560\\tx11"
  },
  {
    "path": "samples/osx/spec/main_spec.rb",
    "chars": 163,
    "preview": "describe \"Application 'osx'\" do\n  before do\n    @app = UIApplication.sharedApplication\n  end\n\n  it \"has one window\" do\n "
  },
  {
    "path": "spec/lib/bubble-wrap/ext/motion_project_app_spec.rb",
    "chars": 4024,
    "preview": "require 'mocha-on-bacon'\nrequire File.expand_path('../../../motion_stub', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe Bubb"
  },
  {
    "path": "spec/lib/bubble-wrap/ext/motion_project_config_spec.rb",
    "chars": 1254,
    "preview": "require 'mocha-on-bacon'\nrequire File.expand_path('../../../motion_stub', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe Bubb"
  },
  {
    "path": "spec/lib/bubble-wrap/requirement/path_manipulation_spec.rb",
    "chars": 1564,
    "preview": "require File.expand_path('../../../../../lib/bubble-wrap/requirement/path_manipulation', __FILE__)\n\ndescribe BubbleWrap:"
  },
  {
    "path": "spec/lib/bubble-wrap/requirement_spec.rb",
    "chars": 2154,
    "preview": "require File.expand_path('../../motion_stub', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe BubbleWrap::Requirement do\n\n  be"
  },
  {
    "path": "spec/lib/bubble-wrap_spec.rb",
    "chars": 870,
    "preview": "require 'mocha-on-bacon'\nrequire File.expand_path('../motion_stub.rb', __FILE__)\nrequire 'bubble-wrap'\n\ndescribe BubbleW"
  },
  {
    "path": "spec/lib/motion_stub.rb",
    "chars": 230,
    "preview": "# Create a fake Motion class hierarchy for testing.\nmodule Motion\n  module Project\n    class App\n      def self.setup\n  "
  },
  {
    "path": "spec/motion/core/app_spec.rb",
    "chars": 3216,
    "preview": "describe BubbleWrap::App do\n  describe '.documents_path' do\n    it 'should end in \"/Documents\"' do\n      App.documents_p"
  },
  {
    "path": "spec/motion/core/device/ios/camera_spec.rb",
    "chars": 4057,
    "preview": "def camera_picker\n  @camera.instance_variable_get(\"@picker\")\nend\n\ndef example_info\n  { UIImagePickerControllerMediaType "
  },
  {
    "path": "spec/motion/core/device/ios/camera_wrapper_spec.rb",
    "chars": 2263,
    "preview": "describe BubbleWrap::Device::CameraWrapper do\n\n  before do\n    BW::Device.camera.instance_variable_set(:@front, nil)\n   "
  },
  {
    "path": "spec/motion/core/device/ios/device_spec.rb",
    "chars": 1778,
    "preview": "describe BubbleWrap::Device do\ndescribe \"iOS\" do\n  describe 'on iPhone' do\n    before do\n      @idiom = UIUserInterfaceI"
  },
  {
    "path": "spec/motion/core/device/ios/screen_spec.rb",
    "chars": 6750,
    "preview": "describe BubbleWrap::Device::Screen do\ndescribe \"iOS\" do\n  describe 'on retina enabled screen' do\n    before do\n      @s"
  },
  {
    "path": "spec/motion/core/device/osx/screen_spec.rb",
    "chars": 682,
    "preview": "describe BubbleWrap::Device::Screen do\n  describe \"OS X\" do\n    describe 'on retina enabled screen' do\n      before do\n "
  },
  {
    "path": "spec/motion/core/device_spec.rb",
    "chars": 319,
    "preview": "describe BubbleWrap::Device do\n\n  describe '.screen' do\n    it 'return BubbleWrap::Screen' do\n      BW::Device.screen.sh"
  },
  {
    "path": "spec/motion/core/ios/app_spec.rb",
    "chars": 6176,
    "preview": "describe BubbleWrap::App do\n  describe \"iOS\" do\n    describe '.alert' do\n      after do\n        @alert.dismissWithClicke"
  },
  {
    "path": "spec/motion/core/ios/ns_index_path_spec.rb",
    "chars": 414,
    "preview": "describe \"NSIndexPathWrap\" do\n\n  before do\n      @index = NSIndexPath.indexPathForRow(0, inSection:3)\n  end\n\n  it \"shoul"
  },
  {
    "path": "spec/motion/core/json_spec.rb",
    "chars": 4234,
    "preview": "describe \"JSON\" do\n\n  before do\n    @json_string = <<-EOS\n    {\n  \"public_gists\": 248,\n  \"type\": \"User\",\n  \"blog\": \"http"
  },
  {
    "path": "spec/motion/core/kvo_spec.rb",
    "chars": 9087,
    "preview": "describe BubbleWrap::KVO do\n\n  class KvoExample\n    include BubbleWrap::KVO\n\n    attr_accessor :age\n    attr_accessor :l"
  },
  {
    "path": "spec/motion/core/ns_index_path_spec.rb",
    "chars": 496,
    "preview": "describe \"NSIndexPathWrap\" do\n\n  before do\n    if App.osx?\n      @index = NSIndexPath.indexPathWithIndex(3)\n    else\n   "
  },
  {
    "path": "spec/motion/core/ns_notification_center_spec.rb",
    "chars": 1007,
    "preview": "describe \"NSNotificationCenter\" do\n  SampleNotification = \"SampleNotification\"\n\n  after do\n    @observer = nil\n  end\n\n  "
  },
  {
    "path": "spec/motion/core/osx/app_spec.rb",
    "chars": 380,
    "preview": "describe BubbleWrap::App do\n  describe \"OS X\" do\n\n    describe '.delegate' do\n      it 'returns a TestSuiteDelegate' do\n"
  },
  {
    "path": "spec/motion/core/persistence_spec.rb",
    "chars": 3091,
    "preview": "describe BubbleWrap::Persistence do\n\n  describe '.app_key' do\n\n    it \"caches the @app_key\" do\n      BubbleWrap::Persist"
  },
  {
    "path": "spec/motion/core/string_spec.rb",
    "chars": 6747,
    "preview": "describe BubbleWrap::String do\n\n  describe ::NSString do\n    it 'should include BubbleWrap::String' do\n      ::NSString."
  },
  {
    "path": "spec/motion/core/time_spec.rb",
    "chars": 4047,
    "preview": "describe \"Time\" do\n\n  describe \"Caching the date formatter\" do\n\n    it \"should reuse the created formatter\" do\n      100"
  },
  {
    "path": "spec/motion/core_spec.rb",
    "chars": 1849,
    "preview": "describe 'BubbleWrap' do\n\n\n  describe \"debug flag\" do\n\n    after do\n       BubbleWrap.debug = false\n    end\n\n    it \"can"
  },
  {
    "path": "spec/motion/font/font_spec.rb",
    "chars": 1924,
    "preview": "describe BubbleWrap::Font do\n  [[:system, \"systemFontOfSize:\"], [:bold, \"boldSystemFontOfSize:\"], [:italic, \"italicSyste"
  },
  {
    "path": "spec/motion/location/location_spec.rb",
    "chars": 9441,
    "preview": "describe \"CLLocationWrap\" do\n  it \"should have correct values for lat and lng\" do\n    coordinate = CLLocation.alloc.init"
  },
  {
    "path": "spec/motion/mail/mail_spec.rb",
    "chars": 4258,
    "preview": "# Mocking the presentViewController\nclass MailViewController < UIViewController\n  attr_accessor :expectation\n\n  def pres"
  },
  {
    "path": "spec/motion/mail/result_spec.rb",
    "chars": 1331,
    "preview": "describe BW::Mail::Result do\n\n  before do\n    @subject = BW::Mail::Result.new(MFMailComposeResultCancelled, nil)\n  end\n\n"
  },
  {
    "path": "spec/motion/media/player_spec.rb",
    "chars": 2658,
    "preview": "describe BubbleWrap::Media::Player do\n  describe \".play\" do\n    before do\n      @player = BW::Media::Player.new\n      @l"
  },
  {
    "path": "spec/motion/motion/core_motion_spec.rb",
    "chars": 7497,
    "preview": "describe BubbleWrap::Motion do\n\n  it 'should be able to instantiate all the things' do\n    mgr = CMMotionManager.alloc.i"
  },
  {
    "path": "spec/motion/network-indicator/network_indicator_spec.rb",
    "chars": 3684,
    "preview": "describe BW::NetworkIndicator do\n\n  before do\n    BW::NetworkIndicator.reset!\n  end\n\n  after do\n    BW::NetworkIndicator"
  },
  {
    "path": "spec/motion/reactor/deferrable_spec.rb",
    "chars": 2129,
    "preview": "describe BubbleWrap::Reactor::Deferrable do\n\n  before do\n    @subject = Class.new do\n      include BubbleWrap::Reactor::"
  },
  {
    "path": "spec/motion/reactor/dependent_deferrable_spec.rb",
    "chars": 2433,
    "preview": "describe BubbleWrap::Reactor::DependentDeferrable do\n\n  before do\n    @subject = Class.new do\n      include BubbleWrap::"
  },
  {
    "path": "spec/motion/reactor/eventable_spec.rb",
    "chars": 5643,
    "preview": "describe BubbleWrap::Reactor::Eventable do\n  before do\n    @subject = Class.new do\n      include BubbleWrap::Reactor::Ev"
  },
  {
    "path": "spec/motion/reactor/thread_aware_deferrable_spec.rb",
    "chars": 2199,
    "preview": "shared :queue_caching_deferrable_method do\n  it \"stores the current queue that is being used when a callback is added\" d"
  },
  {
    "path": "spec/motion/reactor_spec.rb",
    "chars": 4115,
    "preview": "describe BubbleWrap::Reactor do\n  before do\n    @subject = ::BubbleWrap::Reactor\n    @proxy = Class.new do\n      attr_ac"
  },
  {
    "path": "spec/motion/rss_parser_spec.rb",
    "chars": 1739,
    "preview": "describe \"RSSParser\" do\n  extend WebStub::SpecHelpers\n\n  before do\n    @feed_url = 'https://raw.github.com/gist/2952427/"
  },
  {
    "path": "spec/motion/sms/result_spec.rb",
    "chars": 916,
    "preview": "describe BW::SMS::Result do\n\n  before do\n    @subject = BW::SMS::Result.new(MessageComposeResultCancelled)\n  end\n\n  it \""
  },
  {
    "path": "spec/motion/sms/sms_spec.rb",
    "chars": 2437,
    "preview": "# Mocking the presentViewController\nclass MessageViewController < UIViewController\n  attr_accessor :expectation\n\n  def p"
  },
  {
    "path": "spec/motion/ui/pollute_spec.rb",
    "chars": 333,
    "preview": "describe \"UIKit pollution\" do\n  it \"pollutes UIControl\" do\n    UIControl.ancestors.should.include BW::UIControlWrapper\n "
  },
  {
    "path": "spec/motion/ui/ui_activity_view_controller_wrapper_spec.rb",
    "chars": 1887,
    "preview": "describe BubbleWrap::UIActivityViewController do\n  before do\n    @controller = UIViewController.alloc.init\n    @controll"
  },
  {
    "path": "spec/motion/ui/ui_alert_view_spec.rb",
    "chars": 38872,
    "preview": "shared \"an instance with no options\" do\n  it \"has the correct class\" do\n    @subject.class.should.equal(BW::UIAlertView)"
  },
  {
    "path": "spec/motion/ui/ui_bar_button_item_spec.rb",
    "chars": 17833,
    "preview": "describe BW::UIBarButtonItem do\n  class NavigationItemContainingBarButtonItem < UINavigationItem\n    def init_with_style"
  },
  {
    "path": "spec/motion/ui/ui_control_wrapper_spec.rb",
    "chars": 2936,
    "preview": "describe BW::UIControlWrapper do\n  describe \"#when\" do\n    before do\n      @subject = UIControl.alloc.init\n      @touche"
  },
  {
    "path": "spec/motion/ui/ui_view_controller_wrapper_spec.rb",
    "chars": 1054,
    "preview": "describe BW::UIViewControllerWrapper do\n  describe \"#content_frame\" do\n    describe \"given a UIViewController\" do\n      "
  },
  {
    "path": "spec/motion/ui/ui_view_wrapper_spec.rb",
    "chars": 2776,
    "preview": "describe BW::UIViewWrapper do\n  describe \"gestures\" do\n    before do\n      @view = App.delegate.window.rootViewControlle"
  },
  {
    "path": "spec/motion/util/constants_spec.rb",
    "chars": 1258,
    "preview": "describe BubbleWrap::Constants do\n  describe \".get\" do\n    BubbleWrap::Constants.register NSStringEncodingConversionAllo"
  },
  {
    "path": "spec/motion/util/deprecated_spec.rb",
    "chars": 1860,
    "preview": "module ModuleExample\n  include BubbleWrap::Deprecated\n\n  module_function\n\n  def a_method\n    @called = true\n  end\n\n  dep"
  }
]

About this extraction

This page contains the full source code of the rubymotion/BubbleWrap GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 186 files (553.1 KB), approximately 153.9k tokens, and a symbol index with 690 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!