luca 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. data/CHANGELOG +49 -0
  2. data/Gemfile +8 -1
  3. data/Gemfile.lock +97 -53
  4. data/Guardfile +3 -25
  5. data/README.md +5 -16
  6. data/ROADMAP +15 -9
  7. data/Rakefile +24 -75
  8. data/app.rb +10 -42
  9. data/app/assets/javascripts/luca/basic.coffee +1 -1
  10. data/app/assets/javascripts/luca/components/application.coffee +187 -104
  11. data/app/assets/javascripts/luca/components/collection_view.coffee +115 -51
  12. data/app/assets/javascripts/luca/components/controller.coffee +87 -10
  13. data/app/assets/javascripts/luca/components/fields/base.coffee +74 -13
  14. data/app/assets/javascripts/luca/components/fields/button_field.coffee +60 -13
  15. data/app/assets/javascripts/luca/components/fields/checkbox_array.coffee +12 -7
  16. data/app/assets/javascripts/luca/components/fields/select_field.coffee +82 -23
  17. data/app/assets/javascripts/luca/components/fields/text_area_field.coffee +25 -10
  18. data/app/assets/javascripts/luca/components/fields/text_field.coffee +9 -3
  19. data/app/assets/javascripts/luca/components/form_view.coffee +105 -33
  20. data/app/assets/javascripts/luca/components/grid_layout_view.coffee +42 -0
  21. data/app/assets/javascripts/luca/components/index.coffee +6 -0
  22. data/app/assets/javascripts/luca/components/nav_bar.coffee +60 -6
  23. data/app/assets/javascripts/luca/components/page.coffee +70 -0
  24. data/app/assets/javascripts/luca/components/simple_collection_view.coffee +10 -0
  25. data/app/assets/javascripts/luca/components/table_view.coffee +7 -3
  26. data/app/assets/javascripts/luca/components/table_view_scrollable.coffee +23 -0
  27. data/app/assets/javascripts/luca/concerns/collection_event_bindings.coffee +4 -1
  28. data/app/assets/javascripts/luca/concerns/development_tool_helpers.coffee +23 -14
  29. data/app/assets/javascripts/luca/concerns/dom_helpers.coffee +2 -2
  30. data/app/assets/javascripts/luca/concerns/filterable.coffee +8 -11
  31. data/app/assets/javascripts/luca/concerns/form_model_bindings.coffee +20 -0
  32. data/app/assets/javascripts/luca/concerns/modal_view.coffee +40 -15
  33. data/app/assets/javascripts/luca/concerns/query_collection_bindings.coffee +7 -1
  34. data/app/assets/javascripts/luca/concerns/state_model.coffee +40 -26
  35. data/app/assets/javascripts/luca/concerns/templating.coffee +3 -1
  36. data/app/assets/javascripts/luca/config.coffee +5 -0
  37. data/app/assets/javascripts/luca/containers/card_view.coffee +87 -52
  38. data/app/assets/javascripts/luca/containers/container.coffee +305 -108
  39. data/app/assets/javascripts/luca/containers/modal_view.coffee +9 -9
  40. data/app/assets/javascripts/luca/containers/page_controller.coffee +25 -0
  41. data/app/assets/javascripts/luca/containers/panel_toolbar.coffee +5 -6
  42. data/app/assets/javascripts/luca/containers/tab_view.coffee +19 -10
  43. data/app/assets/javascripts/luca/containers/viewport.coffee +12 -16
  44. data/app/assets/javascripts/luca/core/collection.coffee +19 -5
  45. data/app/assets/javascripts/luca/core/events.coffee +5 -5
  46. data/app/assets/javascripts/luca/core/model.coffee +1 -1
  47. data/app/assets/javascripts/luca/core/panel.coffee +18 -6
  48. data/app/assets/javascripts/luca/core/registry/component_definition.coffee +2 -1
  49. data/app/assets/javascripts/luca/core/registry/meta_data.coffee +2 -0
  50. data/app/assets/javascripts/luca/core/registry/registry.coffee +14 -11
  51. data/app/assets/javascripts/luca/core/templates.coffee +5 -1
  52. data/app/assets/javascripts/luca/core/view.coffee +200 -47
  53. data/app/assets/javascripts/luca/dependencies.coffee +2 -0
  54. data/app/assets/javascripts/luca/development/code_sync_manager.coffee +173 -0
  55. data/app/assets/javascripts/luca/development/component.coffee +76 -0
  56. data/app/assets/javascripts/luca/development/components.coffee +57 -0
  57. data/app/assets/javascripts/luca/development/console.coffee +1 -1
  58. data/app/assets/javascripts/luca/development/index.coffee +4 -1
  59. data/app/assets/javascripts/luca/framework.coffee +7 -3
  60. data/app/assets/javascripts/luca/index.coffee +2 -1
  61. data/app/assets/javascripts/luca/managers/collection_manager.coffee +2 -3
  62. data/app/assets/javascripts/luca/managers/index.coffee +1 -1
  63. data/app/assets/javascripts/luca/managers/socket_manager.coffee +31 -8
  64. data/app/assets/javascripts/luca/templates/components/nav_bar.jst.ejs +16 -1
  65. data/app/assets/javascripts/luca/templates/containers/tab_view.jst.ejs +1 -1
  66. data/app/assets/javascripts/luca/util/index.coffee +1 -0
  67. data/app/assets/javascripts/luca/util/keybindings.coffee +24 -0
  68. data/app/assets/javascripts/luca/util/logging.coffee +15 -0
  69. data/app/assets/javascripts/luca/util/luca.coffee +9 -1
  70. data/app/assets/stylesheets/luca/components/table_view.scss +85 -0
  71. data/app/assets/stylesheets/luca/components/viewport.scss +0 -4
  72. data/app/assets/stylesheets/luca/containers/container.scss +8 -0
  73. data/app/assets/stylesheets/luca/index.css +2 -2
  74. data/bin/luca +14 -0
  75. data/config.ru +1 -2
  76. data/docs/framework.json +1 -0
  77. data/docs/luca-framework-documentation.js +1 -0
  78. data/docs/{application.md → old/application.md} +0 -0
  79. data/docs/{collection.md → old/collection.md} +0 -0
  80. data/docs/{collection_manager.md → old/collection_manager.md} +0 -0
  81. data/docs/{container_philosophy.md → old/container_philosophy.md} +0 -0
  82. data/docs/{event_binding_helpers.md → old/event_binding_helpers.md} +0 -0
  83. data/docs/{method_caching_and_computed_properties.md → old/method_caching_and_computed_properties.md} +0 -0
  84. data/docs/{view.md → old/view.md} +0 -0
  85. data/lib/generators/luca/application/templates/javascripts/dependencies.coffee +2 -5
  86. data/lib/guard/luca.rb +84 -0
  87. data/lib/luca.rb +25 -1
  88. data/lib/luca/asset_compiler.rb +117 -0
  89. data/lib/luca/cli.rb +68 -0
  90. data/lib/luca/cli/generate.rb +37 -0
  91. data/lib/luca/cli/server.rb +20 -0
  92. data/lib/luca/cli/sync.rb +40 -0
  93. data/lib/luca/cli/watch.rb +16 -0
  94. data/lib/luca/collection.rb +64 -0
  95. data/lib/luca/collection/endpoint.rb +38 -0
  96. data/lib/luca/collection/file_backend.rb +121 -0
  97. data/lib/luca/collection/redis_backend.rb +153 -0
  98. data/lib/luca/compiled_asset.rb +61 -0
  99. data/lib/luca/component_definition.rb +356 -0
  100. data/lib/luca/luca_application.rb +258 -0
  101. data/lib/luca/project.rb +73 -0
  102. data/lib/luca/project_harness.rb +96 -0
  103. data/lib/luca/rails.rb +5 -3
  104. data/lib/luca/rails/engine.rb +8 -0
  105. data/lib/luca/rails/version.rb +1 -2
  106. data/lib/luca/server.rb +7 -0
  107. data/lib/luca/stylesheet.rb +35 -0
  108. data/lib/luca/template.rb +2 -0
  109. data/lib/luca/template_asset.rb +64 -0
  110. data/lib/luca/version.rb +3 -0
  111. data/lib/luca/watcher.rb +72 -0
  112. data/lib/railties/luca/tasks.rake +7 -0
  113. data/site/.bundle/config +2 -0
  114. data/site/.gitignore +5 -0
  115. data/site/.rvmrc +1 -0
  116. data/site/CHANGELOG.md +41 -0
  117. data/site/DOCS.md +41 -0
  118. data/site/Gemfile +8 -0
  119. data/site/Gemfile.lock +134 -0
  120. data/site/LICENSE.md +19 -0
  121. data/site/config.rb +84 -0
  122. data/site/helpers/site_helpers.rb +20 -0
  123. data/site/html5bp-docs/README.md +38 -0
  124. data/site/html5bp-docs/contribute.md +104 -0
  125. data/site/html5bp-docs/crossdomain.md +21 -0
  126. data/site/html5bp-docs/css.md +135 -0
  127. data/site/html5bp-docs/extend.md +507 -0
  128. data/site/html5bp-docs/faq.md +77 -0
  129. data/site/html5bp-docs/htaccess.md +323 -0
  130. data/site/html5bp-docs/html.md +170 -0
  131. data/site/html5bp-docs/js.md +31 -0
  132. data/site/html5bp-docs/misc.md +25 -0
  133. data/site/html5bp-docs/usage.md +109 -0
  134. data/site/readme.md +47 -0
  135. data/site/source/.htaccess +540 -0
  136. data/site/source/404.html +157 -0
  137. data/site/source/app/assets/javascripts/dependencies.js.coffee +6 -0
  138. data/site/source/app/assets/javascripts/docs-docs.js +1 -0
  139. data/site/source/app/assets/javascripts/docs/application.coffee +64 -0
  140. data/site/source/app/assets/javascripts/docs/collections/docs_documentation.coffee +17 -0
  141. data/site/source/app/assets/javascripts/docs/collections/github_repositories.coffee +7 -0
  142. data/site/source/app/assets/javascripts/docs/collections/index.coffee +1 -0
  143. data/site/source/app/assets/javascripts/docs/collections/luca_documentation.coffee +17 -0
  144. data/site/source/app/assets/javascripts/docs/collections/public_gists.coffee +4 -0
  145. data/site/source/app/assets/javascripts/docs/config.coffee +5 -0
  146. data/site/source/app/assets/javascripts/docs/index.coffee +12 -0
  147. data/site/source/app/assets/javascripts/docs/lib/router.coffee +3 -0
  148. data/{spec/components/application_spec.coffee → site/source/app/assets/javascripts/docs/lib/util.coffee} +0 -0
  149. data/site/source/app/assets/javascripts/docs/models/component.coffee +99 -0
  150. data/site/source/app/assets/javascripts/docs/models/github_repository.coffee +3 -0
  151. data/site/source/app/assets/javascripts/docs/models/index.coffee +1 -0
  152. data/site/source/app/assets/javascripts/docs/templates/component_documentation.jst.ejs +55 -0
  153. data/site/source/app/assets/javascripts/docs/templates/examples_browser/overview.jst.ejs +4 -0
  154. data/site/source/app/assets/javascripts/docs/templates/examples_browser/selector.jst.ejs +11 -0
  155. data/site/source/app/assets/javascripts/docs/templates/github_repository.jst.ejs +4 -0
  156. data/site/source/app/assets/javascripts/docs/templates/layouts/main.jst.ejs +4 -0
  157. data/site/source/app/assets/javascripts/docs/templates/left_navigation.jst.ejs +5 -0
  158. data/site/source/app/assets/javascripts/docs/templates/pages/getting_started.jst.ejs +78 -0
  159. data/site/source/app/assets/javascripts/docs/templates/pages/home.jst.ejs +57 -0
  160. data/site/source/app/assets/javascripts/docs/views/components/code_editor.coffee +45 -0
  161. data/{spec/components/collection_loader_view_spec.coffee → site/source/app/assets/javascripts/docs/views/components/code_editor/index.coffee} +0 -0
  162. data/site/source/app/assets/javascripts/docs/views/components/component_documentation.coffee +72 -0
  163. data/site/source/app/assets/javascripts/docs/views/index.coffee +3 -0
  164. data/site/source/app/assets/javascripts/docs/views/pages/browse_source.coffee +46 -0
  165. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/details.coffee +37 -0
  166. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/list.coffee +31 -0
  167. data/site/source/app/assets/javascripts/docs/views/pages/component_editor.coffee +10 -0
  168. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser.coffee +102 -0
  169. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/docs.coffee +12 -0
  170. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/source.coffee +13 -0
  171. data/site/source/app/assets/javascripts/docs/views/pages/home.coffee +10 -0
  172. data/site/source/app/assets/javascripts/docs/views/views/api_browser/index.coffee +43 -0
  173. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/grid_layout_view_example.coffee +14 -0
  174. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/table_view_example.coffee +39 -0
  175. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/basic_example.coffee +38 -0
  176. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/complex_layout.coffee +110 -0
  177. data/site/source/app/assets/javascripts/docs/views/views/top_navigation.coffee +6 -0
  178. data/site/source/app/assets/javascripts/luca-docs.js +1 -0
  179. data/site/source/app/assets/javascripts/luca-framework-documentation.js +1 -0
  180. data/site/source/app/assets/javascripts/site.js.coffee +4 -0
  181. data/site/source/app/assets/javascripts/vendor/codemirror.js +4786 -0
  182. data/site/source/app/assets/javascripts/vendor/coffeescript.js +346 -0
  183. data/site/source/app/assets/javascripts/vendor/css.js +465 -0
  184. data/site/source/app/assets/javascripts/vendor/htmlmixed.js +84 -0
  185. data/site/source/app/assets/javascripts/vendor/javascript.js +422 -0
  186. data/site/source/app/assets/javascripts/vendor/js-beautify.js +1353 -0
  187. data/site/source/app/assets/javascripts/vendor/modernizr-2.6.1.min.js +4 -0
  188. data/site/source/app/assets/javascripts/vendor/vim.js +2511 -0
  189. data/site/source/app/assets/stylesheets/docs/api-browser.css.scss +5 -0
  190. data/site/source/app/assets/stylesheets/docs/application.css.scss +35 -0
  191. data/site/source/app/assets/stylesheets/docs/browse-source.css.scss +5 -0
  192. data/site/source/app/assets/stylesheets/docs/scrollable-table.css.scss +5 -0
  193. data/site/source/app/assets/stylesheets/site.css.scss +2 -0
  194. data/site/source/app/assets/stylesheets/vendor/codemirror.css +240 -0
  195. data/site/source/app/assets/stylesheets/vendor/prettify-tomorrow-night-bright.css +160 -0
  196. data/site/source/app/assets/stylesheets/vendor/twilight.css +26 -0
  197. data/site/source/crossdomain.xml +15 -0
  198. data/site/source/documentation.html.haml +1 -0
  199. data/site/source/favicon_base.png +0 -0
  200. data/site/source/humans.txt +15 -0
  201. data/site/source/images/background.png +0 -0
  202. data/site/source/images/middleman.png +0 -0
  203. data/site/source/index.html.haml +1 -0
  204. data/site/source/layouts/layout.haml +55 -0
  205. data/site/source/readme.md +63 -0
  206. data/site/source/robots.txt +3 -0
  207. data/spec/{components/grid_view_spec.coffee → javascripts/components/application_spec.coffee} +0 -0
  208. data/spec/{components/pagination_control_spec.coffee → javascripts/components/collection_loader_view_spec.coffee} +0 -0
  209. data/spec/{components → javascripts/components}/collection_view_spec.coffee +1 -1
  210. data/spec/{components → javascripts/components}/controller_spec.coffee +0 -0
  211. data/spec/{components → javascripts/components}/fields/checkbox_array_spec.coffee +0 -0
  212. data/spec/javascripts/components/form_view_spec.coffee +162 -0
  213. data/spec/{components/record_manager_spec.coffee → javascripts/components/grid_view_spec.coffee} +0 -0
  214. data/spec/{components → javascripts/components}/multi_collection_view_spec.coffee +0 -0
  215. data/spec/{components/template_spec.coffee → javascripts/components/pagination_control_spec.coffee} +0 -0
  216. data/spec/{concerns/paginatable_spec.coffee → javascripts/components/record_manager_spec.coffee} +0 -0
  217. data/spec/{components → javascripts/components}/table_view_spec.coffee +0 -0
  218. data/spec/{containers/modal_view_spec.coffee → javascripts/components/template_spec.coffee} +0 -0
  219. data/spec/{concerns → javascripts/concerns}/collection_event_bindings_spec.coffee +0 -0
  220. data/spec/{concerns → javascripts/concerns}/dom_helpers_spec.coffee +0 -0
  221. data/spec/{concerns → javascripts/concerns}/filterable_spec.coffee +0 -0
  222. data/spec/{concerns → javascripts/concerns}/model_presenter_spec.coffee +0 -0
  223. data/spec/{containers/panel_view_spec.coffee → javascripts/concerns/paginatable_spec.coffee} +0 -0
  224. data/spec/{concerns → javascripts/concerns}/state_model_spec.coffee +5 -0
  225. data/spec/javascripts/containers/card_view_spec.coffee +108 -0
  226. data/spec/{containers/tab_view_spec.coffee → javascripts/containers/modal_view_spec.coffee} +0 -0
  227. data/spec/{containers/viewport_spec.coffee → javascripts/containers/panel_view_spec.coffee} +0 -0
  228. data/spec/{core/observer_spec.coffee → javascripts/containers/tab_view_spec.coffee} +0 -0
  229. data/spec/{managers/socket_manager_spec.coffee → javascripts/containers/viewport_spec.coffee} +0 -0
  230. data/spec/{core → javascripts/core}/collection_spec.coffee +1 -1
  231. data/spec/{core → javascripts/core}/concerns_spec.coffee +0 -0
  232. data/spec/{core → javascripts/core}/container_spec.coffee +0 -0
  233. data/spec/{core → javascripts/core}/define_spec.coffee +0 -0
  234. data/spec/{core → javascripts/core}/events_spec.coffee +0 -0
  235. data/spec/{core → javascripts/core}/field_spec.coffee +0 -0
  236. data/spec/{core → javascripts/core}/framework_spec.coffee +0 -0
  237. data/spec/{core → javascripts/core}/model_spec.coffee +0 -0
  238. data/spec/javascripts/core/observer_spec.coffee +0 -0
  239. data/spec/{core → javascripts/core}/util_spec.coffee +0 -0
  240. data/spec/{core → javascripts/core}/view_spec.coffee +51 -39
  241. data/spec/{dependencies → javascripts/dependencies}/index.coffee +0 -0
  242. data/spec/{dependencies → javascripts/dependencies}/jasmine-html.js +0 -0
  243. data/spec/{dependencies → javascripts/dependencies}/jasmine.js +0 -0
  244. data/spec/{dependencies → javascripts/dependencies}/sinon.js +0 -0
  245. data/spec/{helper.coffee → javascripts/helper.coffee} +0 -0
  246. data/spec/{managers → javascripts/managers}/collection_manager_spec.coffee +0 -0
  247. data/spec/javascripts/managers/socket_manager_spec.coffee +0 -0
  248. data/spec/lib/component_definition_spec.rb +63 -0
  249. data/spec/lib/input_compiler_spec.rb +9 -0
  250. data/spec/lib/luca_application_spec.rb +30 -0
  251. data/spec/support/fixtures/application.coffee +45 -0
  252. data/spec/support/fixtures/component.coffee +34 -0
  253. data/tutorials/component-definitions.md +0 -0
  254. data/tutorials/component-definitions/01_intro.md +0 -0
  255. data/tutorials/component-driven-design.md +140 -0
  256. data/tutorials/structure-of-a-project.md +63 -0
  257. data/vendor/assets/javascripts/backbone-min.js +37 -33
  258. data/vendor/assets/javascripts/backbone-query.min.js +1 -1
  259. data/vendor/assets/javascripts/hogan.js +707 -0
  260. data/vendor/assets/javascripts/jquery.js +5 -4
  261. data/vendor/assets/javascripts/keymaster.min.js +4 -0
  262. data/vendor/assets/javascripts/luca-dependencies.min.js +8 -0
  263. data/vendor/assets/javascripts/luca-development.min.js +1 -0
  264. data/vendor/assets/javascripts/luca-spec.js +6 -6
  265. data/vendor/assets/javascripts/luca-ui.js +7386 -0
  266. data/vendor/assets/javascripts/luca-ui.min.js +5 -0
  267. data/vendor/assets/javascripts/luca.full.min.js +12 -0
  268. data/vendor/assets/javascripts/luca.min.js +5 -0
  269. data/vendor/assets/javascripts/underscore-min.js +1 -5
  270. data/vendor/assets/javascripts/underscore-string.min.js +1 -1
  271. data/vendor/assets/stylesheets/luca-components.css +202 -0
  272. data/vendor/assets/stylesheets/luca-development.css +23 -0
  273. data/vendor/assets/stylesheets/luca-ui.css +198 -0
  274. metadata +324 -94
  275. data/app/assets/javascripts/luca/components/base_toolbar.coffee +0 -17
  276. data/app/assets/javascripts/luca/components/form_button_toolbar.coffee +0 -28
  277. data/app/assets/javascripts/luca/components/grid_view.coffee +0 -269
  278. data/app/assets/javascripts/luca/components/page_controller.coffee +0 -7
  279. data/app/assets/javascripts/luca/components/template.coffee +0 -5
  280. data/app/assets/javascripts/luca/components/toolbar_dialog.coffee +0 -25
  281. data/lib/luca/code_browser.rb +0 -55
  282. data/lib/luca/command_line.rb +0 -69
  283. data/lib/luca/component_documentation.rb +0 -72
  284. data/site/assets/bootstrap.min.js +0 -7
  285. data/site/assets/dependencies.js +0 -94
  286. data/site/assets/glyphicons-halflings-white.png +0 -0
  287. data/site/assets/glyphicons-halflings.png +0 -0
  288. data/site/assets/luca-ui-bootstrap.css +0 -1331
  289. data/site/assets/luca-ui-bootstrap.js +0 -9
  290. data/site/assets/luca-ui-development-tools.css +0 -234
  291. data/site/assets/luca-ui-development-tools.js +0 -18561
  292. data/site/assets/luca-ui-development-tools.min.js +0 -15
  293. data/site/assets/luca-ui-full.min.js +0 -8
  294. data/site/assets/luca-ui.min.js +0 -4
  295. data/site/assets/sandbox.css +0 -62
  296. data/site/assets/sandbox.js +0 -469
  297. data/site/docs/application.html +0 -41
  298. data/site/docs/caching.html +0 -43
  299. data/site/docs/collection.html +0 -75
  300. data/site/docs/collection_manager.html +0 -71
  301. data/site/docs/containers.html +0 -118
  302. data/site/docs/events.html +0 -153
  303. data/site/docs/view.html +0 -128
  304. data/site/img/glyphicons-halflings-white.png +0 -0
  305. data/site/img/glyphicons-halflings.png +0 -0
  306. data/site/index.html +0 -20
  307. data/site/source-map.js +0 -1
  308. data/spec/components/form_view_spec.coffee +0 -84
  309. data/spec/containers/card_view_spec.coffee +0 -50
  310. data/spec/luca-spec.coffee +0 -9
@@ -0,0 +1,63 @@
1
+ ## The Structure Of A Project
2
+
3
+ Luca Applications can be generated with a rails generator `rails generate luca:application app`
4
+
5
+ This will create an application file structure for you, as well as some basic classes:
6
+
7
+ ```
8
+ - app/assets/javascripts/app
9
+ - views/
10
+ - models/
11
+ - components/
12
+ - collections/
13
+ - templates/
14
+ - lib/
15
+ - config.coffee
16
+ - index.coffee
17
+ - application.coffee
18
+ ```
19
+
20
+ ### config.coffee
21
+
22
+ ```
23
+ Luca.initialize "App",
24
+ modelBootstrap: "window.AppBootstrap"
25
+ customConfigValue: "overrides Luca.config.customConfigValue"
26
+ ```
27
+
28
+ This will create the necessary namespaces to hold your components:
29
+
30
+ ```
31
+ window.App =
32
+ views: {}
33
+ collections: {}
34
+ models: {}
35
+ components: {}
36
+ ```
37
+
38
+ It will also create a helper function for you called `App()`
39
+
40
+ `App()` without any arguments can be used to access the singleton instance of the global `App.Application` class.
41
+
42
+ `App("my_view_name")` can be used to access an individual view instance by its `@name` or `@cid` property.
43
+
44
+ `App(".custom-dom-selector")` can be used to access an instance of a view by a member of its DOM structure.
45
+
46
+
47
+ ### index.coffee
48
+
49
+ This will make the application available to the Rails asset Pipeline. You simply need to:
50
+
51
+ ```
52
+ javascript_include_tag 'app'
53
+ ```
54
+
55
+ This will load all of the assets defined in your folder, in the proper order they need to be included.
56
+
57
+ It will also handle booting your application for you:
58
+
59
+ ```
60
+ App.onReady ()->
61
+ window.MyApp = new App.Application()
62
+ window.MyApp.boot()
63
+ ```
@@ -1,38 +1,42 @@
1
- // Backbone.js 0.9.2
1
+ // Backbone.js 0.9.9
2
2
 
3
3
  // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
4
4
  // Backbone may be freely distributed under the MIT license.
5
5
  // For all details and documentation:
6
6
  // http://backbonejs.org
7
- (function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks=
8
- {});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g=
9
- z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent=
10
- {};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null==
11
- b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent:
12
- b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)};
13
- a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error,
14
- h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t();
15
- return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending=
16
- {};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length||
17
- !this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator);
18
- this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");g=e.cid;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])?
19
- l.push(c):j[g]=k[i]=e}for(c=l.length;c--;)a.splice(l[c],1);c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;A.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:!0});if(b.silent)return this;c=0;for(d=this.models.length;c<d;c++)if(j[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?
20
- a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],e=this.indexOf(g),this.models.splice(e,1),this.length--,b.silent||(b.index=e,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,b);return a},pop:function(a){var b=this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,f.extend({at:0},b));return a},
21
- shift:function(a){var b=this.at(0);this.remove(b,a);return b},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return f.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1==this.comparator.length?
22
- this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,f.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d,
23
- e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(e,f){b.wait&&c.add(e,b);d?d(e,f):e.trigger("sync",a,f,b)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId=
24
- {};this._byCid={}},_prepareModel:function(a,b){b||(b={});a instanceof o?a.collection||(a.collection=this):(b.collection=this,a=new this.model(a,b),a._validate(a.attributes,b)||(a=!1));return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,
25
- arguments))}});f.each("forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split(","),function(a){r.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});var u=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/:\w+/g,
26
- C=/\*\w+/g,D=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(u.prototype,k,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new m);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,
27
- this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(D,"\\$&").replace(B,"([^/]+)").replace(C,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var m=g.History=function(){this.handlers=[];f.bindAll(this,"checkUrl")},s=/^[#\/]/,E=/msie [\w.]+/;m.started=!1;f.extend(m.prototype,k,{interval:50,getHash:function(a){return(a=(a?a.location:window.location).href.match(/#(.*)$/))?a[1]:
28
- ""},getFragment:function(a,b){if(null==a)if(this._hasPushState||b){var a=window.location.pathname,c=window.location.search;c&&(a+=c)}else a=this.getHash();a.indexOf(this.options.root)||(a=a.substr(this.options.root.length));return a.replace(s,"")},start:function(a){if(m.started)throw Error("Backbone.history has already been started");m.started=!0;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=
29
- !(!this.options.pushState||!window.history||!window.history.pushState);var a=this.getFragment(),b=document.documentMode;if(b=E.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b))this.iframe=i('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);this._hasPushState?i(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?i(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,
30
- this.interval));this.fragment=a;a=window.location;b=a.pathname==this.options.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;this._wantsPushState&&this._hasPushState&&b&&a.hash&&(this.fragment=this.getHash().replace(s,""),window.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment));if(!this.options.silent)return this.loadUrl()},
31
- stop:function(){i(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);m.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a==this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},loadUrl:function(a){var b=this.fragment=this.getFragment(a);return f.any(this.handlers,
32
- function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!m.started)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(s,"");this.fragment!=c&&(this._hasPushState?(0!=c.indexOf(this.options.root)&&(c=this.options.root+c),this.fragment=c,window.history[b.replace?"replaceState":"pushState"]({},document.title,c)):this._wantsHashChange?(this.fragment=c,this._updateHash(window.location,c,b.replace),this.iframe&&c!=this.getFragment(this.getHash(this.iframe))&&(b.replace||
33
- this.iframe.document.open().close(),this._updateHash(this.iframe.location,c,b.replace))):window.location.assign(this.options.root+a),b.trigger&&this.loadUrl(a))},_updateHash:function(a,b,c){c?a.replace(a.toString().replace(/(javascript:|#).*$/,"")+"#"+b):a.hash=b}});var v=g.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},F=/^(\S+)\s*(.*)$/,w="model,collection,el,id,attributes,className,tagName".split(",");
34
- f.extend(v.prototype,k,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&i(a).attr(b);c&&i(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof i?a:i(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=n(this,"events"))){this.undelegateEvents();
35
- for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(F),e=d[1],d=d[2],c=f.bind(c,this),e=e+(".delegateEvents"+this.cid);""===d?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=w.length;b<c;b++){var d=w[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,
36
- !1);else{var a=n(this,"attributes")||{};this.id&&(a.id=this.id);this.className&&(a["class"]=this.className);this.setElement(this.make(this.tagName,a),!1)}}});o.extend=r.extend=u.extend=v.extend=function(a,b){var c=G(this,a,b);c.extend=this.extend;return c};var H={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=H[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=n(b,"url")||t());if(!c.data&&b&&("create"==a||"update"==a))e.contentType="application/json",
37
- e.data=JSON.stringify(b.toJSON());g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return i.ajax(f.extend(e,c))};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var x=function(){},G=function(a,
38
- b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};f.extend(d,a);x.prototype=a.prototype;d.prototype=new x;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},n=function(a,b){return!a||!a[b]?null:f.isFunction(a[b])?a[b]():a[b]},t=function(){throw Error('A "url" property or function must be specified');}}).call(this);
7
+ (function(){var k=this,y=k.Backbone,h=[],z=h.push,r=h.slice,A=h.splice,g;g="undefined"!==typeof exports?exports:k.Backbone={};g.VERSION="0.9.9";var e=k._;!e&&"undefined"!==typeof require&&(e=require("underscore"));g.$=k.jQuery||k.Zepto||k.ender;g.noConflict=function(){k.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var s=/\s+/,n=function(a,b,c,d){if(!c)return!0;if("object"===typeof c)for(var f in c)a[b].apply(a,[f,c[f]].concat(d));else if(s.test(c)){c=c.split(s);f=0;for(var e=c.length;f<
8
+ e;f++)a[b].apply(a,[c[f]].concat(d))}else return!0},t=function(a,b,c){var d,a=-1,f=b.length;switch(c.length){case 0:for(;++a<f;)(d=b[a]).callback.call(d.ctx);break;case 1:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0]);break;case 2:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0],c[1]);break;case 3:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0],c[1],c[2]);break;default:for(;++a<f;)(d=b[a]).callback.apply(d.ctx,c)}},h=g.Events={on:function(a,b,c){if(!n(this,"on",a,[b,c])||!b)return this;this._events||(this._events=
9
+ {});(this._events[a]||(this._events[a]=[])).push({callback:b,context:c,ctx:c||this});return this},once:function(a,b,c){if(!n(this,"once",a,[b,c])||!b)return this;var d=this,f=e.once(function(){d.off(a,f);b.apply(this,arguments)});f._callback=b;this.on(a,f,c);return this},off:function(a,b,c){var d,f,l,g,i,m,h,j;if(!this._events||!n(this,"off",a,[b,c]))return this;if(!a&&!b&&!c)return this._events={},this;g=a?[a]:e.keys(this._events);i=0;for(m=g.length;i<m;i++)if(a=g[i],d=this._events[a]){l=[];if(b||
10
+ c){h=0;for(j=d.length;h<j;h++)f=d[h],(b&&b!==(f.callback._callback||f.callback)||c&&c!==f.context)&&l.push(f)}this._events[a]=l}return this},trigger:function(a){if(!this._events)return this;var b=r.call(arguments,1);if(!n(this,"trigger",a,b))return this;var c=this._events[a],d=this._events.all;c&&t(this,c,b);d&&t(this,d,arguments);return this},listenTo:function(a,b,c){var d=this._listeners||(this._listeners={}),f=a._listenerId||(a._listenerId=e.uniqueId("l"));d[f]=a;a.on(b,c||this,this);return this},
11
+ stopListening:function(a,b,c){var d=this._listeners;if(d){if(a)a.off(b,c,this),!b&&!c&&delete d[a._listenerId];else{for(var f in d)d[f].off(null,null,this);this._listeners={}}return this}}};h.bind=h.on;h.unbind=h.off;e.extend(g,h);var o=g.Model=function(a,b){var c,d=a||{};this.cid=e.uniqueId("c");this.changed={};this.attributes={};this._changes=[];b&&b.collection&&(this.collection=b.collection);b&&b.parse&&(d=this.parse(d));(c=e.result(this,"defaults"))&&e.defaults(d,c);this.set(d,{silent:!0});this._currentAttributes=
12
+ e.clone(this.attributes);this._previousAttributes=e.clone(this.attributes);this.initialize.apply(this,arguments)};e.extend(o.prototype,h,{changed:null,idAttribute:"id",initialize:function(){},toJSON:function(){return e.clone(this.attributes)},sync:function(){return g.sync.apply(this,arguments)},get:function(a){return this.attributes[a]},escape:function(a){return e.escape(this.get(a))},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,f;if(null==a)return this;e.isObject(a)?(f=a,c=
13
+ b):(f={})[a]=b;var a=c&&c.silent,l=c&&c.unset;if(!this._validate(f,c))return!1;this.idAttribute in f&&(this.id=f[this.idAttribute]);var g=this.attributes;for(d in f)b=f[d],l?delete g[d]:g[d]=b,this._changes.push(d,b);this._hasComputed=!1;a||this.change(c);return this},unset:function(a,b){return this.set(a,void 0,e.extend({},b,{unset:!0}))},clear:function(a){var b={},c;for(c in this.attributes)b[c]=void 0;return this.set(b,e.extend({},a,{unset:!0}))},fetch:function(a){a=a?e.clone(a):{};void 0===a.parse&&
14
+ (a.parse=!0);var b=this,c=a.success;a.success=function(d){if(!b.set(b.parse(d),a))return false;c&&c(b,d,a)};return this.sync("read",this,a)},save:function(a,b,c){var d,f,g;null==a||e.isObject(a)?(d=a,c=b):null!=a&&((d={})[a]=b);c=c?e.clone(c):{};if(c.wait){if(d&&!this._validate(d,c))return!1;f=e.clone(this.attributes)}a=e.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c)||!d&&!this._validate(null,c))return!1;var q=this,i=c.success;c.success=function(a){g=true;var b=q.parse(a);c.wait&&(b=e.extend(d||
15
+ {},b));if(!q.set(b,c))return false;i&&i(q,a,c)};b=this.isNew()?"create":c.patch?"patch":"update";"patch"==b&&(c.attrs=d);b=this.sync(b,this,c);!g&&c.wait&&(this.clear(a),this.set(f,a));return b},destroy:function(a){var a=a?e.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};a.success=function(f){(a.wait||b.isNew())&&d();c&&c(b,f,a)};if(this.isNew())return a.success(),!1;var f=this.sync("delete",this,a);a.wait||d();return f},url:function(){var a=e.result(this,"urlRoot")||
16
+ e.result(this.collection,"url")||u();return this.isNew()?a:a+("/"===a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){var b=this._changing;this._changing=!0;var c=this._computeChanges(!0);this._pending=!!c.length;for(var d=c.length-2;0<=d;d-=2)this.trigger("change:"+c[d],this,c[d+1],a);if(b)return this;for(;this._pending;)this._pending=!1,this.trigger("change",
17
+ this,a),this._previousAttributes=e.clone(this.attributes);this._changing=!1;return this},hasChanged:function(a){this._hasComputed||this._computeChanges();return null==a?!e.isEmpty(this.changed):e.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?e.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,f;for(f in a)if(!e.isEqual(d[f],b=a[f]))(c||(c={}))[f]=b;return c},_computeChanges:function(a){this.changed={};for(var b={},c=[],d=this._currentAttributes,f=this._changes,
18
+ e=f.length-2;0<=e;e-=2){var g=f[e],i=f[e+1];b[g]||(b[g]=!0,d[g]!==i&&(this.changed[g]=i,a&&(c.push(g,i),d[g]=i)))}a&&(this._changes=[]);this._hasComputed=!0;return c},previous:function(a){return null==a||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return e.clone(this._previousAttributes)},_validate:function(a,b){if(!this.validate)return!0;var a=e.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error&&b.error(this,c,b);this.trigger("error",
19
+ this,c,b);return!1}});var p=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);void 0!==b.comparator&&(this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,e.extend({silent:!0},b))};e.extend(p.prototype,h,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},sync:function(){return g.sync.apply(this,arguments)},add:function(a,b){var c,d,f,g,h=b&&b.at,i=null==(b&&b.sort)?!0:b.sort,a=e.isArray(a)?
20
+ a.slice():[a];for(c=a.length-1;0<=c;c--)(d=this._prepareModel(a[c],b))?(a[c]=d,(f=null!=d.id&&this._byId[d.id])||this._byCid[d.cid]?(b&&(b.merge&&f)&&(f.set(d.attributes,b),g=i),a.splice(c,1)):(d.on("all",this._onModelEvent,this),this._byCid[d.cid]=d,null!=d.id&&(this._byId[d.id]=d))):(this.trigger("error",this,a[c],b),a.splice(c,1));a.length&&(g=i);this.length+=a.length;c=[null!=h?h:this.models.length,0];z.apply(c,a);A.apply(this.models,c);g&&(this.comparator&&null==h)&&this.sort({silent:!0});if(b&&
21
+ b.silent)return this;for(;d=a.shift();)d.trigger("add",d,this,b);return this},remove:function(a,b){var c,d,f,g;b||(b={});a=e.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],f=this.indexOf(g),this.models.splice(f,1),this.length--,b.silent||(b.index=f,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,e.extend({at:this.length},b));return a},pop:function(a){var b=
22
+ this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,e.extend({at:0},b));return a},shift:function(a){var b=this.at(0);this.remove(b,a);return b},slice:function(a,b){return this.models.slice(a,b)},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]||this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return e.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},
23
+ sort:function(a){if(!this.comparator)throw Error("Cannot sort a set without a comparator");e.isString(this.comparator)||1===this.comparator.length?this.models=this.sortBy(this.comparator,this):this.models.sort(e.bind(this.comparator,this));(!a||!a.silent)&&this.trigger("sort",this,a);return this},pluck:function(a){return e.invoke(this.models,"get",a)},update:function(a,b){var c,d,f,g,h=[],i=[],m={},j=this.model.prototype.idAttribute,b=e.extend({add:!0,merge:!0,remove:!0},b);b.parse&&(a=this.parse(a));
24
+ e.isArray(a)||(a=a?[a]:[]);if(b.add&&!b.remove)return this.add(a,b);d=0;for(f=a.length;d<f;d++)c=a[d],g=this.get(c.id||c.cid||c[j]),b.remove&&g&&(m[g.cid]=!0),(b.add&&!g||b.merge&&g)&&h.push(c);if(b.remove){d=0;for(f=this.models.length;d<f;d++)c=this.models[d],m[c.cid]||i.push(c)}i.length&&this.remove(i,b);h.length&&this.add(h,b);return this},reset:function(a,b){b||(b={});b.parse&&(a=this.parse(a));for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);b.previousModels=this.models;
25
+ this._reset();a&&this.add(a,e.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?e.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d){b[a.update?"update":"reset"](d,a);c&&c(b,d,a)};return this.sync("read",this,a)},create:function(a,b){var c=this,b=b?e.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(a,b,e){e.wait&&c.add(a,e);d&&d(a,b,e)};a.save(null,b);return a},
26
+ parse:function(a){return a},clone:function(){return new this.constructor(this.models)},chain:function(){return e(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){if(a instanceof o)return a.collection||(a.collection=this),a;b||(b={});b.collection=this;var c=new this.model(a,b);return!c._validate(a,b)?!1:c},_removeReference:function(a){this===a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,
27
+ b,c,d){("add"===a||"remove"===a)&&c!==this||("destroy"===a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],null!=b.id&&(this._byId[b.id]=b)),this.trigger.apply(this,arguments))}});e.each("forEach each map collect reduce foldl inject reduceRight foldr find detect filter select reject every all some any include contains invoke max min sortedIndex toArray size first head take initial rest tail last without indexOf shuffle lastIndexOf isEmpty".split(" "),
28
+ function(a){p.prototype[a]=function(){var b=r.call(arguments);b.unshift(this.models);return e[a].apply(e,b)}});e.each(["groupBy","countBy","sortBy"],function(a){p.prototype[a]=function(b,c){var d=e.isFunction(b)?b:function(a){return a.get(b)};return e[a](this.models,d,c)}});var v=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/\((.*?)\)/g,C=/:\w+/g,D=/\*\w+/g,E=/[\-{}\[\]+?.,\\\^$|#\s]/g;e.extend(v.prototype,h,{initialize:function(){},
29
+ route:function(a,b,c){e.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,e.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b);return this},_bindRoutes:function(){if(this.routes)for(var a,b=e.keys(this.routes);null!=(a=b.pop());)this.route(a,this.routes[a])},_routeToRegExp:function(a){a=a.replace(E,"\\$&").replace(B,
30
+ "(?:$1)?").replace(C,"([^/]+)").replace(D,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var j=g.History=function(){this.handlers=[];e.bindAll(this,"checkUrl");"undefined"!==typeof window&&(this.location=window.location,this.history=window.history)},w=/^[#\/]|\s+$/g,F=/^\/+|\/+$/g,G=/msie [\w.]+/,H=/\/$/;j.started=!1;e.extend(j.prototype,h,{interval:50,getHash:function(a){return(a=(a||this).location.href.match(/#(.*)$/))?a[1]:""},getFragment:function(a,
31
+ b){if(null==a)if(this._hasPushState||!this._wantsHashChange||b){var a=this.location.pathname,c=this.root.replace(H,"");a.indexOf(c)||(a=a.substr(c.length))}else a=this.getHash();return a.replace(w,"")},start:function(a){if(j.started)throw Error("Backbone.history has already been started");j.started=!0;this.options=e.extend({},{root:"/"},this.options,a);this.root=this.options.root;this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||
32
+ !this.history||!this.history.pushState);var a=this.getFragment(),b=document.documentMode,b=G.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b);this.root=("/"+this.root+"/").replace(F,"/");b&&this._wantsHashChange&&(this.iframe=g.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a));this._hasPushState?g.$(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?g.$(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&
33
+ (this._checkUrlInterval=setInterval(this.checkUrl,this.interval));this.fragment=a;a=this.location;b=a.pathname.replace(/[^\/]$/,"$&/")===this.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+this.location.search+"#"+this.fragment),!0;this._wantsPushState&&(this._hasPushState&&b&&a.hash)&&(this.fragment=this.getHash().replace(w,""),this.history.replaceState({},document.title,this.root+this.fragment+
34
+ a.search));if(!this.options.silent)return this.loadUrl()},stop:function(){g.$(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);j.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a===this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a===this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},
35
+ loadUrl:function(a){var b=this.fragment=this.getFragment(a);return e.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!j.started)return!1;if(!b||!0===b)b={trigger:b};a=this.getFragment(a||"");if(this.fragment!==a){this.fragment=a;var c=this.root+a;if(this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,c);else if(this._wantsHashChange)this._updateHash(this.location,a,b.replace),this.iframe&&a!==this.getFragment(this.getHash(this.iframe))&&
36
+ (b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,a,b.replace));else return this.location.assign(c);b.trigger&&this.loadUrl(a)}},_updateHash:function(a,b,c){c?(c=a.href.replace(/(javascript:|#).*$/,""),a.replace(c+"#"+b)):a.hash="#"+b}});g.history=new j;var x=g.View=function(a){this.cid=e.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},I=/^(\S+)\s*(.*)$/,J="model collection el id attributes className tagName events".split(" ");
37
+ e.extend(x.prototype,h,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},make:function(a,b,c){a=document.createElement(a);b&&g.$(a).attr(b);null!=c&&g.$(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof g.$?a:g.$(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=e.result(this,
38
+ "events"))){this.undelegateEvents();for(var b in a){var c=a[b];e.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(I),f=d[1],d=d[2],c=e.bind(c,this),f=f+(".delegateEvents"+this.cid);""===d?this.$el.bind(f,c):this.$el.delegate(d,f,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=e.extend({},e.result(this,"options"),a));e.extend(this,e.pick(a,J));this.options=a},_ensureElement:function(){if(this.el)this.setElement(e.result(this,
39
+ "el"),!1);else{var a=e.extend({},e.result(this,"attributes"));this.id&&(a.id=e.result(this,"id"));this.className&&(a["class"]=e.result(this,"className"));this.setElement(this.make(e.result(this,"tagName"),a),!1)}}});var K={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=K[a];e.defaults(c||(c={}),{emulateHTTP:g.emulateHTTP,emulateJSON:g.emulateJSON});var f={type:d,dataType:"json"};c.url||(f.url=e.result(b,"url")||u());if(null==c.data&&b&&("create"===
40
+ a||"update"===a||"patch"===a))f.contentType="application/json",f.data=JSON.stringify(c.attrs||b.toJSON(c));c.emulateJSON&&(f.contentType="application/x-www-form-urlencoded",f.data=f.data?{model:f.data}:{});if(c.emulateHTTP&&("PUT"===d||"DELETE"===d||"PATCH"===d)){f.type="POST";c.emulateJSON&&(f.data._method=d);var h=c.beforeSend;c.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d);if(h)return h.apply(this,arguments)}}"GET"!==f.type&&!c.emulateJSON&&(f.processData=!1);var j=c.success;
41
+ c.success=function(a,d,e){j&&j(a,d,e);b.trigger("sync",b,a,c)};var i=c.error;c.error=function(a){i&&i(b,a,c);b.trigger("error",b,a,c)};a=g.ajax(e.extend(f,c));b.trigger("request",b,a,c);return a};g.ajax=function(){return g.$.ajax.apply(g.$,arguments)};o.extend=p.extend=v.extend=x.extend=j.extend=function(a,b){var c=this,d;d=a&&e.has(a,"constructor")?a.constructor:function(){c.apply(this,arguments)};e.extend(d,c,b);var f=function(){this.constructor=d};f.prototype=c.prototype;d.prototype=new f;a&&e.extend(d.prototype,
42
+ a);d.__super__=c.prototype;return d};var u=function(){throw Error('A "url" property or function must be specified');}}).call(this);
@@ -1 +1 @@
1
- ((function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o=Array.prototype.indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};h=function(a){var b,c,d,e,f,g,i;i=[];for(b in a){e=a[b],c={key:b};if(_.isRegExp(e))c.type="$regex",c.value=e;else if(_(e).isObject()&&!_(e).isArray())for(f in e){g=e[f];if(n(f,g)){c.type=f;switch(f){case"$elemMatch":case"$relationMatch":c.value=h(g);break;case"$computed":d={},d[b]=g,c.value=h(d);break;default:c.value=g}}}else c.type="$equal",c.value=e;c.type==="$equal"&&_(c.value).isObject()&&(c.type="$oEqual"),i.push(c)}return i},n=function(a,b){switch(a){case"$in":case"$nin":case"$all":case"$any":return _(b).isArray();case"$size":return _(b).isNumber();case"$regex":return _(b).isRegExp();case"$like":case"$likeI":return _(b).isString();case"$between":return _(b).isArray()&&b.length===2;case"$cb":return _(b).isFunction();default:return!0}},m=function(a,b){switch(a){case"$like":case"$likeI":case"$regex":return _(b).isString();case"$contains":case"$all":case"$any":case"$elemMatch":return _(b).isArray();case"$size":return _(b).isArray()||_(b).isString();case"$in":case"$nin":return b!=null;case"$relationMatch":return b!=null&&b.models;default:return!0}},i=function(b,c,d,e,g){switch(b){case"$equal":return _(d).isArray()?o.call(d,c)>=0:d===c;case"$oEqual":return _(d).isEqual(c);case"$contains":return o.call(d,c)>=0;case"$ne":return d!==c;case"$lt":return d<c;case"$gt":return d>c;case"$lte":return d<=c;case"$gte":return d>=c;case"$between":return c[0]<d&&d<c[1];case"$in":return o.call(c,d)>=0;case"$nin":return o.call(c,d)<0;case"$all":return _(c).all(function(a){return o.call(d,a)>=0});case"$any":return _(d).any(function(a){return o.call(c,a)>=0});case"$size":return d.length===c;case"$exists":case"$has":return d!=null===c;case"$like":return d.indexOf(c)!==-1;case"$likeI":return d.toLowerCase().indexOf(c.toLowerCase())!==-1;case"$regex":return c.test(d);case"$cb":return c.call(e,d);case"$elemMatch":return f(d,c,!1,a,"elemMatch");case"$relationMatch":return f(d.models,c,!1,a,"relationMatch");case"$computed":return f([e],c,!1,a,"computed");default:return!1}},f=function(a,b,c,d,e){var f;return e==null&&(e=!1),f=e?b:h(b),d(a,function(a){var b,d,g,h,j;for(h=0,j=f.length;h<j;h++){d=f[h],b=function(){switch(e){case"elemMatch":return a[d.key];case"computed":return a[d.key]();default:return a.get(d.key)}}(),g=m(d.type,b),g&&(g=i(d.type,d.value,b,a,d.key));if(c===g)return c}return!c})},b=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)&&f.push(c);return f},k=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)||f.push(c);return f},a=function(a,b){var c,d,e;for(d=0,e=a.length;d<e;d++){c=a[d];if(b(c))return!0}return!1},j={$and:function(a,c){return f(a,c,!1,b)},$or:function(a,c){return f(a,c,!0,b)},$nor:function(a,b){return f(a,b,!0,k)},$not:function(a,b){return f(a,b,!1,k)}},c=function(a,b,c){var d,f,g,h;return g=JSON.stringify(b),d=(h=a._query_cache)!=null?h:a._query_cache={},f=d[g],f||(f=e(a,b,c),d[g]=f),f},d=function(a,b){var c,d,e;return c=_.intersection(["$and","$not","$or","$nor"],_(b).keys()),d=a.models,c.length===0?j.$and(d,b):(e=function(a,c){return j[c](a,b[c])},_.reduce(c,e,d))},e=function(a,b,c){var e;return e=d(a,b),c.sortBy&&(e=l(e,c)),e},l=function(a,b){return _(b.sortBy).isString()?a=_(a).sortBy(function(a){return a.get(b.sortBy)}):_(b.sortBy).isFunction()&&(a=_(a).sortBy(b.sortBy)),b.order==="desc"&&(a=a.reverse()),a},g=function(a,b){var c,d,e,f;return b.offset?e=b.offset:b.page?e=(b.page-1)*b.limit:e=0,c=e+b.limit,d=a.slice(e,c),b.pager&&_.isFunction(b.pager)&&(f=Math.ceil(a.length/b.limit),b.pager(f,d)),d};if(typeof require!="undefined"){if(typeof _=="undefined"||_===null)_=require("underscore");if(typeof Backbone=="undefined"||Backbone===null)Backbone=require("backbone")}Backbone.QueryCollection=Backbone.Collection.extend({query:function(a,b){var d;return b==null&&(b={}),b.cache?d=c(this,a,b):d=e(this,a,b),b.limit&&(d=g(d,b)),d},where:function(a,b){return b==null&&(b={}),new this.constructor(this.query(a,b))},reset_query_cache:function(){return this._query_cache={}}}),typeof exports!="undefined"&&(exports.QueryCollection=Backbone.QueryCollection)})).call(this)
1
+ var __slice=[].slice,__hasProp={}.hasOwnProperty,__indexOf=[].indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};((function(a){return a("backbone-query",function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;return u=a("underscore"),c=a("backbone"),e=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)&&f.push(c);return f},p=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)||f.push(c);return f},d=function(a,b){var c,d,e;for(d=0,e=a.length;d<e;d++){c=a[d];if(b(c))return!0}return!1},j=function(){var a,b,c,d,e;a=1<=arguments.length?__slice.call(arguments,0):[],d={},b=d;while(a.length)c=a.shift(),e=a.length===1?a.shift():{},b=b[c]=e;return d},h=function(a){return u.isRegExp(a)?"$regex":u.isDate(a)?"$date":u.isObject(a)&&!u.isArray(a)?"object":u.isArray(a)?"array":u.isString(a)?"string":u.isNumber(a)?"number":u.isBoolean(a)?"boolean":u.isFunction(a)?"function":!1},m=function(a){var b,c,d,e,f,g,i,k,n,o,p,q,r;u.isArray(a)?g=a:g=function(){var c;c=[];for(b in a){if(!__hasProp.call(a,b))continue;n=a[b],c.push(j(b,n))}return c}(),r=[];for(p=0,q=g.length;p<q;p++){f=g[p];for(b in f){if(!__hasProp.call(f,b))continue;i=f[b],c={key:b},d=h(i);switch(d){case"$regex":case"$date":c.type=d,c.value=i;break;case"object":if(b==="$and"||b==="$or"||b==="$nor"||b==="$not")c.value=m(i),c.type=b,c.key=null;else for(k in i){o=i[k];if(t(k,o)){c.type=k;switch(k){case"$elemMatch":case"$relationMatch":c.value=l(o);break;case"$computed":e=j(b,o),c.value=m(e);break;default:c.value=o}}}break;default:c.type="$equal",c.value=i}c.type==="$equal"&&(d==="object"||d==="array")&&(c.type="$oEqual")}r.push(c)}return r},t=function(a,b){switch(a){case"$in":case"$nin":case"$all":case"$any":return u(b).isArray();case"$size":return u(b).isNumber();case"$regex":return u(b).isRegExp();case"$like":case"$likeI":return u(b).isString();case"$between":return u(b).isArray()&&b.length===2;case"$cb":return u(b).isFunction();default:return!0}},s=function(a,b){switch(a){case"$like":case"$likeI":case"$regex":return u(b).isString();case"$contains":case"$all":case"$any":case"$elemMatch":return u(b).isArray();case"$size":return u(b).isArray()||u(b).isString();case"$in":case"$nin":return b!=null;case"$relationMatch":return b!=null&&b.models;default:return!0}},n=function(a,b,c,e,f){switch(a){case"$equal":return u(c).isArray()?__indexOf.call(c,b)>=0:c===b;case"$oEqual":return u(c).isEqual(b);case"$contains":return __indexOf.call(c,b)>=0;case"$ne":return c!==b;case"$lt":return c<b;case"$gt":return c>b;case"$lte":return c<=b;case"$gte":return c>=b;case"$between":return b[0]<c&&c<b[1];case"$in":return __indexOf.call(b,c)>=0;case"$nin":return __indexOf.call(b,c)<0;case"$all":return u(b).all(function(a){return __indexOf.call(c,a)>=0});case"$any":return u(c).any(function(a){return __indexOf.call(b,a)>=0});case"$size":return c.length===b;case"$exists":case"$has":return c!=null===b;case"$like":return c.indexOf(b)!==-1;case"$likeI":return c.toLowerCase().indexOf(b.toLowerCase())!==-1;case"$regex":return b.test(c);case"$cb":return b.call(e,c);case"$elemMatch":return q(c,b,"elemMatch").length>0;case"$relationMatch":return q(c.models,b,"relationMatch").length>0;case"$computed":return i([e],b,!1,d,"computed");case"$and":case"$or":case"$nor":case"$not":return o[a]([e],b).length===1;default:return!1}},i=function(a,b,c,d,e){return e==null&&(e=!1),d(a,function(a){var d,f,g,h,i;for(h=0,i=b.length;h<i;h++){f=b[h],d=function(){switch(e){case"elemMatch":return a[f.key];case"computed":return a[f.key]();default:return a.get(f.key)}}(),g=s(f.type,d),g&&(g=n(f.type,f.value,d,a,f.key));if(c===g)return c}return!c})},o={$and:function(a,b,c){return i(a,b,!1,e,c)},$or:function(a,b,c){return i(a,b,!0,e,c)},$nor:function(a,b,c){return i(a,b,!0,p,c)},$not:function(a,b,c){return i(a,b,!1,p,c)}},l=function(a){var b,c,d,e,f,g;e=u(a).keys(),b=["$and","$not","$or","$nor"],c=u.intersection(b,e);if(c.length===0)return[{type:"$and",parsedQuery:m(a)}];if(c.length!==e.length){__indexOf.call(c,"$and")<0&&(a.$and={},c.unshift("$and"));for(d in a){if(!__hasProp.call(a,d))continue;g=a[d];if(__indexOf.call(b,d)<0)a.$and[d]=g,delete a[d];else continue}}return function(){var b,d,e;e=[];for(b=0,d=c.length;b<d;b++)f=c[b],e.push({type:f,parsedQuery:m(a[f])});return e}()},q=function(a,b,c){var d;return c||(b=l(b)),d=function(a,b){return o[b.type](a,b.parsedQuery,c)},u.reduce(b,d,a)},f=function(a,b,c){var d,e,f,h;return f=JSON.stringify(b),d=(h=a._queryCache)!=null?h:a._queryCache={},e=d[f],e||(e=g(a,b,c),d[f]=e),e},g=function(a,b,c){var d;return d=q(a.models,b),c.sortBy&&(d=r(d,c)),d},r=function(a,b){return u(b.sortBy).isString()?a=u(a).sortBy(function(a){return a.get(b.sortBy)}):u(b.sortBy).isFunction()&&(a=u(a).sortBy(b.sortBy)),b.order==="desc"&&(a=a.reverse()),a},k=function(a,b){var c,d,e,f;return b.offset?e=b.offset:b.page?e=(b.page-1)*b.limit:e=0,c=e+b.limit,d=a.slice(e,c),b.pager&&u.isFunction(b.pager)&&(f=Math.ceil(a.length/b.limit),b.pager(f,d)),d},c.QueryCollection=c.Collection.extend({query:function(a,b){var c;return b==null&&(b={}),b.cache?c=f(this,a,b):c=g(this,a,b),b.limit&&(c=k(c,b)),c},findOne:function(a){return this.query(a)[0]},whereBy:function(a,b){return b==null&&(b={}),new this.constructor(this.query(a,b))},resetQueryCache:function(){return this._queryCache={}}}),b.QueryCollection=c.QueryCollection})})).call(this,typeof define=="function"&&define.amd?define:function(a,b){typeof exports!="undefined"?b(function(a){return require(a)},exports):b(function(a){return this[a==="underscore"?"_":"Backbone"]},{})})
@@ -0,0 +1,707 @@
1
+ /*
2
+ * Copyright 2011 Twitter, Inc.
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+
17
+
18
+ var Hogan = {};
19
+
20
+ (function (Hogan, useArrayBuffer) {
21
+ Hogan.Template = function (codeObj, text, compiler, options) {
22
+ codeObj = codeObj || {};
23
+ this.r = codeObj.code || this.r;
24
+ this.c = compiler;
25
+ this.options = options;
26
+ this.text = text || '';
27
+ this.partials = codeObj.partials || {};
28
+ this.subs = codeObj.subs || {};
29
+ this.ib();
30
+ }
31
+
32
+ Hogan.Template.prototype = {
33
+ // render: replaced by generated code.
34
+ r: function (context, partials, indent) { return ''; },
35
+
36
+ // variable escaping
37
+ v: hoganEscape,
38
+
39
+ // triple stache
40
+ t: coerceToString,
41
+
42
+ render: function render(context, partials, indent) {
43
+ return this.ri([context], partials || {}, indent);
44
+ },
45
+
46
+ // render internal -- a hook for overrides that catches partials too
47
+ ri: function (context, partials, indent) {
48
+ return this.r(context, partials, indent);
49
+ },
50
+
51
+ // ensurePartial
52
+ ep: function(symbol, partials) {
53
+ var partial = this.partials[symbol];
54
+
55
+ // check to see that if we've instantiated this partial before
56
+ var template = partials[partial.name];
57
+ if (partial.instance && partial.base == template) {
58
+ return partial.instance;
59
+ }
60
+
61
+ if (typeof template == 'string') {
62
+ if (!this.c) {
63
+ throw new Error("No compiler available.");
64
+ }
65
+ template = this.c.compile(template, this.options);
66
+ }
67
+
68
+ if (!template) {
69
+ return null;
70
+ }
71
+
72
+ // We use this to check whether the partials dictionary has changed
73
+ this.partials[symbol].base = template;
74
+
75
+ if (partial.subs) {
76
+ template = createSpecializedPartial(template, partial.subs, partial.partials);
77
+ }
78
+
79
+ this.partials[symbol].instance = template;
80
+ return template;
81
+ },
82
+
83
+ // tries to find a partial in the curent scope and render it
84
+ rp: function(symbol, context, partials, indent) {
85
+ var partial = this.ep(symbol, partials);
86
+ if (!partial) {
87
+ return '';
88
+ }
89
+
90
+ return partial.ri(context, partials, indent);
91
+ },
92
+
93
+ // render a section
94
+ rs: function(context, partials, section) {
95
+ var tail = context[context.length - 1];
96
+
97
+ if (!isArray(tail)) {
98
+ section(context, partials, this);
99
+ return;
100
+ }
101
+
102
+ for (var i = 0; i < tail.length; i++) {
103
+ context.push(tail[i]);
104
+ section(context, partials, this);
105
+ context.pop();
106
+ }
107
+ },
108
+
109
+ // maybe start a section
110
+ s: function(val, ctx, partials, inverted, start, end, tags) {
111
+ var pass;
112
+
113
+ if (isArray(val) && val.length === 0) {
114
+ return false;
115
+ }
116
+
117
+ if (typeof val == 'function') {
118
+ val = this.ms(val, ctx, partials, inverted, start, end, tags);
119
+ }
120
+
121
+ pass = (val === '') || !!val;
122
+
123
+ if (!inverted && pass && ctx) {
124
+ ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
125
+ }
126
+
127
+ return pass;
128
+ },
129
+
130
+ // find values with dotted names
131
+ d: function(key, ctx, partials, returnFound) {
132
+ var names = key.split('.'),
133
+ val = this.f(names[0], ctx, partials, returnFound),
134
+ cx = null;
135
+
136
+ if (key === '.' && isArray(ctx[ctx.length - 2])) {
137
+ return ctx[ctx.length - 1];
138
+ }
139
+
140
+ for (var i = 1; i < names.length; i++) {
141
+ if (val && typeof val == 'object' && val[names[i]] != null) {
142
+ cx = val;
143
+ val = val[names[i]];
144
+ } else {
145
+ val = '';
146
+ }
147
+ }
148
+
149
+ if (returnFound && !val) {
150
+ return false;
151
+ }
152
+
153
+ if (!returnFound && typeof val == 'function') {
154
+ ctx.push(cx);
155
+ val = this.mv(val, ctx, partials);
156
+ ctx.pop();
157
+ }
158
+
159
+ return val;
160
+ },
161
+
162
+ // find values with normal names
163
+ f: function(key, ctx, partials, returnFound) {
164
+ var val = false,
165
+ v = null,
166
+ found = false;
167
+
168
+ for (var i = ctx.length - 1; i >= 0; i--) {
169
+ v = ctx[i];
170
+ if (v && typeof v == 'object' && v[key] != null) {
171
+ val = v[key];
172
+ found = true;
173
+ break;
174
+ }
175
+ }
176
+
177
+ if (!found) {
178
+ return (returnFound) ? false : "";
179
+ }
180
+
181
+ if (!returnFound && typeof val == 'function') {
182
+ val = this.mv(val, ctx, partials);
183
+ }
184
+
185
+ return val;
186
+ },
187
+
188
+ // higher order templates
189
+ ls: function(func, cx, partials, text, tags) {
190
+ var oldTags = this.options.delimiters;
191
+
192
+ this.options.delimiters = tags;
193
+ this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials));
194
+ this.options.delimiters = oldTags;
195
+
196
+ return false;
197
+ },
198
+
199
+ // compile text
200
+ ct: function(text, cx, partials) {
201
+ if (this.options.disableLambda) {
202
+ throw new Error('Lambda features disabled.');
203
+ }
204
+ return this.c.compile(text, this.options).render(cx, partials);
205
+ },
206
+
207
+ // template result buffering
208
+ b: (useArrayBuffer) ? function(s) { this.buf.push(s); } :
209
+ function(s) { this.buf += s; },
210
+
211
+ fl: (useArrayBuffer) ? function() { var r = this.buf.join(''); this.buf = []; return r; } :
212
+ function() { var r = this.buf; this.buf = ''; return r; },
213
+ // init the buffer
214
+ ib: function () {
215
+ this.buf = (useArrayBuffer) ? [] : '';
216
+ },
217
+
218
+ // method replace section
219
+ ms: function(func, ctx, partials, inverted, start, end, tags) {
220
+ var cx = ctx[ctx.length - 1],
221
+ result = func.call(cx);
222
+
223
+ if (typeof result == 'function') {
224
+ if (inverted) {
225
+ return true;
226
+ } else {
227
+ return this.ls(result, cx, partials, this.text.substring(start, end), tags);
228
+ }
229
+ }
230
+
231
+ return result;
232
+ },
233
+
234
+ // method replace variable
235
+ mv: function(func, ctx, partials) {
236
+ var cx = ctx[ctx.length - 1];
237
+ var result = func.call(cx);
238
+
239
+ if (typeof result == 'function') {
240
+ return this.ct(coerceToString(result.call(cx)), cx, partials);
241
+ }
242
+
243
+ return result;
244
+ },
245
+
246
+ sub: function(name, context, partials, indent) {
247
+ var f = this.subs[name];
248
+ if (f) {
249
+ f(context, partials, this, indent);
250
+ }
251
+ }
252
+
253
+ };
254
+
255
+ function createSpecializedPartial(instance, subs, partials) {
256
+ function PartialTemplate() {};
257
+ PartialTemplate.prototype = instance;
258
+ function Substitutions() {};
259
+ Substitutions.prototype = instance.subs;
260
+ var key;
261
+ var partial = new PartialTemplate();
262
+ partial.subs = new Substitutions();
263
+ partial.ib();
264
+
265
+ for (key in subs) {
266
+ partial.subs[key] = subs[key];
267
+ }
268
+
269
+ for (key in partials) {
270
+ partial.partials[key] = partials[key];
271
+ }
272
+
273
+ return partial;
274
+ }
275
+
276
+ var rAmp = /&/g,
277
+ rLt = /</g,
278
+ rGt = />/g,
279
+ rApos =/\'/g,
280
+ rQuot = /\"/g,
281
+ hChars =/[&<>\"\']/;
282
+
283
+ function coerceToString(val) {
284
+ return String((val === null || val === undefined) ? '' : val);
285
+ }
286
+
287
+ function hoganEscape(str) {
288
+ str = coerceToString(str);
289
+ return hChars.test(str) ?
290
+ str
291
+ .replace(rAmp,'&amp;')
292
+ .replace(rLt,'&lt;')
293
+ .replace(rGt,'&gt;')
294
+ .replace(rApos,'&#39;')
295
+ .replace(rQuot, '&quot;') :
296
+ str;
297
+ }
298
+
299
+ var isArray = Array.isArray || function(a) {
300
+ return Object.prototype.toString.call(a) === '[object Array]';
301
+ };
302
+
303
+ })(typeof exports !== 'undefined' ? exports : Hogan);
304
+
305
+
306
+
307
+ (function (Hogan) {
308
+ // Setup regex assignments
309
+ // remove whitespace according to Mustache spec
310
+ var rIsWhitespace = /\S/,
311
+ rQuot = /\"/g,
312
+ rNewline = /\n/g,
313
+ rCr = /\r/g,
314
+ rSlash = /\\/g;
315
+
316
+ Hogan.tags = {
317
+ '#': 1, '^': 2, '<': 3, '$': 4,
318
+ '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9,
319
+ '{': 10, '&': 11, '_t': 12
320
+ };
321
+
322
+ Hogan.scan = function scan(text, delimiters) {
323
+ var len = text.length,
324
+ IN_TEXT = 0,
325
+ IN_TAG_TYPE = 1,
326
+ IN_TAG = 2,
327
+ state = IN_TEXT,
328
+ tagType = null,
329
+ tag = null,
330
+ buf = '',
331
+ tokens = [],
332
+ seenTag = false,
333
+ i = 0,
334
+ lineStart = 0,
335
+ otag = '{{',
336
+ ctag = '}}';
337
+
338
+ function addBuf() {
339
+ if (buf.length > 0) {
340
+ tokens.push({tag: '_t', text: new String(buf)});
341
+ buf = '';
342
+ }
343
+ }
344
+
345
+ function lineIsWhitespace() {
346
+ var isAllWhitespace = true;
347
+ for (var j = lineStart; j < tokens.length; j++) {
348
+ isAllWhitespace =
349
+ (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) ||
350
+ (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null);
351
+ if (!isAllWhitespace) {
352
+ return false;
353
+ }
354
+ }
355
+
356
+ return isAllWhitespace;
357
+ }
358
+
359
+ function filterLine(haveSeenTag, noNewLine) {
360
+ addBuf();
361
+
362
+ if (haveSeenTag && lineIsWhitespace()) {
363
+ for (var j = lineStart, next; j < tokens.length; j++) {
364
+ if (tokens[j].text) {
365
+ if ((next = tokens[j+1]) && next.tag == '>') {
366
+ // set indent to token value
367
+ next.indent = tokens[j].text.toString()
368
+ }
369
+ tokens.splice(j, 1);
370
+ }
371
+ }
372
+ } else if (!noNewLine) {
373
+ tokens.push({tag:'\n'});
374
+ }
375
+
376
+ seenTag = false;
377
+ lineStart = tokens.length;
378
+ }
379
+
380
+ function changeDelimiters(text, index) {
381
+ var close = '=' + ctag,
382
+ closeIndex = text.indexOf(close, index),
383
+ delimiters = trim(
384
+ text.substring(text.indexOf('=', index) + 1, closeIndex)
385
+ ).split(' ');
386
+
387
+ otag = delimiters[0];
388
+ ctag = delimiters[1];
389
+
390
+ return closeIndex + close.length - 1;
391
+ }
392
+
393
+ if (delimiters) {
394
+ delimiters = delimiters.split(' ');
395
+ otag = delimiters[0];
396
+ ctag = delimiters[1];
397
+ }
398
+
399
+ for (i = 0; i < len; i++) {
400
+ if (state == IN_TEXT) {
401
+ if (tagChange(otag, text, i)) {
402
+ --i;
403
+ addBuf();
404
+ state = IN_TAG_TYPE;
405
+ } else {
406
+ if (text.charAt(i) == '\n') {
407
+ filterLine(seenTag);
408
+ } else {
409
+ buf += text.charAt(i);
410
+ }
411
+ }
412
+ } else if (state == IN_TAG_TYPE) {
413
+ i += otag.length - 1;
414
+ tag = Hogan.tags[text.charAt(i + 1)];
415
+ tagType = tag ? text.charAt(i + 1) : '_v';
416
+ if (tagType == '=') {
417
+ i = changeDelimiters(text, i);
418
+ state = IN_TEXT;
419
+ } else {
420
+ if (tag) {
421
+ i++;
422
+ }
423
+ state = IN_TAG;
424
+ }
425
+ seenTag = i;
426
+ } else {
427
+ if (tagChange(ctag, text, i)) {
428
+ tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
429
+ i: (tagType == '/') ? seenTag - otag.length : i + ctag.length});
430
+ buf = '';
431
+ i += ctag.length - 1;
432
+ state = IN_TEXT;
433
+ if (tagType == '{') {
434
+ if (ctag == '}}') {
435
+ i++;
436
+ } else {
437
+ cleanTripleStache(tokens[tokens.length - 1]);
438
+ }
439
+ }
440
+ } else {
441
+ buf += text.charAt(i);
442
+ }
443
+ }
444
+ }
445
+
446
+ filterLine(seenTag, true);
447
+
448
+ return tokens;
449
+ }
450
+
451
+ function cleanTripleStache(token) {
452
+ if (token.n.substr(token.n.length - 1) === '}') {
453
+ token.n = token.n.substring(0, token.n.length - 1);
454
+ }
455
+ }
456
+
457
+ function trim(s) {
458
+ if (s.trim) {
459
+ return s.trim();
460
+ }
461
+
462
+ return s.replace(/^\s*|\s*$/g, '');
463
+ }
464
+
465
+ function tagChange(tag, text, index) {
466
+ if (text.charAt(index) != tag.charAt(0)) {
467
+ return false;
468
+ }
469
+
470
+ for (var i = 1, l = tag.length; i < l; i++) {
471
+ if (text.charAt(index + i) != tag.charAt(i)) {
472
+ return false;
473
+ }
474
+ }
475
+
476
+ return true;
477
+ }
478
+
479
+ // the tags allowed inside super templates
480
+ var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true};
481
+
482
+ function buildTree(tokens, kind, stack, customTags) {
483
+ var instructions = [],
484
+ opener = null,
485
+ tail = null,
486
+ token = null;
487
+
488
+ tail = stack[stack.length - 1];
489
+
490
+ while (tokens.length > 0) {
491
+ token = tokens.shift();
492
+
493
+ if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) {
494
+ throw new Error('Illegal content in < super tag.');
495
+ }
496
+
497
+ if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) {
498
+ stack.push(token);
499
+ token.nodes = buildTree(tokens, token.tag, stack, customTags);
500
+ } else if (token.tag == '/') {
501
+ if (stack.length === 0) {
502
+ throw new Error('Closing tag without opener: /' + token.n);
503
+ }
504
+ opener = stack.pop();
505
+ if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
506
+ throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
507
+ }
508
+ opener.end = token.i;
509
+ return instructions;
510
+ } else if (token.tag == '\n') {
511
+ token.last = (tokens.length == 0) || (tokens[0].tag == '\n');
512
+ }
513
+
514
+ instructions.push(token);
515
+ }
516
+
517
+ if (stack.length > 0) {
518
+ throw new Error('missing closing tag: ' + stack.pop().n);
519
+ }
520
+
521
+ return instructions;
522
+ }
523
+
524
+ function isOpener(token, tags) {
525
+ for (var i = 0, l = tags.length; i < l; i++) {
526
+ if (tags[i].o == token.n) {
527
+ token.tag = '#';
528
+ return true;
529
+ }
530
+ }
531
+ }
532
+
533
+ function isCloser(close, open, tags) {
534
+ for (var i = 0, l = tags.length; i < l; i++) {
535
+ if (tags[i].c == close && tags[i].o == open) {
536
+ return true;
537
+ }
538
+ }
539
+ }
540
+
541
+ function stringifySubstitutions(obj) {
542
+ var items = [];
543
+ for (var key in obj) {
544
+ items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}');
545
+ }
546
+ return "{ " + items.join(",") + " }";
547
+ }
548
+
549
+ function stringifyPartials(codeObj) {
550
+ var partials = [];
551
+ for (var key in codeObj.partials) {
552
+ partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}");
553
+ }
554
+ return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs);
555
+ }
556
+
557
+ Hogan.stringify = function(codeObj, text, options) {
558
+ return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}";
559
+ }
560
+
561
+ var serialNo = 0;
562
+ Hogan.generate = function(tree, text, options) {
563
+ serialNo = 0;
564
+ var context = { code: '', subs: {}, partials: {} };
565
+ Hogan.walk(tree, context);
566
+
567
+ if (options.asString) {
568
+ return this.stringify(context, text, options);
569
+ }
570
+
571
+ return this.makeTemplate(context, text, options);
572
+ }
573
+
574
+ Hogan.wrapMain = function(code) {
575
+ return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();';
576
+ }
577
+
578
+ Hogan.template = Hogan.Template;
579
+
580
+ Hogan.makeTemplate = function(codeObj, text, options) {
581
+ var template = this.makePartials(codeObj);
582
+ template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code));
583
+ return new this.template(template, text, this, options);
584
+ }
585
+
586
+ Hogan.makePartials = function(codeObj) {
587
+ var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name};
588
+ for (key in template.partials) {
589
+ template.partials[key] = this.makePartials(template.partials[key]);
590
+ }
591
+ for (key in codeObj.subs) {
592
+ template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]);
593
+ }
594
+ return template;
595
+ }
596
+
597
+ function esc(s) {
598
+ return s.replace(rSlash, '\\\\')
599
+ .replace(rQuot, '\\\"')
600
+ .replace(rNewline, '\\n')
601
+ .replace(rCr, '\\r');
602
+ }
603
+
604
+ function chooseMethod(s) {
605
+ return (~s.indexOf('.')) ? 'd' : 'f';
606
+ }
607
+
608
+ function createPartial(node, context) {
609
+ var prefix = "<" + (context.prefix || "");
610
+ var sym = prefix + node.n + serialNo++;
611
+ context.partials[sym] = {name: node.n, partials: {}};
612
+ context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || '') + '"));';
613
+ return sym;
614
+ }
615
+
616
+ Hogan.codegen = {
617
+ '#': function(node, context) {
618
+ context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' +
619
+ 'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' +
620
+ 't.rs(c,p,' + 'function(c,p,t){';
621
+ Hogan.walk(node.nodes, context);
622
+ context.code += '});c.pop();}';
623
+ },
624
+
625
+ '^': function(node, context) {
626
+ context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){';
627
+ Hogan.walk(node.nodes, context);
628
+ context.code += '};';
629
+ },
630
+
631
+ '>': createPartial,
632
+ '<': function(node, context) {
633
+ var ctx = {partials: {}, code: '', subs: {}, inPartial: true};
634
+ Hogan.walk(node.nodes, ctx);
635
+ var template = context.partials[createPartial(node, context)];
636
+ template.subs = ctx.subs;
637
+ template.partials = ctx.partials;
638
+ },
639
+
640
+ '$': function(node, context) {
641
+ var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n};
642
+ Hogan.walk(node.nodes, ctx);
643
+ context.subs[node.n] = ctx.code;
644
+ if (!context.inPartial) {
645
+ context.code += 't.sub("' + esc(node.n) + '",c,p,i);';
646
+ }
647
+ },
648
+
649
+ '\n': function(node, context) {
650
+ context.code += write('"\\n"' + (node.last ? '' : ' + i'));
651
+ },
652
+
653
+ '_v': function(node, context) {
654
+ context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
655
+ },
656
+
657
+ '_t': function(node, context) {
658
+ context.code += write('"' + esc(node.text) + '"');
659
+ },
660
+
661
+ '{': tripleStache,
662
+
663
+ '&': tripleStache
664
+ }
665
+
666
+ function tripleStache(node, context) {
667
+ context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
668
+ }
669
+
670
+ function write(s) {
671
+ return 't.b(' + s + ');';
672
+ }
673
+
674
+ Hogan.walk = function (nodelist, context) {
675
+ var func;
676
+ for (var i = 0, l = nodelist.length; i < l; i++) {
677
+ func = Hogan.codegen[nodelist[i].tag];
678
+ func && func(nodelist[i], context);
679
+ }
680
+ return context;
681
+ }
682
+
683
+ Hogan.parse = function(tokens, text, options) {
684
+ options = options || {};
685
+ return buildTree(tokens, '', [], options.sectionTags || []);
686
+ },
687
+
688
+ Hogan.cache = {};
689
+
690
+ Hogan.cacheKey = function(text, options) {
691
+ return [text, !!options.asString, !!options.disableLambda].join('||');
692
+ },
693
+
694
+ Hogan.compile = function(text, options) {
695
+ options = options || {};
696
+ var key = Hogan.cacheKey(text, options);
697
+ var template = this.cache[key];
698
+
699
+ if (template) {
700
+ return template;
701
+ }
702
+
703
+ template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
704
+ return this.cache[key] = template;
705
+ };
706
+ })(typeof exports !== 'undefined' ? exports : Hogan);
707
+