stratosphere 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +262 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/stratosphere/inflection.min.js +22 -0
  6. data/app/assets/javascripts/stratosphere/rsvp.min.js +9 -0
  7. data/app/assets/javascripts/stratosphere/stratosphere.bundled.min.js +31 -0
  8. data/app/assets/javascripts/stratosphere/stratosphere.js +297 -0
  9. data/app/controllers/stratosphere/application_controller.rb +4 -0
  10. data/app/helpers/stratosphere/application_helper.rb +4 -0
  11. data/app/vendor/assets/javascripts/rsvp/README.md +9 -0
  12. data/app/vendor/assets/javascripts/rsvp/bower.json +22 -0
  13. data/app/vendor/assets/javascripts/rsvp/composer.json +18 -0
  14. data/app/vendor/assets/javascripts/rsvp/package.json +59 -0
  15. data/app/vendor/assets/javascripts/rsvp/rsvp.js +1671 -0
  16. data/app/vendor/assets/javascripts/rsvp/rsvp.min.js +9 -0
  17. data/app/views/_attachment_field.html.erb +42 -0
  18. data/config/initializers/action_controller.rb +56 -0
  19. data/config/routes.rb +2 -0
  20. data/lib/generators/stratosphere/attachment/USAGE +8 -0
  21. data/lib/generators/stratosphere/attachment/attachment_generator.rb +18 -0
  22. data/lib/generators/stratosphere/install/USAGE +0 -0
  23. data/lib/generators/stratosphere/install/install_generator.rb +26 -0
  24. data/lib/generators/stratosphere/install/templates/stratosphere.rb.erb +10 -0
  25. data/lib/stratosphere.rb +23 -0
  26. data/lib/stratosphere/attachment.rb +51 -0
  27. data/lib/stratosphere/aws.rb +50 -0
  28. data/lib/stratosphere/config.rb +5 -0
  29. data/lib/stratosphere/engine.rb +5 -0
  30. data/lib/stratosphere/has_attachment.rb +63 -0
  31. data/lib/stratosphere/image.rb +65 -0
  32. data/lib/stratosphere/style.rb +23 -0
  33. data/lib/stratosphere/version.rb +3 -0
  34. data/lib/stratosphere/video.rb +63 -0
  35. data/lib/tasks/stratosphere_tasks.rake +4 -0
  36. data/test/dummy/README.rdoc +28 -0
  37. data/test/dummy/Rakefile +6 -0
  38. data/test/dummy/app/assets/javascripts/application.js +13 -0
  39. data/test/dummy/app/controllers/application_controller.rb +5 -0
  40. data/test/dummy/app/helpers/application_helper.rb +2 -0
  41. data/test/dummy/app/views/layouts/application.html.erb +13 -0
  42. data/test/dummy/bin/bundle +3 -0
  43. data/test/dummy/bin/rails +4 -0
  44. data/test/dummy/bin/rake +4 -0
  45. data/test/dummy/bin/setup +29 -0
  46. data/test/dummy/config.ru +4 -0
  47. data/test/dummy/config/application.rb +26 -0
  48. data/test/dummy/config/boot.rb +5 -0
  49. data/test/dummy/config/database.yml +25 -0
  50. data/test/dummy/config/environment.rb +5 -0
  51. data/test/dummy/config/environments/development.rb +41 -0
  52. data/test/dummy/config/environments/production.rb +79 -0
  53. data/test/dummy/config/environments/test.rb +42 -0
  54. data/test/dummy/config/initializers/assets.rb +11 -0
  55. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  56. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  57. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  58. data/test/dummy/config/initializers/inflections.rb +16 -0
  59. data/test/dummy/config/initializers/mime_types.rb +4 -0
  60. data/test/dummy/config/initializers/session_store.rb +3 -0
  61. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  62. data/test/dummy/config/locales/en.yml +23 -0
  63. data/test/dummy/config/routes.rb +4 -0
  64. data/test/dummy/config/secrets.yml +22 -0
  65. data/test/dummy/log/test.log +0 -0
  66. data/test/dummy/public/404.html +67 -0
  67. data/test/dummy/public/422.html +67 -0
  68. data/test/dummy/public/500.html +66 -0
  69. data/test/dummy/public/favicon.ico +0 -0
  70. data/test/integration/navigation_test.rb +10 -0
  71. data/test/stratosphere_test.rb +7 -0
  72. data/test/test_helper.rb +19 -0
  73. metadata +218 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 905b59e0f027db766423f0a7ba6debedb8052106
4
+ data.tar.gz: 965b81ddfed6656d877256ba47f7fa4da78a2f7c
5
+ SHA512:
6
+ metadata.gz: 9268320ede2866543b7321ea05ee1517698589538c13325d0746dc020035e269b658c5225f0065bb80aaed5d237b6eeea0477425a44f7db9456092eab952c1ac
7
+ data.tar.gz: e412e68dbb9f1a548f0fd9976866b10a6af972d8869eb071659b6e8b0eb7159f5ac46cb132b8bed84d74b40a664380b4ea87a0cdbd1a84edbdd27ad8841e7a23
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Zachary Golba
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,262 @@
1
+ # Stratosphere
2
+
3
+ ### Lightning fast, easy-to-use, magic attachment handling for Ruby on Rails Applications
4
+
5
+ In today's day and age we have Dropbox, Google Drive, iCloud, etc. Shouldn't file uploading and attachment handling be easier and alot faster in Ruby on Rails Applications?
6
+ Stratosphere makes it easy to **upload directly to cloud storage providers at lightning fast speeds** while maintaining that "magic" Ruby on Rails **convention-over-configuration** we all know and love.
7
+
8
+ Currently only supporting AWS S3.
9
+
10
+ ## Prerequisites
11
+
12
+ ### AWS Setup
13
+
14
+ Make sure your AWS User has access to your S3 bucket and has the permissions necessary to **list**, **upload**, and **delete**.
15
+
16
+ ![AWS S3 Config](http://cdn.zacharygolba.com/stratosphere/docs/img/s3-configuration.jpg)
17
+
18
+ In order for Stratoshpere to properly load your AWS configuration in your ~/.bash_profile or ~/.bashrc:
19
+
20
+ ```bash
21
+ export AWS_ACCESS_KEY_ID="your-access-key-id"
22
+ export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
23
+ export AWS_REGION="s3-bucket-region"
24
+ ```
25
+
26
+ ### Ruby/Rails
27
+
28
+ Stratosphere requires **Ruby >= 2.0** and **Rails >= 4.0**.
29
+
30
+ ### ImageMagick
31
+
32
+ ImageMagick and it's relevant development libraries are required for Stratosphere to provide image proccessing.
33
+
34
+ If your using **Mac OSX** and **homebrew** you can install ImageMagick with:
35
+
36
+ ```bash
37
+ brew install imagemagick
38
+ ```
39
+
40
+ If your using **Ubuntu** or other **Debian** based Linux distros you can install ImageMagick with:
41
+
42
+ ```bash
43
+ sudo apt-get install -y ImageMagick libmagickwand-dev
44
+ ```
45
+
46
+ If your using **Amazon Linux**, **CentOS**, **Red Hat**, or other **RPM** based Linux distros you can install ImageMagick with:
47
+
48
+ ```bash
49
+ sudo yum install -y ImageMagick ImageMagick-devel
50
+ ```
51
+
52
+ ## Installation
53
+
54
+ Add this line to your application's Gemfile:
55
+
56
+ ```ruby
57
+ gem 'stratosphere'
58
+ ```
59
+
60
+ From the root of your rails app execute:
61
+
62
+ ```bash
63
+ bundle
64
+ ```
65
+
66
+ And then:
67
+
68
+ ```bash
69
+ rails g stratosphere:install
70
+ ```
71
+
72
+ You will be asked your S3 Bucket name in order for Stratosphere to generate an appropriate initializer.
73
+
74
+ After running the `rails g stratosphere:install` command make sure you include `stratosphere.bundled.min` in the asset pipeline AFTER jquery.
75
+
76
+ ```javascript
77
+ //= require jquery
78
+ //= require jquery_ujs
79
+ //= require turbolinks
80
+ //= require stratosphere.bundled.min
81
+ //= require_tree .
82
+ ```
83
+
84
+ ## Usage
85
+
86
+ ### General
87
+
88
+ To generate an attachment on one of your models execute the following from the root of your rails application:
89
+
90
+ ```bash
91
+ rails g stratosphere:attachment <model> <attachment_name>
92
+ ```
93
+
94
+ Executing the command above with **document** in place of model and **attachment** in place of attachment_name would generate the following migration:
95
+
96
+ ```ruby
97
+ class AddAttachmentToDocument < ActiveRecord::Migration
98
+ def change
99
+ add_column :documents, :attachment_file, :string
100
+ add_column :documents, :attachment_content_type, :string
101
+ add_column :documents, :attachment_content_length, :int8
102
+ end
103
+ end
104
+ ```
105
+
106
+ Now just add your attachment configuration to your Model with the has_attachment method:
107
+
108
+ ```ruby
109
+ class Document < ActiveRecord::Base
110
+ has_attachment :attachment
111
+ end
112
+ ```
113
+
114
+ And in any the view:
115
+
116
+ ```erb
117
+ <%= render partial: 'stratosphere/attachment_field', locals: { model: @post } %>
118
+ ```
119
+
120
+ :cloud: Thats it! No additional routes. No methods or strong parameters to add to your controllers. Just kick ass, highly scalable, lightning fast, AJAX file uploads!
121
+
122
+ ##### Configuration
123
+
124
+ By default, Stratosphere will create an initializer with the following code after running the `rails g stratosphere:install` command:
125
+
126
+ ```ruby
127
+ Stratosphere.configure do |config|
128
+ config.cloud = :aws
129
+ config.domain = 'http://s3.amazonaws.com/<your-s3-bucket-name>'
130
+ config.aws = {
131
+ access_key: ENV['AWS_ACCESS_KEY_ID'],
132
+ secret: ENV['AWS_SECRET_ACCESS_KEY'],
133
+ region: ENV['AWS_REGION'],
134
+ s3_bucket: '<your-s3-bucket-name>'
135
+ }
136
+ end
137
+ ```
138
+
139
+ To add a directory prefix to provide Stratosphere better, global insight to where your attachments will be stored in your S3 bucket you can add `config.dir_prefix = 'path/to/attachments'` to the `Stratosphere.configure` block above. Also if you are using Cloudfront to serve assets in you S3 bucket you can change the `config.domain` option to your CloudFront domain name or CNAME.
140
+
141
+ ##### Attachment URLs
142
+
143
+ To get a URL for your attachment simply execute:
144
+
145
+ ```ruby
146
+ @document = Document.find(1)
147
+ @document.attachment.url
148
+ ```
149
+
150
+ Or for image and video attachments that have additional styles, pass the style that you wish to retrieve a url for as a symbol to the attachment's url method:
151
+
152
+ ```ruby
153
+ @post = Post.find(1)
154
+ @post.image.url(:thumb)
155
+ ```
156
+
157
+ If you do not pass a style to the url method and your attachment has multiple styles, it will default to original.
158
+
159
+ ### Images & Videos
160
+
161
+ For image/video attachments, you can set the `:type` option in your Model's `has_attachment` method:
162
+
163
+ ```ruby
164
+ class Post < ActiveRecord::Base
165
+ has_attachment :image, type: :image
166
+ end
167
+ ```
168
+
169
+ ```ruby
170
+ class MusicVideo < ActiveRecord::Base
171
+ has_attachment :video, type: :video
172
+ end
173
+ ```
174
+
175
+ This provides addition features such as a `:default` option, the ability to add additional styles, a `crop` method for images, and an `encode` method for videos.
176
+
177
+ ##### Setting a Default Image/Video
178
+
179
+ Set a default image by passing a string with the path to the default image from root of your S3 bucket to the `:default` option in your Model's `has_attachment` method:
180
+
181
+ ```ruby
182
+ class Post < ActiveRecord::Base
183
+ has_attachment :image, type: :image, default: 'path/to/default.jpg'
184
+ end
185
+ ```
186
+
187
+ ##### Styles
188
+
189
+ Adding additional styles to your image attachment is as easy as passing an array of hashes with the name of the style and the dimensions of that style in an array ([width, height]):
190
+
191
+ ```ruby
192
+ class Post < ActiveRecord::Base
193
+ has_attachment :image, type: :image, styles: [ { name: :thumb, dimensions: [64, 64] }, { name: :medium, dimensions: [300, 300] } ]
194
+ end
195
+ ```
196
+
197
+ ##### Image Cropping
198
+
199
+ To crop your image attachment first make sure that you have at least one style set in your Model's `has_attachment` method. Cropping can be done simply making a PATCH request with the following parameters to the relative controller's `update` method:
200
+
201
+ ```javascript
202
+ {
203
+ crop_params: [x, y, width, height]
204
+ }
205
+ ```
206
+
207
+ You can also manually crop your attachment by executing the following code:
208
+
209
+ ```ruby
210
+ @post = Post.find(1)
211
+ @post.crop(0, 0, 300, 500)
212
+ ```
213
+
214
+ ##### Video Encoding
215
+
216
+ To enable AWS ElasticTranscoder video encoding, add the following `:transcoder` option to the `config.aws` hash in `config/initializers/stratosphere.rb`:
217
+
218
+ ```ruby
219
+ Stratosphere.configure do |config|
220
+ config.aws = {
221
+ transcoder: {
222
+ pipeline: '<pipeline-id>',
223
+ formats: { mp4: '<preset-id>', webm: '<preset-id>' }
224
+ }
225
+ }
226
+ end
227
+ ```
228
+
229
+ Video attachments with multiple styles containing different `:format` options will call encode automatically after your Model's attachment has changed.
230
+
231
+ You can also manually call the encode method by executing the following code:
232
+
233
+ ```ruby
234
+ @music_video = MusicVideo.find(1)
235
+ @music_video.encode
236
+ ```
237
+
238
+ By default if video encoding is enabled, a :thumb style will be automatically generated. To access the :thumb style simply add the following configuration to your Model's `has_attachment` method:
239
+
240
+ ```ruby
241
+ class MusicVideo < ActiveRecord::Base
242
+ has_attachment :video, type: :video, styles: [ { name: :thumb, format: :jpg, suffix: '-00001' } ]
243
+ end
244
+ ```
245
+
246
+ ## Example
247
+
248
+ Coming Soon!
249
+
250
+ ## To Do
251
+
252
+ - [ ] Better tests
253
+ - [ ] Multiple attachment support per each ActiveRecord Model
254
+ - [ ] Add additional cloud service providers (Google Cloud Storage, Azure Storage Box, Zencoder Video Encoding)
255
+
256
+ ## Contributing
257
+
258
+ 1. Fork it ( https://github.com/zacharygolba/stratosphere/fork )
259
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
260
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
261
+ 4. Push to the branch (`git push origin my-new-feature`)
262
+ 5. Create a new Pull Request
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Stratosphere'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task default: :test
@@ -0,0 +1,22 @@
1
+ /*
2
+ Copyright (c) 2010 Ryan Schuft (ryan.schuft@gmail.com)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+ */
22
+ window&&!window.InflectionJS&&(window.InflectionJS=null),InflectionJS={uncountable_words:["equipment","information","rice","money","species","series","fish","sheep","moose","deer","news"],plural_rules:[[new RegExp("(m)an$","gi"),"$1en"],[new RegExp("(pe)rson$","gi"),"$1ople"],[new RegExp("(child)$","gi"),"$1ren"],[new RegExp("^(ox)$","gi"),"$1en"],[new RegExp("(ax|test)is$","gi"),"$1es"],[new RegExp("(octop|vir)us$","gi"),"$1i"],[new RegExp("(alias|status)$","gi"),"$1es"],[new RegExp("(bu)s$","gi"),"$1ses"],[new RegExp("(buffal|tomat|potat)o$","gi"),"$1oes"],[new RegExp("([ti])um$","gi"),"$1a"],[new RegExp("sis$","gi"),"ses"],[new RegExp("(?:([^f])fe|([lr])f)$","gi"),"$1$2ves"],[new RegExp("(hive)$","gi"),"$1s"],[new RegExp("([^aeiouy]|qu)y$","gi"),"$1ies"],[new RegExp("(x|ch|ss|sh)$","gi"),"$1es"],[new RegExp("(matr|vert|ind)ix|ex$","gi"),"$1ices"],[new RegExp("([m|l])ouse$","gi"),"$1ice"],[new RegExp("(quiz)$","gi"),"$1zes"],[new RegExp("s$","gi"),"s"],[new RegExp("$","gi"),"s"]],singular_rules:[[new RegExp("(m)en$","gi"),"$1an"],[new RegExp("(pe)ople$","gi"),"$1rson"],[new RegExp("(child)ren$","gi"),"$1"],[new RegExp("([ti])a$","gi"),"$1um"],[new RegExp("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$","gi"),"$1$2sis"],[new RegExp("(hive)s$","gi"),"$1"],[new RegExp("(tive)s$","gi"),"$1"],[new RegExp("(curve)s$","gi"),"$1"],[new RegExp("([lr])ves$","gi"),"$1f"],[new RegExp("([^fo])ves$","gi"),"$1fe"],[new RegExp("([^aeiouy]|qu)ies$","gi"),"$1y"],[new RegExp("(s)eries$","gi"),"$1eries"],[new RegExp("(m)ovies$","gi"),"$1ovie"],[new RegExp("(x|ch|ss|sh)es$","gi"),"$1"],[new RegExp("([m|l])ice$","gi"),"$1ouse"],[new RegExp("(bus)es$","gi"),"$1"],[new RegExp("(o)es$","gi"),"$1"],[new RegExp("(shoe)s$","gi"),"$1"],[new RegExp("(cris|ax|test)es$","gi"),"$1is"],[new RegExp("(octop|vir)i$","gi"),"$1us"],[new RegExp("(alias|status)es$","gi"),"$1"],[new RegExp("^(ox)en","gi"),"$1"],[new RegExp("(vert|ind)ices$","gi"),"$1ex"],[new RegExp("(matr)ices$","gi"),"$1ix"],[new RegExp("(quiz)zes$","gi"),"$1"],[new RegExp("s$","gi"),""]],non_titlecased_words:["and","or","nor","a","an","the","so","but","to","of","at","by","from","into","on","onto","off","out","in","over","with","for"],id_suffix:new RegExp("(_ids|_id)$","g"),underbar:new RegExp("_","g"),space_or_underbar:new RegExp("[ _]","g"),uppercase:new RegExp("([A-Z])","g"),underbar_prefix:new RegExp("^_"),apply_rules:function(e,t,i,n){if(n)e=n;else{var r=i.indexOf(e.toLowerCase())>-1;if(!r)for(var o=0;o<t.length;o++)if(e.match(t[o][0])){e=e.replace(t[o][0],t[o][1]);break}}return e}},Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t,i){t||(t=-1);for(var n=-1,r=t;r<this.length;r++)if(this[r]===e||i&&i(this[r],e)){n=r;break}return n}),String.prototype._uncountable_words||(String.prototype._uncountable_words=InflectionJS.uncountable_words),String.prototype._plural_rules||(String.prototype._plural_rules=InflectionJS.plural_rules),String.prototype._singular_rules||(String.prototype._singular_rules=InflectionJS.singular_rules),String.prototype._non_titlecased_words||(String.prototype._non_titlecased_words=InflectionJS.non_titlecased_words),String.prototype.pluralize||(String.prototype.pluralize=function(e){return InflectionJS.apply_rules(this,this._plural_rules,this._uncountable_words,e)}),String.prototype.singularize||(String.prototype.singularize=function(e){return InflectionJS.apply_rules(this,this._singular_rules,this._uncountable_words,e)}),String.prototype.camelize||(String.prototype.camelize=function(e){for(var t=this.toLowerCase(),i=t.split("/"),n=0;n<i.length;n++){for(var r=i[n].split("_"),o=e&&n+1===i.length?1:0,s=o;s<r.length;s++)r[s]=r[s].charAt(0).toUpperCase()+r[s].substring(1);i[n]=r.join("")}return t=i.join("::")}),String.prototype.underscore||(String.prototype.underscore=function(){for(var e=this,t=e.split("::"),i=0;i<t.length;i++)t[i]=t[i].replace(InflectionJS.uppercase,"_$1"),t[i]=t[i].replace(InflectionJS.underbar_prefix,"");return e=t.join("/").toLowerCase()}),String.prototype.humanize||(String.prototype.humanize=function(e){var t=this.toLowerCase();return t=t.replace(InflectionJS.id_suffix,""),t=t.replace(InflectionJS.underbar," "),e||(t=t.capitalize()),t}),String.prototype.capitalize||(String.prototype.capitalize=function(){var e=this.toLowerCase();return e=e.substring(0,1).toUpperCase()+e.substring(1)}),String.prototype.dasherize||(String.prototype.dasherize=function(){var e=this;return e=e.replace(InflectionJS.space_or_underbar,"-")}),String.prototype.titleize||(String.prototype.titleize=function(){var e=this.toLowerCase();e=e.replace(InflectionJS.underbar," ");for(var t=e.split(" "),i=0;i<t.length;i++){for(var n=t[i].split("-"),r=0;r<n.length;r++)this._non_titlecased_words.indexOf(n[r].toLowerCase())<0&&(n[r]=n[r].capitalize());t[i]=n.join("-")}return e=t.join(" "),e=e.substring(0,1).toUpperCase()+e.substring(1)}),String.prototype.demodulize||(String.prototype.demodulize=function(){var e=this,t=e.split("::");return e=t[t.length-1]}),String.prototype.tableize||(String.prototype.tableize=function(){var e=this;return e=e.underscore().pluralize()}),String.prototype.classify||(String.prototype.classify=function(){var e=this;return e=e.camelize().singularize()}),String.prototype.foreign_key||(String.prototype.foreign_key=function(e){var t=this;return t=t.demodulize().underscore()+(e?"":"_")+"id"}),String.prototype.ordinalize||(String.prototype.ordinalize=function(){for(var e=this,t=e.split(" "),i=0;i<t.length;i++){var n=parseInt(t[i]);if(0/0===n){var r=t[i].substring(t[i].length-2),o=t[i].substring(t[i].length-1),s="th";"11"!=r&&"12"!=r&&"13"!=r&&("1"===o?s="st":"2"===o?s="nd":"3"===o&&(s="rd")),t[i]+=s}}return e=t.join(" ")});
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * @overview RSVP - a tiny implementation of Promises/A+.
3
+ * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors
4
+ * @license Licensed under MIT license
5
+ * See https://raw.githubusercontent.com/tildeio/rsvp.js/master/LICENSE
6
+ * @version 3.0.16
7
+ */
8
+
9
+ (function(){"use strict";function lib$rsvp$utils$$objectOrFunction(x){return typeof x==="function"||typeof x==="object"&&x!==null}function lib$rsvp$utils$$isFunction(x){return typeof x==="function"}function lib$rsvp$utils$$isMaybeThenable(x){return typeof x==="object"&&x!==null}var lib$rsvp$utils$$_isArray;if(!Array.isArray){lib$rsvp$utils$$_isArray=function(x){return Object.prototype.toString.call(x)==="[object Array]"}}else{lib$rsvp$utils$$_isArray=Array.isArray}var lib$rsvp$utils$$isArray=lib$rsvp$utils$$_isArray;var lib$rsvp$utils$$now=Date.now||function(){return(new Date).getTime()};function lib$rsvp$utils$$F(){}var lib$rsvp$utils$$o_create=Object.create||function(o){if(arguments.length>1){throw new Error("Second argument not supported")}if(typeof o!=="object"){throw new TypeError("Argument must be an object")}lib$rsvp$utils$$F.prototype=o;return new lib$rsvp$utils$$F};function lib$rsvp$events$$indexOf(callbacks,callback){for(var i=0,l=callbacks.length;i<l;i++){if(callbacks[i]===callback){return i}}return-1}function lib$rsvp$events$$callbacksFor(object){var callbacks=object._promiseCallbacks;if(!callbacks){callbacks=object._promiseCallbacks={}}return callbacks}var lib$rsvp$events$$default={mixin:function(object){object["on"]=this["on"];object["off"]=this["off"];object["trigger"]=this["trigger"];object._promiseCallbacks=undefined;return object},on:function(eventName,callback){var allCallbacks=lib$rsvp$events$$callbacksFor(this),callbacks;callbacks=allCallbacks[eventName];if(!callbacks){callbacks=allCallbacks[eventName]=[]}if(lib$rsvp$events$$indexOf(callbacks,callback)===-1){callbacks.push(callback)}},off:function(eventName,callback){var allCallbacks=lib$rsvp$events$$callbacksFor(this),callbacks,index;if(!callback){allCallbacks[eventName]=[];return}callbacks=allCallbacks[eventName];index=lib$rsvp$events$$indexOf(callbacks,callback);if(index!==-1){callbacks.splice(index,1)}},trigger:function(eventName,options){var allCallbacks=lib$rsvp$events$$callbacksFor(this),callbacks,callback;if(callbacks=allCallbacks[eventName]){for(var i=0;i<callbacks.length;i++){callback=callbacks[i];callback(options)}}}};var lib$rsvp$config$$config={instrument:false};lib$rsvp$events$$default["mixin"](lib$rsvp$config$$config);function lib$rsvp$config$$configure(name,value){if(name==="onerror"){lib$rsvp$config$$config["on"]("error",value);return}if(arguments.length===2){lib$rsvp$config$$config[name]=value}else{return lib$rsvp$config$$config[name]}}var lib$rsvp$instrument$$queue=[];function lib$rsvp$instrument$$scheduleFlush(){setTimeout(function(){var entry;for(var i=0;i<lib$rsvp$instrument$$queue.length;i++){entry=lib$rsvp$instrument$$queue[i];var payload=entry.payload;payload.guid=payload.key+payload.id;payload.childGuid=payload.key+payload.childId;if(payload.error){payload.stack=payload.error.stack}lib$rsvp$config$$config["trigger"](entry.name,entry.payload)}lib$rsvp$instrument$$queue.length=0},50)}function lib$rsvp$instrument$$instrument(eventName,promise,child){if(1===lib$rsvp$instrument$$queue.push({name:eventName,payload:{key:promise._guidKey,id:promise._id,eventName:eventName,detail:promise._result,childId:child&&child._id,label:promise._label,timeStamp:lib$rsvp$utils$$now(),error:lib$rsvp$config$$config["instrument-with-stack"]?new Error(promise._label):null}})){lib$rsvp$instrument$$scheduleFlush()}}var lib$rsvp$instrument$$default=lib$rsvp$instrument$$instrument;function lib$rsvp$$internal$$withOwnPromise(){return new TypeError("A promises callback cannot return that same promise.")}function lib$rsvp$$internal$$noop(){}var lib$rsvp$$internal$$PENDING=void 0;var lib$rsvp$$internal$$FULFILLED=1;var lib$rsvp$$internal$$REJECTED=2;var lib$rsvp$$internal$$GET_THEN_ERROR=new lib$rsvp$$internal$$ErrorObject;function lib$rsvp$$internal$$getThen(promise){try{return promise.then}catch(error){lib$rsvp$$internal$$GET_THEN_ERROR.error=error;return lib$rsvp$$internal$$GET_THEN_ERROR}}function lib$rsvp$$internal$$tryThen(then,value,fulfillmentHandler,rejectionHandler){try{then.call(value,fulfillmentHandler,rejectionHandler)}catch(e){return e}}function lib$rsvp$$internal$$handleForeignThenable(promise,thenable,then){lib$rsvp$config$$config.async(function(promise){var sealed=false;var error=lib$rsvp$$internal$$tryThen(then,thenable,function(value){if(sealed){return}sealed=true;if(thenable!==value){lib$rsvp$$internal$$resolve(promise,value)}else{lib$rsvp$$internal$$fulfill(promise,value)}},function(reason){if(sealed){return}sealed=true;lib$rsvp$$internal$$reject(promise,reason)},"Settle: "+(promise._label||" unknown promise"));if(!sealed&&error){sealed=true;lib$rsvp$$internal$$reject(promise,error)}},promise)}function lib$rsvp$$internal$$handleOwnThenable(promise,thenable){if(thenable._state===lib$rsvp$$internal$$FULFILLED){lib$rsvp$$internal$$fulfill(promise,thenable._result)}else if(thenable._state===lib$rsvp$$internal$$REJECTED){thenable._onError=null;lib$rsvp$$internal$$reject(promise,thenable._result)}else{lib$rsvp$$internal$$subscribe(thenable,undefined,function(value){if(thenable!==value){lib$rsvp$$internal$$resolve(promise,value)}else{lib$rsvp$$internal$$fulfill(promise,value)}},function(reason){lib$rsvp$$internal$$reject(promise,reason)})}}function lib$rsvp$$internal$$handleMaybeThenable(promise,maybeThenable){if(maybeThenable.constructor===promise.constructor){lib$rsvp$$internal$$handleOwnThenable(promise,maybeThenable)}else{var then=lib$rsvp$$internal$$getThen(maybeThenable);if(then===lib$rsvp$$internal$$GET_THEN_ERROR){lib$rsvp$$internal$$reject(promise,lib$rsvp$$internal$$GET_THEN_ERROR.error)}else if(then===undefined){lib$rsvp$$internal$$fulfill(promise,maybeThenable)}else if(lib$rsvp$utils$$isFunction(then)){lib$rsvp$$internal$$handleForeignThenable(promise,maybeThenable,then)}else{lib$rsvp$$internal$$fulfill(promise,maybeThenable)}}}function lib$rsvp$$internal$$resolve(promise,value){if(promise===value){lib$rsvp$$internal$$fulfill(promise,value)}else if(lib$rsvp$utils$$objectOrFunction(value)){lib$rsvp$$internal$$handleMaybeThenable(promise,value)}else{lib$rsvp$$internal$$fulfill(promise,value)}}function lib$rsvp$$internal$$publishRejection(promise){if(promise._onError){promise._onError(promise._result)}lib$rsvp$$internal$$publish(promise)}function lib$rsvp$$internal$$fulfill(promise,value){if(promise._state!==lib$rsvp$$internal$$PENDING){return}promise._result=value;promise._state=lib$rsvp$$internal$$FULFILLED;if(promise._subscribers.length===0){if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("fulfilled",promise)}}else{lib$rsvp$config$$config.async(lib$rsvp$$internal$$publish,promise)}}function lib$rsvp$$internal$$reject(promise,reason){if(promise._state!==lib$rsvp$$internal$$PENDING){return}promise._state=lib$rsvp$$internal$$REJECTED;promise._result=reason;lib$rsvp$config$$config.async(lib$rsvp$$internal$$publishRejection,promise)}function lib$rsvp$$internal$$subscribe(parent,child,onFulfillment,onRejection){var subscribers=parent._subscribers;var length=subscribers.length;parent._onError=null;subscribers[length]=child;subscribers[length+lib$rsvp$$internal$$FULFILLED]=onFulfillment;subscribers[length+lib$rsvp$$internal$$REJECTED]=onRejection;if(length===0&&parent._state){lib$rsvp$config$$config.async(lib$rsvp$$internal$$publish,parent)}}function lib$rsvp$$internal$$publish(promise){var subscribers=promise._subscribers;var settled=promise._state;if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default(settled===lib$rsvp$$internal$$FULFILLED?"fulfilled":"rejected",promise)}if(subscribers.length===0){return}var child,callback,detail=promise._result;for(var i=0;i<subscribers.length;i+=3){child=subscribers[i];callback=subscribers[i+settled];if(child){lib$rsvp$$internal$$invokeCallback(settled,child,callback,detail)}else{callback(detail)}}promise._subscribers.length=0}function lib$rsvp$$internal$$ErrorObject(){this.error=null}var lib$rsvp$$internal$$TRY_CATCH_ERROR=new lib$rsvp$$internal$$ErrorObject;function lib$rsvp$$internal$$tryCatch(callback,detail){try{return callback(detail)}catch(e){lib$rsvp$$internal$$TRY_CATCH_ERROR.error=e;return lib$rsvp$$internal$$TRY_CATCH_ERROR}}function lib$rsvp$$internal$$invokeCallback(settled,promise,callback,detail){var hasCallback=lib$rsvp$utils$$isFunction(callback),value,error,succeeded,failed;if(hasCallback){value=lib$rsvp$$internal$$tryCatch(callback,detail);if(value===lib$rsvp$$internal$$TRY_CATCH_ERROR){failed=true;error=value.error;value=null}else{succeeded=true}if(promise===value){lib$rsvp$$internal$$reject(promise,lib$rsvp$$internal$$withOwnPromise());return}}else{value=detail;succeeded=true}if(promise._state!==lib$rsvp$$internal$$PENDING){}else if(hasCallback&&succeeded){lib$rsvp$$internal$$resolve(promise,value)}else if(failed){lib$rsvp$$internal$$reject(promise,error)}else if(settled===lib$rsvp$$internal$$FULFILLED){lib$rsvp$$internal$$fulfill(promise,value)}else if(settled===lib$rsvp$$internal$$REJECTED){lib$rsvp$$internal$$reject(promise,value)}}function lib$rsvp$$internal$$initializePromise(promise,resolver){var resolved=false;try{resolver(function resolvePromise(value){if(resolved){return}resolved=true;lib$rsvp$$internal$$resolve(promise,value)},function rejectPromise(reason){if(resolved){return}resolved=true;lib$rsvp$$internal$$reject(promise,reason)})}catch(e){lib$rsvp$$internal$$reject(promise,e)}}function lib$rsvp$enumerator$$makeSettledResult(state,position,value){if(state===lib$rsvp$$internal$$FULFILLED){return{state:"fulfilled",value:value}}else{return{state:"rejected",reason:value}}}function lib$rsvp$enumerator$$Enumerator(Constructor,input,abortOnReject,label){this._instanceConstructor=Constructor;this.promise=new Constructor(lib$rsvp$$internal$$noop,label);this._abortOnReject=abortOnReject;if(this._validateInput(input)){this._input=input;this.length=input.length;this._remaining=input.length;this._init();if(this.length===0){lib$rsvp$$internal$$fulfill(this.promise,this._result)}else{this.length=this.length||0;this._enumerate();if(this._remaining===0){lib$rsvp$$internal$$fulfill(this.promise,this._result)}}}else{lib$rsvp$$internal$$reject(this.promise,this._validationError())}}var lib$rsvp$enumerator$$default=lib$rsvp$enumerator$$Enumerator;lib$rsvp$enumerator$$Enumerator.prototype._validateInput=function(input){return lib$rsvp$utils$$isArray(input)};lib$rsvp$enumerator$$Enumerator.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")};lib$rsvp$enumerator$$Enumerator.prototype._init=function(){this._result=new Array(this.length)};lib$rsvp$enumerator$$Enumerator.prototype._enumerate=function(){var length=this.length;var promise=this.promise;var input=this._input;for(var i=0;promise._state===lib$rsvp$$internal$$PENDING&&i<length;i++){this._eachEntry(input[i],i)}};lib$rsvp$enumerator$$Enumerator.prototype._eachEntry=function(entry,i){var c=this._instanceConstructor;if(lib$rsvp$utils$$isMaybeThenable(entry)){if(entry.constructor===c&&entry._state!==lib$rsvp$$internal$$PENDING){entry._onError=null;this._settledAt(entry._state,i,entry._result)}else{this._willSettleAt(c.resolve(entry),i)}}else{this._remaining--;this._result[i]=this._makeResult(lib$rsvp$$internal$$FULFILLED,i,entry)}};lib$rsvp$enumerator$$Enumerator.prototype._settledAt=function(state,i,value){var promise=this.promise;if(promise._state===lib$rsvp$$internal$$PENDING){this._remaining--;if(this._abortOnReject&&state===lib$rsvp$$internal$$REJECTED){lib$rsvp$$internal$$reject(promise,value)}else{this._result[i]=this._makeResult(state,i,value)}}if(this._remaining===0){lib$rsvp$$internal$$fulfill(promise,this._result)}};lib$rsvp$enumerator$$Enumerator.prototype._makeResult=function(state,i,value){return value};lib$rsvp$enumerator$$Enumerator.prototype._willSettleAt=function(promise,i){var enumerator=this;lib$rsvp$$internal$$subscribe(promise,undefined,function(value){enumerator._settledAt(lib$rsvp$$internal$$FULFILLED,i,value)},function(reason){enumerator._settledAt(lib$rsvp$$internal$$REJECTED,i,reason)})};function lib$rsvp$promise$all$$all(entries,label){return new lib$rsvp$enumerator$$default(this,entries,true,label).promise}var lib$rsvp$promise$all$$default=lib$rsvp$promise$all$$all;function lib$rsvp$promise$race$$race(entries,label){var Constructor=this;var promise=new Constructor(lib$rsvp$$internal$$noop,label);if(!lib$rsvp$utils$$isArray(entries)){lib$rsvp$$internal$$reject(promise,new TypeError("You must pass an array to race."));return promise}var length=entries.length;function onFulfillment(value){lib$rsvp$$internal$$resolve(promise,value)}function onRejection(reason){lib$rsvp$$internal$$reject(promise,reason)}for(var i=0;promise._state===lib$rsvp$$internal$$PENDING&&i<length;i++){lib$rsvp$$internal$$subscribe(Constructor.resolve(entries[i]),undefined,onFulfillment,onRejection)}return promise}var lib$rsvp$promise$race$$default=lib$rsvp$promise$race$$race;function lib$rsvp$promise$resolve$$resolve(object,label){var Constructor=this;if(object&&typeof object==="object"&&object.constructor===Constructor){return object}var promise=new Constructor(lib$rsvp$$internal$$noop,label);lib$rsvp$$internal$$resolve(promise,object);return promise}var lib$rsvp$promise$resolve$$default=lib$rsvp$promise$resolve$$resolve;function lib$rsvp$promise$reject$$reject(reason,label){var Constructor=this;var promise=new Constructor(lib$rsvp$$internal$$noop,label);lib$rsvp$$internal$$reject(promise,reason);return promise}var lib$rsvp$promise$reject$$default=lib$rsvp$promise$reject$$reject;var lib$rsvp$promise$$guidKey="rsvp_"+lib$rsvp$utils$$now()+"-";var lib$rsvp$promise$$counter=0;function lib$rsvp$promise$$needsResolver(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function lib$rsvp$promise$$needsNew(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function lib$rsvp$promise$$Promise(resolver,label){this._id=lib$rsvp$promise$$counter++;this._label=label;this._state=undefined;this._result=undefined;this._subscribers=[];if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("created",this)}if(lib$rsvp$$internal$$noop!==resolver){if(!lib$rsvp$utils$$isFunction(resolver)){lib$rsvp$promise$$needsResolver()}if(!(this instanceof lib$rsvp$promise$$Promise)){lib$rsvp$promise$$needsNew()}lib$rsvp$$internal$$initializePromise(this,resolver)}}var lib$rsvp$promise$$default=lib$rsvp$promise$$Promise;lib$rsvp$promise$$Promise.cast=lib$rsvp$promise$resolve$$default;lib$rsvp$promise$$Promise.all=lib$rsvp$promise$all$$default;lib$rsvp$promise$$Promise.race=lib$rsvp$promise$race$$default;lib$rsvp$promise$$Promise.resolve=lib$rsvp$promise$resolve$$default;lib$rsvp$promise$$Promise.reject=lib$rsvp$promise$reject$$default;lib$rsvp$promise$$Promise.prototype={constructor:lib$rsvp$promise$$Promise,_guidKey:lib$rsvp$promise$$guidKey,_onError:function(reason){lib$rsvp$config$$config.async(function(promise){setTimeout(function(){if(promise._onError){lib$rsvp$config$$config["trigger"]("error",reason)}},0)},this)},then:function(onFulfillment,onRejection,label){var parent=this;var state=parent._state;if(state===lib$rsvp$$internal$$FULFILLED&&!onFulfillment||state===lib$rsvp$$internal$$REJECTED&&!onRejection){if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("chained",this,this)}return this}parent._onError=null;var child=new this.constructor(lib$rsvp$$internal$$noop,label);var result=parent._result;if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("chained",parent,child)}if(state){var callback=arguments[state-1];lib$rsvp$config$$config.async(function(){lib$rsvp$$internal$$invokeCallback(state,child,callback,result)})}else{lib$rsvp$$internal$$subscribe(parent,child,onFulfillment,onRejection)}return child},"catch":function(onRejection,label){return this.then(null,onRejection,label)},"finally":function(callback,label){var constructor=this.constructor;return this.then(function(value){return constructor.resolve(callback()).then(function(){return value})},function(reason){return constructor.resolve(callback()).then(function(){throw reason})},label)}};function lib$rsvp$all$settled$$AllSettled(Constructor,entries,label){this._superConstructor(Constructor,entries,false,label)}lib$rsvp$all$settled$$AllSettled.prototype=lib$rsvp$utils$$o_create(lib$rsvp$enumerator$$default.prototype);lib$rsvp$all$settled$$AllSettled.prototype._superConstructor=lib$rsvp$enumerator$$default;lib$rsvp$all$settled$$AllSettled.prototype._makeResult=lib$rsvp$enumerator$$makeSettledResult;lib$rsvp$all$settled$$AllSettled.prototype._validationError=function(){return new Error("allSettled must be called with an array")};function lib$rsvp$all$settled$$allSettled(entries,label){return new lib$rsvp$all$settled$$AllSettled(lib$rsvp$promise$$default,entries,label).promise}var lib$rsvp$all$settled$$default=lib$rsvp$all$settled$$allSettled;function lib$rsvp$all$$all(array,label){return lib$rsvp$promise$$default.all(array,label)}var lib$rsvp$all$$default=lib$rsvp$all$$all;var lib$rsvp$asap$$len=0;var lib$rsvp$asap$$toString={}.toString;var lib$rsvp$asap$$vertxNext;function lib$rsvp$asap$$asap(callback,arg){lib$rsvp$asap$$queue[lib$rsvp$asap$$len]=callback;lib$rsvp$asap$$queue[lib$rsvp$asap$$len+1]=arg;lib$rsvp$asap$$len+=2;if(lib$rsvp$asap$$len===2){lib$rsvp$asap$$scheduleFlush()}}var lib$rsvp$asap$$default=lib$rsvp$asap$$asap;var lib$rsvp$asap$$browserWindow=typeof window!=="undefined"?window:undefined;var lib$rsvp$asap$$browserGlobal=lib$rsvp$asap$$browserWindow||{};var lib$rsvp$asap$$BrowserMutationObserver=lib$rsvp$asap$$browserGlobal.MutationObserver||lib$rsvp$asap$$browserGlobal.WebKitMutationObserver;var lib$rsvp$asap$$isNode=typeof process!=="undefined"&&{}.toString.call(process)==="[object process]";var lib$rsvp$asap$$isWorker=typeof Uint8ClampedArray!=="undefined"&&typeof importScripts!=="undefined"&&typeof MessageChannel!=="undefined";function lib$rsvp$asap$$useNextTick(){var nextTick=process.nextTick;var version=process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);if(Array.isArray(version)&&version[1]==="0"&&version[2]==="10"){nextTick=setImmediate}return function(){nextTick(lib$rsvp$asap$$flush)}}function lib$rsvp$asap$$useVertxTimer(){return function(){lib$rsvp$asap$$vertxNext(lib$rsvp$asap$$flush)}}function lib$rsvp$asap$$useMutationObserver(){var iterations=0;var observer=new lib$rsvp$asap$$BrowserMutationObserver(lib$rsvp$asap$$flush);var node=document.createTextNode("");observer.observe(node,{characterData:true});return function(){node.data=iterations=++iterations%2}}function lib$rsvp$asap$$useMessageChannel(){var channel=new MessageChannel;channel.port1.onmessage=lib$rsvp$asap$$flush;return function(){channel.port2.postMessage(0)}}function lib$rsvp$asap$$useSetTimeout(){return function(){setTimeout(lib$rsvp$asap$$flush,1)}}var lib$rsvp$asap$$queue=new Array(1e3);function lib$rsvp$asap$$flush(){for(var i=0;i<lib$rsvp$asap$$len;i+=2){var callback=lib$rsvp$asap$$queue[i];var arg=lib$rsvp$asap$$queue[i+1];callback(arg);lib$rsvp$asap$$queue[i]=undefined;lib$rsvp$asap$$queue[i+1]=undefined}lib$rsvp$asap$$len=0}function lib$rsvp$asap$$attemptVertex(){try{var r=require;var vertx=r("vertx");lib$rsvp$asap$$vertxNext=vertx.runOnLoop||vertx.runOnContext;return lib$rsvp$asap$$useVertxTimer()}catch(e){return lib$rsvp$asap$$useSetTimeout()}}var lib$rsvp$asap$$scheduleFlush;if(lib$rsvp$asap$$isNode){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useNextTick()}else if(lib$rsvp$asap$$BrowserMutationObserver){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useMutationObserver()}else if(lib$rsvp$asap$$isWorker){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useMessageChannel()}else if(lib$rsvp$asap$$browserWindow===undefined&&typeof require==="function"){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$attemptVertex()}else{lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useSetTimeout()}function lib$rsvp$defer$$defer(label){var deferred={};deferred["promise"]=new lib$rsvp$promise$$default(function(resolve,reject){deferred["resolve"]=resolve;deferred["reject"]=reject},label);return deferred}var lib$rsvp$defer$$default=lib$rsvp$defer$$defer;function lib$rsvp$filter$$filter(promises,filterFn,label){return lib$rsvp$promise$$default.all(promises,label).then(function(values){if(!lib$rsvp$utils$$isFunction(filterFn)){throw new TypeError("You must pass a function as filter's second argument.")}var length=values.length;var filtered=new Array(length);for(var i=0;i<length;i++){filtered[i]=filterFn(values[i])}return lib$rsvp$promise$$default.all(filtered,label).then(function(filtered){var results=new Array(length);var newLength=0;for(var i=0;i<length;i++){if(filtered[i]){results[newLength]=values[i];newLength++}}results.length=newLength;return results})})}var lib$rsvp$filter$$default=lib$rsvp$filter$$filter;function lib$rsvp$promise$hash$$PromiseHash(Constructor,object,label){this._superConstructor(Constructor,object,true,label)}var lib$rsvp$promise$hash$$default=lib$rsvp$promise$hash$$PromiseHash;lib$rsvp$promise$hash$$PromiseHash.prototype=lib$rsvp$utils$$o_create(lib$rsvp$enumerator$$default.prototype);lib$rsvp$promise$hash$$PromiseHash.prototype._superConstructor=lib$rsvp$enumerator$$default;lib$rsvp$promise$hash$$PromiseHash.prototype._init=function(){this._result={}};lib$rsvp$promise$hash$$PromiseHash.prototype._validateInput=function(input){return input&&typeof input==="object"};lib$rsvp$promise$hash$$PromiseHash.prototype._validationError=function(){return new Error("Promise.hash must be called with an object")};lib$rsvp$promise$hash$$PromiseHash.prototype._enumerate=function(){var promise=this.promise;var input=this._input;var results=[];for(var key in input){if(promise._state===lib$rsvp$$internal$$PENDING&&input.hasOwnProperty(key)){results.push({position:key,entry:input[key]})}}var length=results.length;this._remaining=length;var result;for(var i=0;promise._state===lib$rsvp$$internal$$PENDING&&i<length;i++){result=results[i];this._eachEntry(result.entry,result.position)}};function lib$rsvp$hash$settled$$HashSettled(Constructor,object,label){this._superConstructor(Constructor,object,false,label)}lib$rsvp$hash$settled$$HashSettled.prototype=lib$rsvp$utils$$o_create(lib$rsvp$promise$hash$$default.prototype);lib$rsvp$hash$settled$$HashSettled.prototype._superConstructor=lib$rsvp$enumerator$$default;lib$rsvp$hash$settled$$HashSettled.prototype._makeResult=lib$rsvp$enumerator$$makeSettledResult;lib$rsvp$hash$settled$$HashSettled.prototype._validationError=function(){return new Error("hashSettled must be called with an object")};function lib$rsvp$hash$settled$$hashSettled(object,label){return new lib$rsvp$hash$settled$$HashSettled(lib$rsvp$promise$$default,object,label).promise}var lib$rsvp$hash$settled$$default=lib$rsvp$hash$settled$$hashSettled;function lib$rsvp$hash$$hash(object,label){return new lib$rsvp$promise$hash$$default(lib$rsvp$promise$$default,object,label).promise}var lib$rsvp$hash$$default=lib$rsvp$hash$$hash;function lib$rsvp$map$$map(promises,mapFn,label){return lib$rsvp$promise$$default.all(promises,label).then(function(values){if(!lib$rsvp$utils$$isFunction(mapFn)){throw new TypeError("You must pass a function as map's second argument.")}var length=values.length;var results=new Array(length);for(var i=0;i<length;i++){results[i]=mapFn(values[i])}return lib$rsvp$promise$$default.all(results,label)})}var lib$rsvp$map$$default=lib$rsvp$map$$map;function lib$rsvp$node$$Result(){this.value=undefined}var lib$rsvp$node$$ERROR=new lib$rsvp$node$$Result;var lib$rsvp$node$$GET_THEN_ERROR=new lib$rsvp$node$$Result;function lib$rsvp$node$$getThen(obj){try{return obj.then}catch(error){lib$rsvp$node$$ERROR.value=error;return lib$rsvp$node$$ERROR}}function lib$rsvp$node$$tryApply(f,s,a){try{f.apply(s,a)}catch(error){lib$rsvp$node$$ERROR.value=error;return lib$rsvp$node$$ERROR}}function lib$rsvp$node$$makeObject(_,argumentNames){var obj={};var name;var i;var length=_.length;var args=new Array(length);for(var x=0;x<length;x++){args[x]=_[x]}for(i=0;i<argumentNames.length;i++){name=argumentNames[i];obj[name]=args[i+1]}return obj}function lib$rsvp$node$$arrayResult(_){var length=_.length;var args=new Array(length-1);for(var i=1;i<length;i++){args[i-1]=_[i]}return args}function lib$rsvp$node$$wrapThenable(then,promise){return{then:function(onFulFillment,onRejection){return then.call(promise,onFulFillment,onRejection)}}}function lib$rsvp$node$$denodeify(nodeFunc,options){var fn=function(){var self=this;var l=arguments.length;var args=new Array(l+1);var arg;var promiseInput=false;for(var i=0;i<l;++i){arg=arguments[i];if(!promiseInput){promiseInput=lib$rsvp$node$$needsPromiseInput(arg);if(promiseInput===lib$rsvp$node$$GET_THEN_ERROR){var p=new lib$rsvp$promise$$default(lib$rsvp$$internal$$noop);lib$rsvp$$internal$$reject(p,lib$rsvp$node$$GET_THEN_ERROR.value);return p}else if(promiseInput&&promiseInput!==true){arg=lib$rsvp$node$$wrapThenable(promiseInput,arg)}}args[i]=arg}var promise=new lib$rsvp$promise$$default(lib$rsvp$$internal$$noop);args[l]=function(err,val){if(err)lib$rsvp$$internal$$reject(promise,err);else if(options===undefined)lib$rsvp$$internal$$resolve(promise,val);else if(options===true)lib$rsvp$$internal$$resolve(promise,lib$rsvp$node$$arrayResult(arguments));else if(lib$rsvp$utils$$isArray(options))lib$rsvp$$internal$$resolve(promise,lib$rsvp$node$$makeObject(arguments,options));else lib$rsvp$$internal$$resolve(promise,val)};if(promiseInput){return lib$rsvp$node$$handlePromiseInput(promise,args,nodeFunc,self)}else{return lib$rsvp$node$$handleValueInput(promise,args,nodeFunc,self)}};fn.__proto__=nodeFunc;return fn}var lib$rsvp$node$$default=lib$rsvp$node$$denodeify;function lib$rsvp$node$$handleValueInput(promise,args,nodeFunc,self){var result=lib$rsvp$node$$tryApply(nodeFunc,self,args);if(result===lib$rsvp$node$$ERROR){lib$rsvp$$internal$$reject(promise,result.value)}return promise}function lib$rsvp$node$$handlePromiseInput(promise,args,nodeFunc,self){return lib$rsvp$promise$$default.all(args).then(function(args){var result=lib$rsvp$node$$tryApply(nodeFunc,self,args);if(result===lib$rsvp$node$$ERROR){lib$rsvp$$internal$$reject(promise,result.value)}return promise})}function lib$rsvp$node$$needsPromiseInput(arg){if(arg&&typeof arg==="object"){if(arg.constructor===lib$rsvp$promise$$default){return true}else{return lib$rsvp$node$$getThen(arg)}}else{return false}}function lib$rsvp$race$$race(array,label){return lib$rsvp$promise$$default.race(array,label)}var lib$rsvp$race$$default=lib$rsvp$race$$race;function lib$rsvp$reject$$reject(reason,label){return lib$rsvp$promise$$default.reject(reason,label)}var lib$rsvp$reject$$default=lib$rsvp$reject$$reject;function lib$rsvp$resolve$$resolve(value,label){return lib$rsvp$promise$$default.resolve(value,label)}var lib$rsvp$resolve$$default=lib$rsvp$resolve$$resolve;function lib$rsvp$rethrow$$rethrow(reason){setTimeout(function(){throw reason});throw reason}var lib$rsvp$rethrow$$default=lib$rsvp$rethrow$$rethrow;lib$rsvp$config$$config.async=lib$rsvp$asap$$default;var lib$rsvp$$cast=lib$rsvp$resolve$$default;function lib$rsvp$$async(callback,arg){lib$rsvp$config$$config.async(callback,arg)}function lib$rsvp$$on(){lib$rsvp$config$$config["on"].apply(lib$rsvp$config$$config,arguments)}function lib$rsvp$$off(){lib$rsvp$config$$config["off"].apply(lib$rsvp$config$$config,arguments)}if(typeof window!=="undefined"&&typeof window["__PROMISE_INSTRUMENTATION__"]==="object"){var lib$rsvp$$callbacks=window["__PROMISE_INSTRUMENTATION__"];lib$rsvp$config$$configure("instrument",true);for(var lib$rsvp$$eventName in lib$rsvp$$callbacks){if(lib$rsvp$$callbacks.hasOwnProperty(lib$rsvp$$eventName)){lib$rsvp$$on(lib$rsvp$$eventName,lib$rsvp$$callbacks[lib$rsvp$$eventName])}}}var lib$rsvp$umd$$RSVP={race:lib$rsvp$race$$default,Promise:lib$rsvp$promise$$default,allSettled:lib$rsvp$all$settled$$default,hash:lib$rsvp$hash$$default,hashSettled:lib$rsvp$hash$settled$$default,denodeify:lib$rsvp$node$$default,on:lib$rsvp$$on,off:lib$rsvp$$off,map:lib$rsvp$map$$default,filter:lib$rsvp$filter$$default,resolve:lib$rsvp$resolve$$default,reject:lib$rsvp$reject$$default,all:lib$rsvp$all$$default,rethrow:lib$rsvp$rethrow$$default,defer:lib$rsvp$defer$$default,EventTarget:lib$rsvp$events$$default,configure:lib$rsvp$config$$configure,async:lib$rsvp$$async};if(typeof define==="function"&&define["amd"]){define(function(){return lib$rsvp$umd$$RSVP})}else if(typeof module!=="undefined"&&module["exports"]){module["exports"]=lib$rsvp$umd$$RSVP}else if(typeof this!=="undefined"){this["RSVP"]=lib$rsvp$umd$$RSVP}}).call(this);
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Includes rsvp.js (Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors) & inflection.js (Copyright (c) 2010 Ryan Schuft - ryan.schuft@gmail.com)
3
+ * Intended for use with the Stratosphere Ruby Gem
4
+ * Copyright (c) 2015 Zachary Golba (zak@zacharygolba.com)
5
+ */
6
+ window&&!window.InflectionJS&&(window.InflectionJS=null),InflectionJS={uncountable_words:["equipment","information","rice","money","species","series","fish","sheep","moose","deer","news"],plural_rules:[[new RegExp("(m)an$","gi"),"$1en"],[new RegExp("(pe)rson$","gi"),"$1ople"],[new RegExp("(child)$","gi"),"$1ren"],[new RegExp("^(ox)$","gi"),"$1en"],[new RegExp("(ax|test)is$","gi"),"$1es"],[new RegExp("(octop|vir)us$","gi"),"$1i"],[new RegExp("(alias|status)$","gi"),"$1es"],[new RegExp("(bu)s$","gi"),"$1ses"],[new RegExp("(buffal|tomat|potat)o$","gi"),"$1oes"],[new RegExp("([ti])um$","gi"),"$1a"],[new RegExp("sis$","gi"),"ses"],[new RegExp("(?:([^f])fe|([lr])f)$","gi"),"$1$2ves"],[new RegExp("(hive)$","gi"),"$1s"],[new RegExp("([^aeiouy]|qu)y$","gi"),"$1ies"],[new RegExp("(x|ch|ss|sh)$","gi"),"$1es"],[new RegExp("(matr|vert|ind)ix|ex$","gi"),"$1ices"],[new RegExp("([m|l])ouse$","gi"),"$1ice"],[new RegExp("(quiz)$","gi"),"$1zes"],[new RegExp("s$","gi"),"s"],[new RegExp("$","gi"),"s"]],singular_rules:[[new RegExp("(m)en$","gi"),"$1an"],[new RegExp("(pe)ople$","gi"),"$1rson"],[new RegExp("(child)ren$","gi"),"$1"],[new RegExp("([ti])a$","gi"),"$1um"],[new RegExp("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$","gi"),"$1$2sis"],[new RegExp("(hive)s$","gi"),"$1"],[new RegExp("(tive)s$","gi"),"$1"],[new RegExp("(curve)s$","gi"),"$1"],[new RegExp("([lr])ves$","gi"),"$1f"],[new RegExp("([^fo])ves$","gi"),"$1fe"],[new RegExp("([^aeiouy]|qu)ies$","gi"),"$1y"],[new RegExp("(s)eries$","gi"),"$1eries"],[new RegExp("(m)ovies$","gi"),"$1ovie"],[new RegExp("(x|ch|ss|sh)es$","gi"),"$1"],[new RegExp("([m|l])ice$","gi"),"$1ouse"],[new RegExp("(bus)es$","gi"),"$1"],[new RegExp("(o)es$","gi"),"$1"],[new RegExp("(shoe)s$","gi"),"$1"],[new RegExp("(cris|ax|test)es$","gi"),"$1is"],[new RegExp("(octop|vir)i$","gi"),"$1us"],[new RegExp("(alias|status)es$","gi"),"$1"],[new RegExp("^(ox)en","gi"),"$1"],[new RegExp("(vert|ind)ices$","gi"),"$1ex"],[new RegExp("(matr)ices$","gi"),"$1ix"],[new RegExp("(quiz)zes$","gi"),"$1"],[new RegExp("s$","gi"),""]],non_titlecased_words:["and","or","nor","a","an","the","so","but","to","of","at","by","from","into","on","onto","off","out","in","over","with","for"],id_suffix:new RegExp("(_ids|_id)$","g"),underbar:new RegExp("_","g"),space_or_underbar:new RegExp("[ _]","g"),uppercase:new RegExp("([A-Z])","g"),underbar_prefix:new RegExp("^_"),apply_rules:function(e,t,i,n){if(n)e=n;else{var r=i.indexOf(e.toLowerCase())>-1;if(!r)for(var o=0;o<t.length;o++)if(e.match(t[o][0])){e=e.replace(t[o][0],t[o][1]);break}}return e}},Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t,i){t||(t=-1);for(var n=-1,r=t;r<this.length;r++)if(this[r]===e||i&&i(this[r],e)){n=r;break}return n}),String.prototype._uncountable_words||(String.prototype._uncountable_words=InflectionJS.uncountable_words),String.prototype._plural_rules||(String.prototype._plural_rules=InflectionJS.plural_rules),String.prototype._singular_rules||(String.prototype._singular_rules=InflectionJS.singular_rules),String.prototype._non_titlecased_words||(String.prototype._non_titlecased_words=InflectionJS.non_titlecased_words),String.prototype.pluralize||(String.prototype.pluralize=function(e){return InflectionJS.apply_rules(this,this._plural_rules,this._uncountable_words,e)}),String.prototype.singularize||(String.prototype.singularize=function(e){return InflectionJS.apply_rules(this,this._singular_rules,this._uncountable_words,e)}),String.prototype.camelize||(String.prototype.camelize=function(e){for(var t=this.toLowerCase(),i=t.split("/"),n=0;n<i.length;n++){for(var r=i[n].split("_"),o=e&&n+1===i.length?1:0,s=o;s<r.length;s++)r[s]=r[s].charAt(0).toUpperCase()+r[s].substring(1);i[n]=r.join("")}return t=i.join("::")}),String.prototype.underscore||(String.prototype.underscore=function(){for(var e=this,t=e.split("::"),i=0;i<t.length;i++)t[i]=t[i].replace(InflectionJS.uppercase,"_$1"),t[i]=t[i].replace(InflectionJS.underbar_prefix,"");return e=t.join("/").toLowerCase()}),String.prototype.humanize||(String.prototype.humanize=function(e){var t=this.toLowerCase();return t=t.replace(InflectionJS.id_suffix,""),t=t.replace(InflectionJS.underbar," "),e||(t=t.capitalize()),t}),String.prototype.capitalize||(String.prototype.capitalize=function(){var e=this.toLowerCase();return e=e.substring(0,1).toUpperCase()+e.substring(1)}),String.prototype.dasherize||(String.prototype.dasherize=function(){var e=this;return e=e.replace(InflectionJS.space_or_underbar,"-")}),String.prototype.titleize||(String.prototype.titleize=function(){var e=this.toLowerCase();e=e.replace(InflectionJS.underbar," ");for(var t=e.split(" "),i=0;i<t.length;i++){for(var n=t[i].split("-"),r=0;r<n.length;r++)this._non_titlecased_words.indexOf(n[r].toLowerCase())<0&&(n[r]=n[r].capitalize());t[i]=n.join("-")}return e=t.join(" "),e=e.substring(0,1).toUpperCase()+e.substring(1)}),String.prototype.demodulize||(String.prototype.demodulize=function(){var e=this,t=e.split("::");return e=t[t.length-1]}),String.prototype.tableize||(String.prototype.tableize=function(){var e=this;return e=e.underscore().pluralize()}),String.prototype.classify||(String.prototype.classify=function(){var e=this;return e=e.camelize().singularize()}),String.prototype.foreign_key||(String.prototype.foreign_key=function(e){var t=this;return t=t.demodulize().underscore()+(e?"":"_")+"id"}),String.prototype.ordinalize||(String.prototype.ordinalize=function(){for(var e=this,t=e.split(" "),i=0;i<t.length;i++){var n=parseInt(t[i]);if(0/0===n){var r=t[i].substring(t[i].length-2),o=t[i].substring(t[i].length-1),s="th";"11"!=r&&"12"!=r&&"13"!=r&&("1"===o?s="st":"2"===o?s="nd":"3"===o&&(s="rd")),t[i]+=s}}return e=t.join(" ")});
7
+ (function(){"use strict";function lib$rsvp$utils$$objectOrFunction(x){return typeof x==="function"||typeof x==="object"&&x!==null}function lib$rsvp$utils$$isFunction(x){return typeof x==="function"}function lib$rsvp$utils$$isMaybeThenable(x){return typeof x==="object"&&x!==null}var lib$rsvp$utils$$_isArray;if(!Array.isArray){lib$rsvp$utils$$_isArray=function(x){return Object.prototype.toString.call(x)==="[object Array]"}}else{lib$rsvp$utils$$_isArray=Array.isArray}var lib$rsvp$utils$$isArray=lib$rsvp$utils$$_isArray;var lib$rsvp$utils$$now=Date.now||function(){return(new Date).getTime()};function lib$rsvp$utils$$F(){}var lib$rsvp$utils$$o_create=Object.create||function(o){if(arguments.length>1){throw new Error("Second argument not supported")}if(typeof o!=="object"){throw new TypeError("Argument must be an object")}lib$rsvp$utils$$F.prototype=o;return new lib$rsvp$utils$$F};function lib$rsvp$events$$indexOf(callbacks,callback){for(var i=0,l=callbacks.length;i<l;i++){if(callbacks[i]===callback){return i}}return-1}function lib$rsvp$events$$callbacksFor(object){var callbacks=object._promiseCallbacks;if(!callbacks){callbacks=object._promiseCallbacks={}}return callbacks}var lib$rsvp$events$$default={mixin:function(object){object["on"]=this["on"];object["off"]=this["off"];object["trigger"]=this["trigger"];object._promiseCallbacks=undefined;return object},on:function(eventName,callback){var allCallbacks=lib$rsvp$events$$callbacksFor(this),callbacks;callbacks=allCallbacks[eventName];if(!callbacks){callbacks=allCallbacks[eventName]=[]}if(lib$rsvp$events$$indexOf(callbacks,callback)===-1){callbacks.push(callback)}},off:function(eventName,callback){var allCallbacks=lib$rsvp$events$$callbacksFor(this),callbacks,index;if(!callback){allCallbacks[eventName]=[];return}callbacks=allCallbacks[eventName];index=lib$rsvp$events$$indexOf(callbacks,callback);if(index!==-1){callbacks.splice(index,1)}},trigger:function(eventName,options){var allCallbacks=lib$rsvp$events$$callbacksFor(this),callbacks,callback;if(callbacks=allCallbacks[eventName]){for(var i=0;i<callbacks.length;i++){callback=callbacks[i];callback(options)}}}};var lib$rsvp$config$$config={instrument:false};lib$rsvp$events$$default["mixin"](lib$rsvp$config$$config);function lib$rsvp$config$$configure(name,value){if(name==="onerror"){lib$rsvp$config$$config["on"]("error",value);return}if(arguments.length===2){lib$rsvp$config$$config[name]=value}else{return lib$rsvp$config$$config[name]}}var lib$rsvp$instrument$$queue=[];function lib$rsvp$instrument$$scheduleFlush(){setTimeout(function(){var entry;for(var i=0;i<lib$rsvp$instrument$$queue.length;i++){entry=lib$rsvp$instrument$$queue[i];var payload=entry.payload;payload.guid=payload.key+payload.id;payload.childGuid=payload.key+payload.childId;if(payload.error){payload.stack=payload.error.stack}lib$rsvp$config$$config["trigger"](entry.name,entry.payload)}lib$rsvp$instrument$$queue.length=0},50)}function lib$rsvp$instrument$$instrument(eventName,promise,child){if(1===lib$rsvp$instrument$$queue.push({name:eventName,payload:{key:promise._guidKey,id:promise._id,eventName:eventName,detail:promise._result,childId:child&&child._id,label:promise._label,timeStamp:lib$rsvp$utils$$now(),error:lib$rsvp$config$$config["instrument-with-stack"]?new Error(promise._label):null}})){lib$rsvp$instrument$$scheduleFlush()}}var lib$rsvp$instrument$$default=lib$rsvp$instrument$$instrument;function lib$rsvp$$internal$$withOwnPromise(){return new TypeError("A promises callback cannot return that same promise.")}function lib$rsvp$$internal$$noop(){}var lib$rsvp$$internal$$PENDING=void 0;var lib$rsvp$$internal$$FULFILLED=1;var lib$rsvp$$internal$$REJECTED=2;var lib$rsvp$$internal$$GET_THEN_ERROR=new lib$rsvp$$internal$$ErrorObject;function lib$rsvp$$internal$$getThen(promise){try{return promise.then}catch(error){lib$rsvp$$internal$$GET_THEN_ERROR.error=error;return lib$rsvp$$internal$$GET_THEN_ERROR}}function lib$rsvp$$internal$$tryThen(then,value,fulfillmentHandler,rejectionHandler){try{then.call(value,fulfillmentHandler,rejectionHandler)}catch(e){return e}}function lib$rsvp$$internal$$handleForeignThenable(promise,thenable,then){lib$rsvp$config$$config.async(function(promise){var sealed=false;var error=lib$rsvp$$internal$$tryThen(then,thenable,function(value){if(sealed){return}sealed=true;if(thenable!==value){lib$rsvp$$internal$$resolve(promise,value)}else{lib$rsvp$$internal$$fulfill(promise,value)}},function(reason){if(sealed){return}sealed=true;lib$rsvp$$internal$$reject(promise,reason)},"Settle: "+(promise._label||" unknown promise"));if(!sealed&&error){sealed=true;lib$rsvp$$internal$$reject(promise,error)}},promise)}function lib$rsvp$$internal$$handleOwnThenable(promise,thenable){if(thenable._state===lib$rsvp$$internal$$FULFILLED){lib$rsvp$$internal$$fulfill(promise,thenable._result)}else if(thenable._state===lib$rsvp$$internal$$REJECTED){thenable._onError=null;lib$rsvp$$internal$$reject(promise,thenable._result)}else{lib$rsvp$$internal$$subscribe(thenable,undefined,function(value){if(thenable!==value){lib$rsvp$$internal$$resolve(promise,value)}else{lib$rsvp$$internal$$fulfill(promise,value)}},function(reason){lib$rsvp$$internal$$reject(promise,reason)})}}function lib$rsvp$$internal$$handleMaybeThenable(promise,maybeThenable){if(maybeThenable.constructor===promise.constructor){lib$rsvp$$internal$$handleOwnThenable(promise,maybeThenable)}else{var then=lib$rsvp$$internal$$getThen(maybeThenable);if(then===lib$rsvp$$internal$$GET_THEN_ERROR){lib$rsvp$$internal$$reject(promise,lib$rsvp$$internal$$GET_THEN_ERROR.error)}else if(then===undefined){lib$rsvp$$internal$$fulfill(promise,maybeThenable)}else if(lib$rsvp$utils$$isFunction(then)){lib$rsvp$$internal$$handleForeignThenable(promise,maybeThenable,then)}else{lib$rsvp$$internal$$fulfill(promise,maybeThenable)}}}function lib$rsvp$$internal$$resolve(promise,value){if(promise===value){lib$rsvp$$internal$$fulfill(promise,value)}else if(lib$rsvp$utils$$objectOrFunction(value)){lib$rsvp$$internal$$handleMaybeThenable(promise,value)}else{lib$rsvp$$internal$$fulfill(promise,value)}}function lib$rsvp$$internal$$publishRejection(promise){if(promise._onError){promise._onError(promise._result)}lib$rsvp$$internal$$publish(promise)}function lib$rsvp$$internal$$fulfill(promise,value){if(promise._state!==lib$rsvp$$internal$$PENDING){return}promise._result=value;promise._state=lib$rsvp$$internal$$FULFILLED;if(promise._subscribers.length===0){if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("fulfilled",promise)}}else{lib$rsvp$config$$config.async(lib$rsvp$$internal$$publish,promise)}}function lib$rsvp$$internal$$reject(promise,reason){if(promise._state!==lib$rsvp$$internal$$PENDING){return}promise._state=lib$rsvp$$internal$$REJECTED;promise._result=reason;lib$rsvp$config$$config.async(lib$rsvp$$internal$$publishRejection,promise)}function lib$rsvp$$internal$$subscribe(parent,child,onFulfillment,onRejection){var subscribers=parent._subscribers;var length=subscribers.length;parent._onError=null;subscribers[length]=child;subscribers[length+lib$rsvp$$internal$$FULFILLED]=onFulfillment;subscribers[length+lib$rsvp$$internal$$REJECTED]=onRejection;if(length===0&&parent._state){lib$rsvp$config$$config.async(lib$rsvp$$internal$$publish,parent)}}function lib$rsvp$$internal$$publish(promise){var subscribers=promise._subscribers;var settled=promise._state;if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default(settled===lib$rsvp$$internal$$FULFILLED?"fulfilled":"rejected",promise)}if(subscribers.length===0){return}var child,callback,detail=promise._result;for(var i=0;i<subscribers.length;i+=3){child=subscribers[i];callback=subscribers[i+settled];if(child){lib$rsvp$$internal$$invokeCallback(settled,child,callback,detail)}else{callback(detail)}}promise._subscribers.length=0}function lib$rsvp$$internal$$ErrorObject(){this.error=null}var lib$rsvp$$internal$$TRY_CATCH_ERROR=new lib$rsvp$$internal$$ErrorObject;function lib$rsvp$$internal$$tryCatch(callback,detail){try{return callback(detail)}catch(e){lib$rsvp$$internal$$TRY_CATCH_ERROR.error=e;return lib$rsvp$$internal$$TRY_CATCH_ERROR}}function lib$rsvp$$internal$$invokeCallback(settled,promise,callback,detail){var hasCallback=lib$rsvp$utils$$isFunction(callback),value,error,succeeded,failed;if(hasCallback){value=lib$rsvp$$internal$$tryCatch(callback,detail);if(value===lib$rsvp$$internal$$TRY_CATCH_ERROR){failed=true;error=value.error;value=null}else{succeeded=true}if(promise===value){lib$rsvp$$internal$$reject(promise,lib$rsvp$$internal$$withOwnPromise());return}}else{value=detail;succeeded=true}if(promise._state!==lib$rsvp$$internal$$PENDING){}else if(hasCallback&&succeeded){lib$rsvp$$internal$$resolve(promise,value)}else if(failed){lib$rsvp$$internal$$reject(promise,error)}else if(settled===lib$rsvp$$internal$$FULFILLED){lib$rsvp$$internal$$fulfill(promise,value)}else if(settled===lib$rsvp$$internal$$REJECTED){lib$rsvp$$internal$$reject(promise,value)}}function lib$rsvp$$internal$$initializePromise(promise,resolver){var resolved=false;try{resolver(function resolvePromise(value){if(resolved){return}resolved=true;lib$rsvp$$internal$$resolve(promise,value)},function rejectPromise(reason){if(resolved){return}resolved=true;lib$rsvp$$internal$$reject(promise,reason)})}catch(e){lib$rsvp$$internal$$reject(promise,e)}}function lib$rsvp$enumerator$$makeSettledResult(state,position,value){if(state===lib$rsvp$$internal$$FULFILLED){return{state:"fulfilled",value:value}}else{return{state:"rejected",reason:value}}}function lib$rsvp$enumerator$$Enumerator(Constructor,input,abortOnReject,label){this._instanceConstructor=Constructor;this.promise=new Constructor(lib$rsvp$$internal$$noop,label);this._abortOnReject=abortOnReject;if(this._validateInput(input)){this._input=input;this.length=input.length;this._remaining=input.length;this._init();if(this.length===0){lib$rsvp$$internal$$fulfill(this.promise,this._result)}else{this.length=this.length||0;this._enumerate();if(this._remaining===0){lib$rsvp$$internal$$fulfill(this.promise,this._result)}}}else{lib$rsvp$$internal$$reject(this.promise,this._validationError())}}var lib$rsvp$enumerator$$default=lib$rsvp$enumerator$$Enumerator;lib$rsvp$enumerator$$Enumerator.prototype._validateInput=function(input){return lib$rsvp$utils$$isArray(input)};lib$rsvp$enumerator$$Enumerator.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")};lib$rsvp$enumerator$$Enumerator.prototype._init=function(){this._result=new Array(this.length)};lib$rsvp$enumerator$$Enumerator.prototype._enumerate=function(){var length=this.length;var promise=this.promise;var input=this._input;for(var i=0;promise._state===lib$rsvp$$internal$$PENDING&&i<length;i++){this._eachEntry(input[i],i)}};lib$rsvp$enumerator$$Enumerator.prototype._eachEntry=function(entry,i){var c=this._instanceConstructor;if(lib$rsvp$utils$$isMaybeThenable(entry)){if(entry.constructor===c&&entry._state!==lib$rsvp$$internal$$PENDING){entry._onError=null;this._settledAt(entry._state,i,entry._result)}else{this._willSettleAt(c.resolve(entry),i)}}else{this._remaining--;this._result[i]=this._makeResult(lib$rsvp$$internal$$FULFILLED,i,entry)}};lib$rsvp$enumerator$$Enumerator.prototype._settledAt=function(state,i,value){var promise=this.promise;if(promise._state===lib$rsvp$$internal$$PENDING){this._remaining--;if(this._abortOnReject&&state===lib$rsvp$$internal$$REJECTED){lib$rsvp$$internal$$reject(promise,value)}else{this._result[i]=this._makeResult(state,i,value)}}if(this._remaining===0){lib$rsvp$$internal$$fulfill(promise,this._result)}};lib$rsvp$enumerator$$Enumerator.prototype._makeResult=function(state,i,value){return value};lib$rsvp$enumerator$$Enumerator.prototype._willSettleAt=function(promise,i){var enumerator=this;lib$rsvp$$internal$$subscribe(promise,undefined,function(value){enumerator._settledAt(lib$rsvp$$internal$$FULFILLED,i,value)},function(reason){enumerator._settledAt(lib$rsvp$$internal$$REJECTED,i,reason)})};function lib$rsvp$promise$all$$all(entries,label){return new lib$rsvp$enumerator$$default(this,entries,true,label).promise}var lib$rsvp$promise$all$$default=lib$rsvp$promise$all$$all;function lib$rsvp$promise$race$$race(entries,label){var Constructor=this;var promise=new Constructor(lib$rsvp$$internal$$noop,label);if(!lib$rsvp$utils$$isArray(entries)){lib$rsvp$$internal$$reject(promise,new TypeError("You must pass an array to race."));return promise}var length=entries.length;function onFulfillment(value){lib$rsvp$$internal$$resolve(promise,value)}function onRejection(reason){lib$rsvp$$internal$$reject(promise,reason)}for(var i=0;promise._state===lib$rsvp$$internal$$PENDING&&i<length;i++){lib$rsvp$$internal$$subscribe(Constructor.resolve(entries[i]),undefined,onFulfillment,onRejection)}return promise}var lib$rsvp$promise$race$$default=lib$rsvp$promise$race$$race;function lib$rsvp$promise$resolve$$resolve(object,label){var Constructor=this;if(object&&typeof object==="object"&&object.constructor===Constructor){return object}var promise=new Constructor(lib$rsvp$$internal$$noop,label);lib$rsvp$$internal$$resolve(promise,object);return promise}var lib$rsvp$promise$resolve$$default=lib$rsvp$promise$resolve$$resolve;function lib$rsvp$promise$reject$$reject(reason,label){var Constructor=this;var promise=new Constructor(lib$rsvp$$internal$$noop,label);lib$rsvp$$internal$$reject(promise,reason);return promise}var lib$rsvp$promise$reject$$default=lib$rsvp$promise$reject$$reject;var lib$rsvp$promise$$guidKey="rsvp_"+lib$rsvp$utils$$now()+"-";var lib$rsvp$promise$$counter=0;function lib$rsvp$promise$$needsResolver(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function lib$rsvp$promise$$needsNew(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function lib$rsvp$promise$$Promise(resolver,label){this._id=lib$rsvp$promise$$counter++;this._label=label;this._state=undefined;this._result=undefined;this._subscribers=[];if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("created",this)}if(lib$rsvp$$internal$$noop!==resolver){if(!lib$rsvp$utils$$isFunction(resolver)){lib$rsvp$promise$$needsResolver()}if(!(this instanceof lib$rsvp$promise$$Promise)){lib$rsvp$promise$$needsNew()}lib$rsvp$$internal$$initializePromise(this,resolver)}}var lib$rsvp$promise$$default=lib$rsvp$promise$$Promise;lib$rsvp$promise$$Promise.cast=lib$rsvp$promise$resolve$$default;lib$rsvp$promise$$Promise.all=lib$rsvp$promise$all$$default;lib$rsvp$promise$$Promise.race=lib$rsvp$promise$race$$default;lib$rsvp$promise$$Promise.resolve=lib$rsvp$promise$resolve$$default;lib$rsvp$promise$$Promise.reject=lib$rsvp$promise$reject$$default;lib$rsvp$promise$$Promise.prototype={constructor:lib$rsvp$promise$$Promise,_guidKey:lib$rsvp$promise$$guidKey,_onError:function(reason){lib$rsvp$config$$config.async(function(promise){setTimeout(function(){if(promise._onError){lib$rsvp$config$$config["trigger"]("error",reason)}},0)},this)},then:function(onFulfillment,onRejection,label){var parent=this;var state=parent._state;if(state===lib$rsvp$$internal$$FULFILLED&&!onFulfillment||state===lib$rsvp$$internal$$REJECTED&&!onRejection){if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("chained",this,this)}return this}parent._onError=null;var child=new this.constructor(lib$rsvp$$internal$$noop,label);var result=parent._result;if(lib$rsvp$config$$config.instrument){lib$rsvp$instrument$$default("chained",parent,child)}if(state){var callback=arguments[state-1];lib$rsvp$config$$config.async(function(){lib$rsvp$$internal$$invokeCallback(state,child,callback,result)})}else{lib$rsvp$$internal$$subscribe(parent,child,onFulfillment,onRejection)}return child},"catch":function(onRejection,label){return this.then(null,onRejection,label)},"finally":function(callback,label){var constructor=this.constructor;return this.then(function(value){return constructor.resolve(callback()).then(function(){return value})},function(reason){return constructor.resolve(callback()).then(function(){throw reason})},label)}};function lib$rsvp$all$settled$$AllSettled(Constructor,entries,label){this._superConstructor(Constructor,entries,false,label)}lib$rsvp$all$settled$$AllSettled.prototype=lib$rsvp$utils$$o_create(lib$rsvp$enumerator$$default.prototype);lib$rsvp$all$settled$$AllSettled.prototype._superConstructor=lib$rsvp$enumerator$$default;lib$rsvp$all$settled$$AllSettled.prototype._makeResult=lib$rsvp$enumerator$$makeSettledResult;lib$rsvp$all$settled$$AllSettled.prototype._validationError=function(){return new Error("allSettled must be called with an array")};function lib$rsvp$all$settled$$allSettled(entries,label){return new lib$rsvp$all$settled$$AllSettled(lib$rsvp$promise$$default,entries,label).promise}var lib$rsvp$all$settled$$default=lib$rsvp$all$settled$$allSettled;function lib$rsvp$all$$all(array,label){return lib$rsvp$promise$$default.all(array,label)}var lib$rsvp$all$$default=lib$rsvp$all$$all;var lib$rsvp$asap$$len=0;var lib$rsvp$asap$$toString={}.toString;var lib$rsvp$asap$$vertxNext;function lib$rsvp$asap$$asap(callback,arg){lib$rsvp$asap$$queue[lib$rsvp$asap$$len]=callback;lib$rsvp$asap$$queue[lib$rsvp$asap$$len+1]=arg;lib$rsvp$asap$$len+=2;if(lib$rsvp$asap$$len===2){lib$rsvp$asap$$scheduleFlush()}}var lib$rsvp$asap$$default=lib$rsvp$asap$$asap;var lib$rsvp$asap$$browserWindow=typeof window!=="undefined"?window:undefined;var lib$rsvp$asap$$browserGlobal=lib$rsvp$asap$$browserWindow||{};var lib$rsvp$asap$$BrowserMutationObserver=lib$rsvp$asap$$browserGlobal.MutationObserver||lib$rsvp$asap$$browserGlobal.WebKitMutationObserver;var lib$rsvp$asap$$isNode=typeof process!=="undefined"&&{}.toString.call(process)==="[object process]";var lib$rsvp$asap$$isWorker=typeof Uint8ClampedArray!=="undefined"&&typeof importScripts!=="undefined"&&typeof MessageChannel!=="undefined";function lib$rsvp$asap$$useNextTick(){var nextTick=process.nextTick;var version=process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);if(Array.isArray(version)&&version[1]==="0"&&version[2]==="10"){nextTick=setImmediate}return function(){nextTick(lib$rsvp$asap$$flush)}}function lib$rsvp$asap$$useVertxTimer(){return function(){lib$rsvp$asap$$vertxNext(lib$rsvp$asap$$flush)}}function lib$rsvp$asap$$useMutationObserver(){var iterations=0;var observer=new lib$rsvp$asap$$BrowserMutationObserver(lib$rsvp$asap$$flush);var node=document.createTextNode("");observer.observe(node,{characterData:true});return function(){node.data=iterations=++iterations%2}}function lib$rsvp$asap$$useMessageChannel(){var channel=new MessageChannel;channel.port1.onmessage=lib$rsvp$asap$$flush;return function(){channel.port2.postMessage(0)}}function lib$rsvp$asap$$useSetTimeout(){return function(){setTimeout(lib$rsvp$asap$$flush,1)}}var lib$rsvp$asap$$queue=new Array(1e3);function lib$rsvp$asap$$flush(){for(var i=0;i<lib$rsvp$asap$$len;i+=2){var callback=lib$rsvp$asap$$queue[i];var arg=lib$rsvp$asap$$queue[i+1];callback(arg);lib$rsvp$asap$$queue[i]=undefined;lib$rsvp$asap$$queue[i+1]=undefined}lib$rsvp$asap$$len=0}function lib$rsvp$asap$$attemptVertex(){try{var r=require;var vertx=r("vertx");lib$rsvp$asap$$vertxNext=vertx.runOnLoop||vertx.runOnContext;return lib$rsvp$asap$$useVertxTimer()}catch(e){return lib$rsvp$asap$$useSetTimeout()}}var lib$rsvp$asap$$scheduleFlush;if(lib$rsvp$asap$$isNode){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useNextTick()}else if(lib$rsvp$asap$$BrowserMutationObserver){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useMutationObserver()}else if(lib$rsvp$asap$$isWorker){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useMessageChannel()}else if(lib$rsvp$asap$$browserWindow===undefined&&typeof require==="function"){lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$attemptVertex()}else{lib$rsvp$asap$$scheduleFlush=lib$rsvp$asap$$useSetTimeout()}function lib$rsvp$defer$$defer(label){var deferred={};deferred["promise"]=new lib$rsvp$promise$$default(function(resolve,reject){deferred["resolve"]=resolve;deferred["reject"]=reject},label);return deferred}var lib$rsvp$defer$$default=lib$rsvp$defer$$defer;function lib$rsvp$filter$$filter(promises,filterFn,label){return lib$rsvp$promise$$default.all(promises,label).then(function(values){if(!lib$rsvp$utils$$isFunction(filterFn)){throw new TypeError("You must pass a function as filter's second argument.")}var length=values.length;var filtered=new Array(length);for(var i=0;i<length;i++){filtered[i]=filterFn(values[i])}return lib$rsvp$promise$$default.all(filtered,label).then(function(filtered){var results=new Array(length);var newLength=0;for(var i=0;i<length;i++){if(filtered[i]){results[newLength]=values[i];newLength++}}results.length=newLength;return results})})}var lib$rsvp$filter$$default=lib$rsvp$filter$$filter;function lib$rsvp$promise$hash$$PromiseHash(Constructor,object,label){this._superConstructor(Constructor,object,true,label)}var lib$rsvp$promise$hash$$default=lib$rsvp$promise$hash$$PromiseHash;lib$rsvp$promise$hash$$PromiseHash.prototype=lib$rsvp$utils$$o_create(lib$rsvp$enumerator$$default.prototype);lib$rsvp$promise$hash$$PromiseHash.prototype._superConstructor=lib$rsvp$enumerator$$default;lib$rsvp$promise$hash$$PromiseHash.prototype._init=function(){this._result={}};lib$rsvp$promise$hash$$PromiseHash.prototype._validateInput=function(input){return input&&typeof input==="object"};lib$rsvp$promise$hash$$PromiseHash.prototype._validationError=function(){return new Error("Promise.hash must be called with an object")};lib$rsvp$promise$hash$$PromiseHash.prototype._enumerate=function(){var promise=this.promise;var input=this._input;var results=[];for(var key in input){if(promise._state===lib$rsvp$$internal$$PENDING&&input.hasOwnProperty(key)){results.push({position:key,entry:input[key]})}}var length=results.length;this._remaining=length;var result;for(var i=0;promise._state===lib$rsvp$$internal$$PENDING&&i<length;i++){result=results[i];this._eachEntry(result.entry,result.position)}};function lib$rsvp$hash$settled$$HashSettled(Constructor,object,label){this._superConstructor(Constructor,object,false,label)}lib$rsvp$hash$settled$$HashSettled.prototype=lib$rsvp$utils$$o_create(lib$rsvp$promise$hash$$default.prototype);lib$rsvp$hash$settled$$HashSettled.prototype._superConstructor=lib$rsvp$enumerator$$default;lib$rsvp$hash$settled$$HashSettled.prototype._makeResult=lib$rsvp$enumerator$$makeSettledResult;lib$rsvp$hash$settled$$HashSettled.prototype._validationError=function(){return new Error("hashSettled must be called with an object")};function lib$rsvp$hash$settled$$hashSettled(object,label){return new lib$rsvp$hash$settled$$HashSettled(lib$rsvp$promise$$default,object,label).promise}var lib$rsvp$hash$settled$$default=lib$rsvp$hash$settled$$hashSettled;function lib$rsvp$hash$$hash(object,label){return new lib$rsvp$promise$hash$$default(lib$rsvp$promise$$default,object,label).promise}var lib$rsvp$hash$$default=lib$rsvp$hash$$hash;function lib$rsvp$map$$map(promises,mapFn,label){return lib$rsvp$promise$$default.all(promises,label).then(function(values){if(!lib$rsvp$utils$$isFunction(mapFn)){throw new TypeError("You must pass a function as map's second argument.")}var length=values.length;var results=new Array(length);for(var i=0;i<length;i++){results[i]=mapFn(values[i])}return lib$rsvp$promise$$default.all(results,label)})}var lib$rsvp$map$$default=lib$rsvp$map$$map;function lib$rsvp$node$$Result(){this.value=undefined}var lib$rsvp$node$$ERROR=new lib$rsvp$node$$Result;var lib$rsvp$node$$GET_THEN_ERROR=new lib$rsvp$node$$Result;function lib$rsvp$node$$getThen(obj){try{return obj.then}catch(error){lib$rsvp$node$$ERROR.value=error;return lib$rsvp$node$$ERROR}}function lib$rsvp$node$$tryApply(f,s,a){try{f.apply(s,a)}catch(error){lib$rsvp$node$$ERROR.value=error;return lib$rsvp$node$$ERROR}}function lib$rsvp$node$$makeObject(_,argumentNames){var obj={};var name;var i;var length=_.length;var args=new Array(length);for(var x=0;x<length;x++){args[x]=_[x]}for(i=0;i<argumentNames.length;i++){name=argumentNames[i];obj[name]=args[i+1]}return obj}function lib$rsvp$node$$arrayResult(_){var length=_.length;var args=new Array(length-1);for(var i=1;i<length;i++){args[i-1]=_[i]}return args}function lib$rsvp$node$$wrapThenable(then,promise){return{then:function(onFulFillment,onRejection){return then.call(promise,onFulFillment,onRejection)}}}function lib$rsvp$node$$denodeify(nodeFunc,options){var fn=function(){var self=this;var l=arguments.length;var args=new Array(l+1);var arg;var promiseInput=false;for(var i=0;i<l;++i){arg=arguments[i];if(!promiseInput){promiseInput=lib$rsvp$node$$needsPromiseInput(arg);if(promiseInput===lib$rsvp$node$$GET_THEN_ERROR){var p=new lib$rsvp$promise$$default(lib$rsvp$$internal$$noop);lib$rsvp$$internal$$reject(p,lib$rsvp$node$$GET_THEN_ERROR.value);return p}else if(promiseInput&&promiseInput!==true){arg=lib$rsvp$node$$wrapThenable(promiseInput,arg)}}args[i]=arg}var promise=new lib$rsvp$promise$$default(lib$rsvp$$internal$$noop);args[l]=function(err,val){if(err)lib$rsvp$$internal$$reject(promise,err);else if(options===undefined)lib$rsvp$$internal$$resolve(promise,val);else if(options===true)lib$rsvp$$internal$$resolve(promise,lib$rsvp$node$$arrayResult(arguments));else if(lib$rsvp$utils$$isArray(options))lib$rsvp$$internal$$resolve(promise,lib$rsvp$node$$makeObject(arguments,options));else lib$rsvp$$internal$$resolve(promise,val)};if(promiseInput){return lib$rsvp$node$$handlePromiseInput(promise,args,nodeFunc,self)}else{return lib$rsvp$node$$handleValueInput(promise,args,nodeFunc,self)}};fn.__proto__=nodeFunc;return fn}var lib$rsvp$node$$default=lib$rsvp$node$$denodeify;function lib$rsvp$node$$handleValueInput(promise,args,nodeFunc,self){var result=lib$rsvp$node$$tryApply(nodeFunc,self,args);if(result===lib$rsvp$node$$ERROR){lib$rsvp$$internal$$reject(promise,result.value)}return promise}function lib$rsvp$node$$handlePromiseInput(promise,args,nodeFunc,self){return lib$rsvp$promise$$default.all(args).then(function(args){var result=lib$rsvp$node$$tryApply(nodeFunc,self,args);if(result===lib$rsvp$node$$ERROR){lib$rsvp$$internal$$reject(promise,result.value)}return promise})}function lib$rsvp$node$$needsPromiseInput(arg){if(arg&&typeof arg==="object"){if(arg.constructor===lib$rsvp$promise$$default){return true}else{return lib$rsvp$node$$getThen(arg)}}else{return false}}function lib$rsvp$race$$race(array,label){return lib$rsvp$promise$$default.race(array,label)}var lib$rsvp$race$$default=lib$rsvp$race$$race;function lib$rsvp$reject$$reject(reason,label){return lib$rsvp$promise$$default.reject(reason,label)}var lib$rsvp$reject$$default=lib$rsvp$reject$$reject;function lib$rsvp$resolve$$resolve(value,label){return lib$rsvp$promise$$default.resolve(value,label)}var lib$rsvp$resolve$$default=lib$rsvp$resolve$$resolve;function lib$rsvp$rethrow$$rethrow(reason){setTimeout(function(){throw reason});throw reason}var lib$rsvp$rethrow$$default=lib$rsvp$rethrow$$rethrow;lib$rsvp$config$$config.async=lib$rsvp$asap$$default;var lib$rsvp$$cast=lib$rsvp$resolve$$default;function lib$rsvp$$async(callback,arg){lib$rsvp$config$$config.async(callback,arg)}function lib$rsvp$$on(){lib$rsvp$config$$config["on"].apply(lib$rsvp$config$$config,arguments)}function lib$rsvp$$off(){lib$rsvp$config$$config["off"].apply(lib$rsvp$config$$config,arguments)}if(typeof window!=="undefined"&&typeof window["__PROMISE_INSTRUMENTATION__"]==="object"){var lib$rsvp$$callbacks=window["__PROMISE_INSTRUMENTATION__"];lib$rsvp$config$$configure("instrument",true);for(var lib$rsvp$$eventName in lib$rsvp$$callbacks){if(lib$rsvp$$callbacks.hasOwnProperty(lib$rsvp$$eventName)){lib$rsvp$$on(lib$rsvp$$eventName,lib$rsvp$$callbacks[lib$rsvp$$eventName])}}}var lib$rsvp$umd$$RSVP={race:lib$rsvp$race$$default,Promise:lib$rsvp$promise$$default,allSettled:lib$rsvp$all$settled$$default,hash:lib$rsvp$hash$$default,hashSettled:lib$rsvp$hash$settled$$default,denodeify:lib$rsvp$node$$default,on:lib$rsvp$$on,off:lib$rsvp$$off,map:lib$rsvp$map$$default,filter:lib$rsvp$filter$$default,resolve:lib$rsvp$resolve$$default,reject:lib$rsvp$reject$$default,all:lib$rsvp$all$$default,rethrow:lib$rsvp$rethrow$$default,defer:lib$rsvp$defer$$default,EventTarget:lib$rsvp$events$$default,configure:lib$rsvp$config$$configure,async:lib$rsvp$$async};if(typeof define==="function"&&define["amd"]){define(function(){return lib$rsvp$umd$$RSVP})}else if(typeof module!=="undefined"&&module["exports"]){module["exports"]=lib$rsvp$umd$$RSVP}else if(typeof this!=="undefined"){this["RSVP"]=lib$rsvp$umd$$RSVP}}).call(this);
8
+ /*
9
+ * Intended for use with the Stratosphere Ruby Gem
10
+ * Copyright (c) 2015 Zachary Golba (zak@zacharygolba.com)
11
+ *
12
+ * Permission is hereby granted, free of charge, to any person obtaining
13
+ * a copy of this software and associated documentation files (the
14
+ * "Software"), to deal in the Software without restriction, including
15
+ * without limitation the rights to use, copy, modify, merge, publish,
16
+ * distribute, sublicense, and/or sell copies of the Software, and to
17
+ * permit persons to whom the Software is furnished to do so, subject to
18
+ * the following conditions:
19
+ *
20
+ * The above copyright notice and this permission notice shall be
21
+ * included in all copies or substantial portions of the Software.
22
+ *
23
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
+ */
31
+ window.Stratosphere=function(){"use strict";function e(e,t,n){var a=document.querySelectorAll("meta[name=csrf-token]")[0];this.file=null,this.csrfToken=a?a.getAttribute("content"):"",this.modelId=t,this.modelName=e,this.attachmentName=n}return e.activate=function(){var t=jQuery('*[data-stratosphere-enabled="true"]');if(t.length>0){var n=new e(t.data("modelName"),t.data("modelId"),t.data("attachmentName")),a=t.find("input[type='file']"),o=function(e){if(e){var o=t.find(".upload-controls"),r=t.find(".upload-progress"),i=r.find(".progress-bar");o.css("display","none"),r.css("display","block"),n.upload(e,i[0]).then(function(e){var n=!!e&&e.hasOwnProperty("url")&&e.hasOwnProperty("name")&&e.hasOwnProperty("type");n&&(t.find(".current-attachment a").html(e.name),t.find(".current-attachment a").attr("href",e.url),/^image\/.+/g.test(e.type)&&t.find(".current-attachment img").attr("src",e.url)),o.css("display",""),r.css("display","none"),t.find(".current-attachment").css("display","inline-block"),t.find('*[data-stratosphere-action="delete"]').css("display",""),a.val(""),setTimeout(function(){i[0].setAttribute("aria-valuenow","0"),i[0].style.width=0},500)},function(e){console.log(e)})}else n.file=null};t.find("button").on("click",function(e){var o=jQuery(e.target);e.preventDefault(),"upload"===o.data("stratosphereAction")&&a.trigger("click"),"delete"===o.data("stratosphereAction")&&window.confirm("Are you sure you want to delete this attachment?")&&n.deleteAttachment().then(function(){t.find(".current-attachment").css("display","none"),t.find('*[data-stratosphere-action="delete"]').css("display","none")})}),a.on("change",function(){o(a[0].files[0])})}},e.deactivate=function(){var e=jQuery('*[data-stratosphere-enabled="true"]');e.length>0&&(e.find("input[type='file']").off("change"),e.find("button").off("click"))},e.prototype.getUploadUrl=function(){var e=this;return new RSVP.Promise(function(t,n){e.file?jQuery.ajax({type:"GET",url:"/"+e.modelName.pluralize()+"/"+e.modelId+"/edit",data:{file_name:e.file.name,content_type:e.file.type,content_length:e.file.size,stratosphere_submitted:!0},headers:{"X-CSRF-Token":e.csrfToken}}).done(function(e,a,o){o.status>=200&&o.status<400?e.hasOwnProperty("url")?t(e.url):n(null):n(o)}):n(null)})},e.prototype.upload=function(e,t){var n=this;return null===t&&(t=null),this.file=e,new RSVP.Promise(function(a,o){n.getUploadUrl().then(function(r){var i=new XMLHttpRequest;if(i.open("PUT",r,!0),i.setRequestHeader("Accept","*/*"),i.setRequestHeader("Content-Type",e.type),i.onload=function(){i.status>=200&&i.status<400?n.updateModel().then(function(e){e?a({url:r.split("?")[0],name:n.file.name,type:n.file.type}):o(null)},function(){o(null)}):o(null)},t&&i.upload){var l=jQuery(i.upload);l.on("progress",function(e){if(e.originalEvent.lengthComputable){var n=e.originalEvent.loaded/e.originalEvent.total*100;t.setAttribute("aria-valuenow",""+n),t.style.width=n+"%"}}),l.on("load",function(){l.off("progress"),l.off("load")})}i.send(e)},function(){o(null)})})},e.prototype.updateModel=function(){var e=this;return new RSVP.Promise(function(t,n){if(e.file){var a={stratosphere_submitted:!0};a[e.attachmentName+"_file"]=e.file.name,a[e.attachmentName+"_content_type"]=e.file.type,a[e.attachmentName+"_content_length"]=e.file.size,jQuery.ajax({type:"PATCH",url:"/"+e.modelName.pluralize()+"/"+e.modelId,data:a,headers:{"X-CSRF-Token":e.csrfToken,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}}).done(function(e,a,o){o.status>=200&&o.status<400?t(!0):n(o)})}else n(!1)})},e.prototype.deleteAttachment=function(){var e=this;return new RSVP.Promise(function(t,n){var a={stratosphere_submitted:!0};a[e.attachmentName+"_file"]=null,a[e.attachmentName+"_content_type"]=null,a[e.attachmentName+"_content_length"]=null,jQuery.ajax({type:"PATCH",url:"/"+e.modelName.pluralize()+"/"+e.modelId,data:a,headers:{"X-CSRF-Token":e.csrfToken,"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}}).done(function(e,a,o){200===o.status?t(!0):n(o)})})},e}(),window.jQuery?window.Turbolinks?(jQuery(document).on("page:change",function(){Stratosphere.activate()}),jQuery(document).on("page:before-unload",function(){Stratosphere.deactivate()})):jQuery(document).ready(function(){Stratosphere.activate()}):console.error("jQuery not detected. Make sure you include stratosphere/main after jquery.");
@@ -0,0 +1,297 @@
1
+ /*
2
+ * Intended for use with the Stratosphere Ruby Gem
3
+ * Copyright (c) 2015 Zachary Golba (zak@zacharygolba.com)
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+ window.Stratosphere = function() {
26
+ 'use strict';
27
+
28
+ function Stratosphere(modelName, modelId, attachmentName) {
29
+ var csrfMeta = document.querySelectorAll('meta[name=csrf-token]')[0];
30
+ this.file = null;
31
+ this.csrfToken = !!csrfMeta ? csrfMeta.getAttribute('content') : '';
32
+ this.modelId = modelId;
33
+ this.modelName = modelName;
34
+ this.attachmentName = attachmentName;
35
+ }
36
+
37
+ Stratosphere.activate = function() {
38
+ var $uploadContainer = jQuery('*[data-stratosphere-enabled="true"]');
39
+
40
+ if ( $uploadContainer.length > 0 ) {
41
+ var stratosphere = new Stratosphere( $uploadContainer.data('modelName'), $uploadContainer.data('modelId'), $uploadContainer.data('attachmentName') );
42
+ var $fileInput = $uploadContainer.find("input[type='file']");
43
+
44
+ var uploadFile = function(file) {
45
+ if ( !!file ) {
46
+ var $uploadControls = $uploadContainer.find('.upload-controls');
47
+ var $uploadProgress = $uploadContainer.find('.upload-progress');
48
+ var $progressBar = $uploadProgress.find('.progress-bar');
49
+
50
+ $uploadControls.css('display', 'none');
51
+ $uploadProgress.css('display', 'block');
52
+
53
+ stratosphere.upload(file, $progressBar[0]).then(function (attachment) {
54
+ var successful = !!attachment && attachment.hasOwnProperty('url') && attachment.hasOwnProperty('name') && attachment.hasOwnProperty('type');
55
+
56
+ if ( successful ) {
57
+ $uploadContainer.find('.current-attachment a').html(attachment.name);
58
+ $uploadContainer.find('.current-attachment a').attr('href', attachment.url);
59
+ if ( /^image\/.+/g.test(attachment.type) ) {
60
+ $uploadContainer.find('.current-attachment img').attr('src', attachment.url);
61
+ }
62
+ }
63
+
64
+ $uploadControls.css('display', '');
65
+ $uploadProgress.css('display', 'none');
66
+ $uploadContainer.find('.current-attachment').css('display', 'inline-block');
67
+ $uploadContainer.find('*[data-stratosphere-action="delete"]').css('display', '');
68
+
69
+ $fileInput.val('');
70
+
71
+ setTimeout(function () {
72
+ $progressBar[0].setAttribute('aria-valuenow', '0');
73
+ $progressBar[0].style.width = 0;
74
+ }, 500);
75
+
76
+ }, function (error) {
77
+ console.log(error);
78
+ });
79
+
80
+ } else {
81
+ stratosphere.file = null;
82
+ }
83
+ };
84
+
85
+ $uploadContainer.find('button').on('click', function (e) {
86
+ var $target = jQuery(e.target);
87
+
88
+ e.preventDefault();
89
+
90
+ if ( $target.data('stratosphereAction') === 'upload' ) {
91
+ $fileInput.trigger('click');
92
+ }
93
+
94
+ if ( $target.data('stratosphereAction') === 'delete' ) {
95
+ if ( window.confirm('Are you sure you want to delete this attachment?') ) {
96
+
97
+ stratosphere.deleteAttachment().then(function () {
98
+ $uploadContainer.find('.current-attachment').css('display', 'none');
99
+ $uploadContainer.find('*[data-stratosphere-action="delete"]').css('display', 'none');
100
+ });
101
+
102
+ }
103
+ }
104
+ });
105
+
106
+ $fileInput.on('change', function () {
107
+ uploadFile($fileInput[0].files[0]);
108
+ });
109
+ }
110
+ };
111
+
112
+ Stratosphere.deactivate = function() {
113
+ var $uploadContainer = jQuery('*[data-stratosphere-enabled="true"]');
114
+
115
+ if ($uploadContainer.length > 0) {
116
+ $uploadContainer.find("input[type='file']").off('change');
117
+ $uploadContainer.find('button').off('click');
118
+ }
119
+ };
120
+
121
+ Stratosphere.prototype.getUploadUrl = function() {
122
+ var self = this;
123
+
124
+ return new RSVP.Promise(function(resolve, reject) {
125
+ if ( !!self.file ) {
126
+ jQuery.ajax({
127
+ type: 'GET',
128
+ url: '/' + self.modelName.pluralize() + '/' + self.modelId + '/edit',
129
+ data: {
130
+ 'file_name': self.file.name,
131
+ 'content_type': self.file.type,
132
+ 'content_length': self.file.size,
133
+ 'stratosphere_submitted': true
134
+ },
135
+ headers: {
136
+ 'X-CSRF-Token': self.csrfToken
137
+ }
138
+ }).done(function ( data, textStatus, jqXHR ) {
139
+ if ( jqXHR.status >= 200 && jqXHR.status < 400 ) {
140
+ if ( data.hasOwnProperty('url') ) {
141
+ resolve(data.url);
142
+ } else {
143
+ reject(null);
144
+ }
145
+ } else {
146
+ reject(jqXHR);
147
+ }
148
+ });
149
+ } else {
150
+ reject(null);
151
+ }
152
+ });
153
+ };
154
+
155
+ Stratosphere.prototype.upload = function(file, progressBar) {
156
+ var self = this;
157
+
158
+ if ( progressBar === null ) {
159
+ progressBar = null;
160
+ }
161
+
162
+ this.file = file;
163
+
164
+ return new RSVP.Promise(function (resolve, reject) {
165
+ self.getUploadUrl().then(function (url) {
166
+ var xhr = new XMLHttpRequest();
167
+
168
+ xhr.open('PUT', url, true);
169
+
170
+ xhr.setRequestHeader('Accept', '*/*');
171
+ xhr.setRequestHeader('Content-Type', file.type);
172
+
173
+ xhr.onload = function() {
174
+ if ( xhr.status >= 200 && xhr.status < 400 ) {
175
+ self.updateModel().then(function (didUpdate) {
176
+ if ( didUpdate ) {
177
+ resolve( { url: url.split('?')[0], name: self.file.name, type: self.file.type } );
178
+ } else {
179
+ reject(null);
180
+ }
181
+ }, function () {
182
+ reject(null);
183
+ });
184
+ } else {
185
+ reject(null);
186
+ }
187
+ };
188
+
189
+ if ( !!progressBar && xhr.upload ) {
190
+ var $upload = jQuery(xhr.upload);
191
+
192
+ $upload.on('progress', function (e) {
193
+ if ( e.originalEvent.lengthComputable ) {
194
+ var p = e.originalEvent.loaded / e.originalEvent.total * 100;
195
+ progressBar.setAttribute('aria-valuenow', '' + p);
196
+ progressBar.style.width = p + '%';
197
+ }
198
+ });
199
+
200
+ $upload.on('load', function () {
201
+ $upload.off('progress');
202
+ $upload.off('load');
203
+ });
204
+ }
205
+
206
+ xhr.send(file);
207
+ }, function () {
208
+ reject(null);
209
+ });
210
+ });
211
+
212
+ };
213
+
214
+ Stratosphere.prototype.updateModel = function() {
215
+ var self = this;
216
+
217
+ return new RSVP.Promise(function (resolve, reject) {
218
+ if ( !!self.file ) {
219
+ var params = {
220
+ 'stratosphere_submitted': true
221
+ };
222
+
223
+ params[ self.attachmentName + '_file' ] = self.file.name;
224
+ params[ self.attachmentName + '_content_type' ] = self.file.type;
225
+ params[ self.attachmentName + '_content_length' ] = self.file.size;
226
+
227
+ jQuery.ajax({
228
+ type: 'PATCH',
229
+ url: '/' + self.modelName.pluralize() + '/' + self.modelId,
230
+ data: params,
231
+ headers: {
232
+ 'X-CSRF-Token': self.csrfToken,
233
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
234
+ }
235
+ }).done(function ( data, textStatus, jqXHR ) {
236
+ if ( jqXHR.status >= 200 && jqXHR.status < 400 ) {
237
+ resolve(true);
238
+ } else {
239
+ reject(jqXHR);
240
+ }
241
+ });
242
+ } else {
243
+ reject( false );
244
+ }
245
+ });
246
+ };
247
+
248
+ Stratosphere.prototype.deleteAttachment = function() {
249
+ var self = this;
250
+
251
+ return new RSVP.Promise(function (resolve, reject) {
252
+ var params = {
253
+ 'stratosphere_submitted': true
254
+ };
255
+
256
+ params[ self.attachmentName + '_file' ] = null;
257
+ params[ self.attachmentName + '_content_type' ] = null;
258
+ params[ self.attachmentName + '_content_length' ] = null;
259
+
260
+ jQuery.ajax({
261
+ type: 'PATCH',
262
+ url: '/' + self.modelName.pluralize() + '/' + self.modelId,
263
+ data: params,
264
+ headers: {
265
+ 'X-CSRF-Token': self.csrfToken,
266
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
267
+ }
268
+ }).done(function ( data, textStatus, jqXHR ) {
269
+ if ( jqXHR.status === 200 ) {
270
+ resolve(true);
271
+ } else {
272
+ reject(jqXHR);
273
+ }
274
+ });
275
+ });
276
+ };
277
+
278
+ return Stratosphere;
279
+
280
+ }();
281
+
282
+ if ( !!window.jQuery ) {
283
+ if ( !!window.Turbolinks ) {
284
+ jQuery(document).on('page:change', function() {
285
+ Stratosphere.activate();
286
+ });
287
+ jQuery(document).on('page:before-unload', function() {
288
+ Stratosphere.deactivate();
289
+ });
290
+ } else {
291
+ jQuery(document).ready(function() {
292
+ Stratosphere.activate();
293
+ });
294
+ }
295
+ } else {
296
+ console.error('jQuery not detected. Make sure you include stratosphere/main after jquery.');
297
+ }