lady_josephine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (304) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/fonts/lady_josephine/icons/icons.eot +0 -0
  5. data/app/assets/fonts/lady_josephine/icons/icons.svg +215 -0
  6. data/app/assets/fonts/lady_josephine/icons/icons.ttf +0 -0
  7. data/app/assets/fonts/lady_josephine/icons/icons.woff +0 -0
  8. data/app/assets/javascripts/lady_josephine/blocks/facebook.js +25 -0
  9. data/app/assets/javascripts/lady_josephine/blocks/instagram.js +22 -0
  10. data/app/assets/javascripts/lady_josephine/blocks/soundcloud.js +24 -0
  11. data/app/assets/javascripts/lady_josephine/blocks/twitter.js +25 -0
  12. data/app/assets/javascripts/lady_josephine/blocks/vimeo.js +55 -0
  13. data/app/assets/javascripts/lady_josephine/blocks/youtube.js +64 -0
  14. data/app/assets/javascripts/lady_josephine/editor.js +40 -0
  15. data/app/assets/javascripts/lady_josephine/lady_josephine.js +4 -0
  16. data/app/assets/javascripts/lady_josephine/lady_josephine_view.js +6 -0
  17. data/app/assets/stylesheets/lady_josephine/content.sass +33 -0
  18. data/app/assets/stylesheets/lady_josephine/icons.sass +175 -0
  19. data/app/assets/stylesheets/lady_josephine/lady_josephine.sass +6 -0
  20. data/app/assets/stylesheets/lady_josephine/sir_trevor.sass +619 -0
  21. data/app/assets/stylesheets/lady_josephine/vars.sass +36 -0
  22. data/app/controllers/lady_josephine/application_controller.rb +4 -0
  23. data/app/controllers/lady_josephine/editor_controller.rb +40 -0
  24. data/app/controllers/lady_josephine/images_controller.rb +26 -0
  25. data/app/helpers/lady_josephine/helper.rb +25 -0
  26. data/app/helpers/lady_josephine/sir_trevor_helper.rb +172 -0
  27. data/app/models/lady_josephine/concerns/model.rb +29 -0
  28. data/app/models/lady_josephine/concerns/pingable.rb +28 -0
  29. data/app/models/lady_josephine/concerns/server_uuid.rb +24 -0
  30. data/app/models/lady_josephine/concerns/sir_trevor_images.rb +38 -0
  31. data/app/models/lady_josephine/image.rb +41 -0
  32. data/app/uploader/lady_josephine/base_uploader.rb +47 -0
  33. data/app/uploader/lady_josephine/image_uploader.rb +149 -0
  34. data/app/views/lady_josephine/blocks/_audio_block.haml +2 -0
  35. data/app/views/lady_josephine/blocks/_definition_block.haml +4 -0
  36. data/app/views/lady_josephine/blocks/_divider_block.haml +2 -0
  37. data/app/views/lady_josephine/blocks/_extended_image_block.haml +63 -0
  38. data/app/views/lady_josephine/blocks/_extended_quote_block.haml +5 -0
  39. data/app/views/lady_josephine/blocks/_extended_tweet_block.haml +2 -0
  40. data/app/views/lady_josephine/blocks/_facebook_post_block.haml +2 -0
  41. data/app/views/lady_josephine/blocks/_heading_block.haml +2 -0
  42. data/app/views/lady_josephine/blocks/_html_block.haml +1 -0
  43. data/app/views/lady_josephine/blocks/_instagram_block.haml +2 -0
  44. data/app/views/lady_josephine/blocks/_list_block.haml +3 -0
  45. data/app/views/lady_josephine/blocks/_quote_block.haml +5 -0
  46. data/app/views/lady_josephine/blocks/_text_block.html.haml +2 -0
  47. data/app/views/lady_josephine/blocks/_video_block.haml +9 -0
  48. data/config/routes.rb +9 -0
  49. data/db/migrate/20160222151500_lady_josephine_image.rb +18 -0
  50. data/lib/generators/lady_josephine_migration/USAGE +9 -0
  51. data/lib/generators/lady_josephine_migration/lady_josephine_migration_generator.rb +17 -0
  52. data/lib/generators/lady_josephine_migration/templates/migration.rb +9 -0
  53. data/lib/lady_josephine.rb +18 -0
  54. data/lib/lady_josephine/engine.rb +18 -0
  55. data/lib/lady_josephine/redcarpet/custom_markdown_formatter.rb +63 -0
  56. data/lib/lady_josephine/renderer/sir_trevor_renderer.rb +16 -0
  57. data/lib/lady_josephine/version.rb +3 -0
  58. data/lib/lady_josephine/whitelist.rb +26 -0
  59. data/lib/tasks/lady_josephine_tasks.rake +4 -0
  60. data/spec/controllers/lady_josephine/editor_controller_spec.rb +58 -0
  61. data/spec/dummy/README.rdoc +28 -0
  62. data/spec/dummy/Rakefile +6 -0
  63. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  64. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  65. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  66. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  67. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  68. data/spec/dummy/bin/bundle +3 -0
  69. data/spec/dummy/bin/rails +4 -0
  70. data/spec/dummy/bin/rake +4 -0
  71. data/spec/dummy/bin/setup +29 -0
  72. data/spec/dummy/config.ru +4 -0
  73. data/spec/dummy/config/application.rb +26 -0
  74. data/spec/dummy/config/boot.rb +5 -0
  75. data/spec/dummy/config/database.yml +25 -0
  76. data/spec/dummy/config/environment.rb +5 -0
  77. data/spec/dummy/config/environments/development.rb +41 -0
  78. data/spec/dummy/config/environments/production.rb +79 -0
  79. data/spec/dummy/config/environments/test.rb +42 -0
  80. data/spec/dummy/config/initializers/assets.rb +11 -0
  81. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  82. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  83. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  84. data/spec/dummy/config/initializers/inflections.rb +16 -0
  85. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  86. data/spec/dummy/config/initializers/session_store.rb +3 -0
  87. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  88. data/spec/dummy/config/locales/en.yml +23 -0
  89. data/spec/dummy/config/routes.rb +4 -0
  90. data/spec/dummy/config/secrets.yml +22 -0
  91. data/spec/dummy/db/development.sqlite3 +0 -0
  92. data/spec/dummy/db/schema.rb +16 -0
  93. data/spec/dummy/db/test.sqlite3 +0 -0
  94. data/spec/dummy/log/bla +0 -0
  95. data/spec/dummy/public/404.html +67 -0
  96. data/spec/dummy/public/422.html +67 -0
  97. data/spec/dummy/public/500.html +66 -0
  98. data/spec/dummy/public/favicon.ico +0 -0
  99. data/spec/spec_helper.rb +17 -0
  100. data/vendor/assets/components/Eventable/README.md +12 -0
  101. data/vendor/assets/components/Eventable/bower.json +10 -0
  102. data/vendor/assets/components/Eventable/component.json +11 -0
  103. data/vendor/assets/components/Eventable/eventable.js +207 -0
  104. data/vendor/assets/components/Eventable/package.json +15 -0
  105. data/vendor/assets/components/jquery-autosize/bower.json +30 -0
  106. data/vendor/assets/components/jquery-autosize/demo.html +36 -0
  107. data/vendor/assets/components/jquery-autosize/jquery.autosize.js +273 -0
  108. data/vendor/assets/components/jquery-autosize/jquery.autosize.min.js +6 -0
  109. data/vendor/assets/components/jquery-autosize/package.json +32 -0
  110. data/vendor/assets/components/jquery-autosize/readme.md +216 -0
  111. data/vendor/assets/components/jquery/AUTHORS.txt +163 -0
  112. data/vendor/assets/components/jquery/CONTRIBUTING.md +216 -0
  113. data/vendor/assets/components/jquery/Gruntfile.js +496 -0
  114. data/vendor/assets/components/jquery/MIT-LICENSE.txt +21 -0
  115. data/vendor/assets/components/jquery/README.md +415 -0
  116. data/vendor/assets/components/jquery/build/release-notes.js +59 -0
  117. data/vendor/assets/components/jquery/build/release.js +246 -0
  118. data/vendor/assets/components/jquery/component.json +13 -0
  119. data/vendor/assets/components/jquery/composer.json +35 -0
  120. data/vendor/assets/components/jquery/jquery-migrate.js +496 -0
  121. data/vendor/assets/components/jquery/jquery-migrate.min.js +3 -0
  122. data/vendor/assets/components/jquery/jquery.js +9597 -0
  123. data/vendor/assets/components/jquery/jquery.min.js +5 -0
  124. data/vendor/assets/components/jquery/jquery.min.map +1 -0
  125. data/vendor/assets/components/jquery/package.json +39 -0
  126. data/vendor/assets/components/jquery/speed/benchmark.js +15 -0
  127. data/vendor/assets/components/jquery/speed/benchmarker.css +65 -0
  128. data/vendor/assets/components/jquery/speed/benchmarker.js +181 -0
  129. data/vendor/assets/components/jquery/speed/closest.html +39 -0
  130. data/vendor/assets/components/jquery/speed/css.html +82 -0
  131. data/vendor/assets/components/jquery/speed/event.html +58 -0
  132. data/vendor/assets/components/jquery/speed/filter.html +183 -0
  133. data/vendor/assets/components/jquery/speed/find.html +179 -0
  134. data/vendor/assets/components/jquery/speed/index.html +72 -0
  135. data/vendor/assets/components/jquery/speed/jquery-basis.js +6238 -0
  136. data/vendor/assets/components/jquery/speed/slice.vs.concat.html +47 -0
  137. data/vendor/assets/components/jquery/src/ajax.js +851 -0
  138. data/vendor/assets/components/jquery/src/ajax/jsonp.js +80 -0
  139. data/vendor/assets/components/jquery/src/ajax/script.js +86 -0
  140. data/vendor/assets/components/jquery/src/ajax/xhr.js +207 -0
  141. data/vendor/assets/components/jquery/src/attributes.js +661 -0
  142. data/vendor/assets/components/jquery/src/callbacks.js +196 -0
  143. data/vendor/assets/components/jquery/src/core.js +949 -0
  144. data/vendor/assets/components/jquery/src/css.js +679 -0
  145. data/vendor/assets/components/jquery/src/data.js +340 -0
  146. data/vendor/assets/components/jquery/src/deferred.js +141 -0
  147. data/vendor/assets/components/jquery/src/deprecated.js +4 -0
  148. data/vendor/assets/components/jquery/src/dimensions.js +41 -0
  149. data/vendor/assets/components/jquery/src/effects.js +730 -0
  150. data/vendor/assets/components/jquery/src/event-alias.js +15 -0
  151. data/vendor/assets/components/jquery/src/event.js +991 -0
  152. data/vendor/assets/components/jquery/src/exports.js +18 -0
  153. data/vendor/assets/components/jquery/src/intro.js +20 -0
  154. data/vendor/assets/components/jquery/src/manipulation.js +796 -0
  155. data/vendor/assets/components/jquery/src/offset.js +169 -0
  156. data/vendor/assets/components/jquery/src/outro.js +2 -0
  157. data/vendor/assets/components/jquery/src/queue.js +147 -0
  158. data/vendor/assets/components/jquery/src/serialize.js +99 -0
  159. data/vendor/assets/components/jquery/src/sizzle-jquery.js +9 -0
  160. data/vendor/assets/components/jquery/src/support.js +241 -0
  161. data/vendor/assets/components/jquery/src/traversing.js +275 -0
  162. data/vendor/assets/components/jquery/test/csp.php +16 -0
  163. data/vendor/assets/components/jquery/test/data/1x1.jpg +0 -0
  164. data/vendor/assets/components/jquery/test/data/ajax/unreleasedXHR.html +25 -0
  165. data/vendor/assets/components/jquery/test/data/atom+xml.php +4 -0
  166. data/vendor/assets/components/jquery/test/data/badcall.js +1 -0
  167. data/vendor/assets/components/jquery/test/data/badjson.js +1 -0
  168. data/vendor/assets/components/jquery/test/data/cleanScript.html +10 -0
  169. data/vendor/assets/components/jquery/test/data/core/cc_on.html +22 -0
  170. data/vendor/assets/components/jquery/test/data/dashboard.xml +11 -0
  171. data/vendor/assets/components/jquery/test/data/dimensions/documentLarge.html +17 -0
  172. data/vendor/assets/components/jquery/test/data/dimensions/documentSmall.html +21 -0
  173. data/vendor/assets/components/jquery/test/data/echoData.php +1 -0
  174. data/vendor/assets/components/jquery/test/data/echoQuery.php +1 -0
  175. data/vendor/assets/components/jquery/test/data/errorWithText.php +5 -0
  176. data/vendor/assets/components/jquery/test/data/etag.php +21 -0
  177. data/vendor/assets/components/jquery/test/data/evalScript.php +1 -0
  178. data/vendor/assets/components/jquery/test/data/event/longLoadScript.php +4 -0
  179. data/vendor/assets/components/jquery/test/data/event/promiseReady.html +17 -0
  180. data/vendor/assets/components/jquery/test/data/event/syncReady.html +23 -0
  181. data/vendor/assets/components/jquery/test/data/headers.php +18 -0
  182. data/vendor/assets/components/jquery/test/data/if_modified_since.php +20 -0
  183. data/vendor/assets/components/jquery/test/data/iframe.html +8 -0
  184. data/vendor/assets/components/jquery/test/data/jquery-1.8.2.ajax_xhr.min.js +2 -0
  185. data/vendor/assets/components/jquery/test/data/json.php +13 -0
  186. data/vendor/assets/components/jquery/test/data/json_obj.js +1 -0
  187. data/vendor/assets/components/jquery/test/data/jsonp.php +14 -0
  188. data/vendor/assets/components/jquery/test/data/manipulation/iframe-denied.html +36 -0
  189. data/vendor/assets/components/jquery/test/data/name.html +1 -0
  190. data/vendor/assets/components/jquery/test/data/name.php +24 -0
  191. data/vendor/assets/components/jquery/test/data/nocontent.php +5 -0
  192. data/vendor/assets/components/jquery/test/data/offset/absolute.html +41 -0
  193. data/vendor/assets/components/jquery/test/data/offset/body.html +26 -0
  194. data/vendor/assets/components/jquery/test/data/offset/fixed.html +34 -0
  195. data/vendor/assets/components/jquery/test/data/offset/relative.html +31 -0
  196. data/vendor/assets/components/jquery/test/data/offset/scroll.html +39 -0
  197. data/vendor/assets/components/jquery/test/data/offset/static.html +31 -0
  198. data/vendor/assets/components/jquery/test/data/offset/table.html +43 -0
  199. data/vendor/assets/components/jquery/test/data/params_html.php +12 -0
  200. data/vendor/assets/components/jquery/test/data/readywaitasset.js +1 -0
  201. data/vendor/assets/components/jquery/test/data/readywaitloader.js +25 -0
  202. data/vendor/assets/components/jquery/test/data/script.php +11 -0
  203. data/vendor/assets/components/jquery/test/data/selector/html5_selector.html +114 -0
  204. data/vendor/assets/components/jquery/test/data/selector/sizzle_cache.html +21 -0
  205. data/vendor/assets/components/jquery/test/data/statusText.php +5 -0
  206. data/vendor/assets/components/jquery/test/data/support/bodyBackground.html +28 -0
  207. data/vendor/assets/components/jquery/test/data/support/shrinkWrapBlocks.html +23 -0
  208. data/vendor/assets/components/jquery/test/data/support/testElementCrash.html +17 -0
  209. data/vendor/assets/components/jquery/test/data/test.html +7 -0
  210. data/vendor/assets/components/jquery/test/data/test.js +3 -0
  211. data/vendor/assets/components/jquery/test/data/test.php +7 -0
  212. data/vendor/assets/components/jquery/test/data/test2.html +5 -0
  213. data/vendor/assets/components/jquery/test/data/test3.html +3 -0
  214. data/vendor/assets/components/jquery/test/data/testinit.js +269 -0
  215. data/vendor/assets/components/jquery/test/data/testrunner.js +368 -0
  216. data/vendor/assets/components/jquery/test/data/testsuite.css +155 -0
  217. data/vendor/assets/components/jquery/test/data/text.php +12 -0
  218. data/vendor/assets/components/jquery/test/data/ua.txt +272 -0
  219. data/vendor/assets/components/jquery/test/data/with_fries.xml +25 -0
  220. data/vendor/assets/components/jquery/test/data/with_fries_over_jsonp.php +7 -0
  221. data/vendor/assets/components/jquery/test/delegatetest.html +228 -0
  222. data/vendor/assets/components/jquery/test/hovertest.html +158 -0
  223. data/vendor/assets/components/jquery/test/index.html +330 -0
  224. data/vendor/assets/components/jquery/test/localfile.html +75 -0
  225. data/vendor/assets/components/jquery/test/networkerror.html +84 -0
  226. data/vendor/assets/components/jquery/test/polluted.php +110 -0
  227. data/vendor/assets/components/jquery/test/readywait.html +70 -0
  228. data/vendor/assets/components/jquery/test/unit/ajax.js +1971 -0
  229. data/vendor/assets/components/jquery/test/unit/attributes.js +1332 -0
  230. data/vendor/assets/components/jquery/test/unit/callbacks.js +326 -0
  231. data/vendor/assets/components/jquery/test/unit/core.js +1332 -0
  232. data/vendor/assets/components/jquery/test/unit/css.js +1036 -0
  233. data/vendor/assets/components/jquery/test/unit/data.js +636 -0
  234. data/vendor/assets/components/jquery/test/unit/deferred.js +440 -0
  235. data/vendor/assets/components/jquery/test/unit/deprecated.js +1 -0
  236. data/vendor/assets/components/jquery/test/unit/dimensions.js +461 -0
  237. data/vendor/assets/components/jquery/test/unit/effects.js +2050 -0
  238. data/vendor/assets/components/jquery/test/unit/event.js +2690 -0
  239. data/vendor/assets/components/jquery/test/unit/exports.js +7 -0
  240. data/vendor/assets/components/jquery/test/unit/manipulation.js +2242 -0
  241. data/vendor/assets/components/jquery/test/unit/offset.js +549 -0
  242. data/vendor/assets/components/jquery/test/unit/queue.js +316 -0
  243. data/vendor/assets/components/jquery/test/unit/selector.js +185 -0
  244. data/vendor/assets/components/jquery/test/unit/serialize.js +146 -0
  245. data/vendor/assets/components/jquery/test/unit/support.js +384 -0
  246. data/vendor/assets/components/jquery/test/unit/traversing.js +667 -0
  247. data/vendor/assets/components/jquery/test/xhtml.php +5 -0
  248. data/vendor/assets/components/sir-trevor-js/CHANGELOG.md +44 -0
  249. data/vendor/assets/components/sir-trevor-js/Gemfile +3 -0
  250. data/vendor/assets/components/sir-trevor-js/Gemfile.lock +10 -0
  251. data/vendor/assets/components/sir-trevor-js/Gruntfile.js +109 -0
  252. data/vendor/assets/components/sir-trevor-js/MIT-LICENCE +20 -0
  253. data/vendor/assets/components/sir-trevor-js/Readme.md +84 -0
  254. data/vendor/assets/components/sir-trevor-js/bower.json +21 -0
  255. data/vendor/assets/components/sir-trevor-js/component.json +42 -0
  256. data/vendor/assets/components/sir-trevor-js/contributing.md +74 -0
  257. data/vendor/assets/components/sir-trevor-js/examples-component/component.json +14 -0
  258. data/vendor/assets/components/sir-trevor-js/examples-component/index.html +33 -0
  259. data/vendor/assets/components/sir-trevor-js/examples-component/index.js +29 -0
  260. data/vendor/assets/components/sir-trevor-js/examples-component/javascript/example_block.js +203 -0
  261. data/vendor/assets/components/sir-trevor-js/examples-component/javascript/limit_chars.js +46 -0
  262. data/vendor/assets/components/sir-trevor-js/examples-component/sir-trevor.gif +0 -0
  263. data/vendor/assets/components/sir-trevor-js/locales/cn.js +51 -0
  264. data/vendor/assets/components/sir-trevor-js/locales/de.js +51 -0
  265. data/vendor/assets/components/sir-trevor-js/locales/es.js +51 -0
  266. data/vendor/assets/components/sir-trevor-js/locales/fi.js +51 -0
  267. data/vendor/assets/components/sir-trevor-js/locales/fr.js +51 -0
  268. data/vendor/assets/components/sir-trevor-js/locales/pt.js +52 -0
  269. data/vendor/assets/components/sir-trevor-js/package.json +23 -0
  270. data/vendor/assets/components/sir-trevor-js/sir-trevor-icons.css +6 -0
  271. data/vendor/assets/components/sir-trevor-js/sir-trevor.css +393 -0
  272. data/vendor/assets/components/sir-trevor-js/sir-trevor.css.map +7 -0
  273. data/vendor/assets/components/sir-trevor-js/sir-trevor.js +5481 -0
  274. data/vendor/assets/components/sir-trevor-js/sir-trevor.min.js +13 -0
  275. data/vendor/assets/components/underscore/CNAME +1 -0
  276. data/vendor/assets/components/underscore/CONTRIBUTING.md +9 -0
  277. data/vendor/assets/components/underscore/LICENSE +22 -0
  278. data/vendor/assets/components/underscore/README.md +19 -0
  279. data/vendor/assets/components/underscore/Rakefile +10 -0
  280. data/vendor/assets/components/underscore/docs/docco.css +192 -0
  281. data/vendor/assets/components/underscore/docs/favicon.ico +0 -0
  282. data/vendor/assets/components/underscore/docs/images/background.png +0 -0
  283. data/vendor/assets/components/underscore/docs/images/underscore.png +0 -0
  284. data/vendor/assets/components/underscore/docs/underscore.html +823 -0
  285. data/vendor/assets/components/underscore/favicon.ico +0 -0
  286. data/vendor/assets/components/underscore/index.html +2467 -0
  287. data/vendor/assets/components/underscore/index.js +1 -0
  288. data/vendor/assets/components/underscore/package.json +16 -0
  289. data/vendor/assets/components/underscore/test/arrays.js +200 -0
  290. data/vendor/assets/components/underscore/test/chaining.js +59 -0
  291. data/vendor/assets/components/underscore/test/collections.js +453 -0
  292. data/vendor/assets/components/underscore/test/functions.js +265 -0
  293. data/vendor/assets/components/underscore/test/index.html +44 -0
  294. data/vendor/assets/components/underscore/test/objects.js +570 -0
  295. data/vendor/assets/components/underscore/test/speed.js +75 -0
  296. data/vendor/assets/components/underscore/test/utility.js +266 -0
  297. data/vendor/assets/components/underscore/test/vendor/jquery.js +9404 -0
  298. data/vendor/assets/components/underscore/test/vendor/jslitmus.js +670 -0
  299. data/vendor/assets/components/underscore/test/vendor/qunit.css +235 -0
  300. data/vendor/assets/components/underscore/test/vendor/qunit.js +1977 -0
  301. data/vendor/assets/components/underscore/test/vendor/runner.js +98 -0
  302. data/vendor/assets/components/underscore/underscore-min.js +1 -0
  303. data/vendor/assets/components/underscore/underscore.js +1226 -0
  304. metadata +473 -0
@@ -0,0 +1,13 @@
1
+ /*!
2
+ * Sir Trevor JS v0.3.2
3
+ *
4
+ * Released under the MIT license
5
+ * www.opensource.org/licenses/MIT
6
+ *
7
+ * 2016-02-09
8
+ */
9
+
10
+ !function($,_){function $element(el){return el instanceof $?el:$(el)}var SirTrevor,root=this;SirTrevor=root.SirTrevor={},SirTrevor.DEBUG=!1,SirTrevor.SKIP_VALIDATION=!1,SirTrevor.version="0.3.0",SirTrevor.LANGUAGE="de",SirTrevor.DEFAULTS={defaultType:!1,spinner:{className:"st-spinner",lines:9,length:8,width:3,radius:6,color:"#000",speed:1.4,trail:57,shadow:!1,left:"50%",top:"50%"},blockLimit:0,blockTypeLimits:{},required:[],uploadUrl:"/attachments",baseImageUrl:"/sir-trevor-uploads/",errorsContainer:void 0,toMarkdown:{aggresiveHTMLStrip:!1},escapeHTML:!1},SirTrevor.BlockMixins={},SirTrevor.Blocks={},SirTrevor.Formatters={},SirTrevor.instances=[],SirTrevor.Events=Eventable;var formBound=!1,FunctionBind={bound:[],_bindFunctions:function(){this.bound.length>0&&_.bindAll.apply(null,_.union([this],this.bound))}},Renderable={tagName:"div",className:"sir-trevor__view",attributes:{},$:function(selector){return this.$el.find(selector)},render:function(){return this},destroy:function(){_.isUndefined(this.stopListening)||this.stopListening(),this.$el.remove()},_ensureElement:function(){if(this.el)this._setElement(this.el);else{var html,attrs=_.extend({},_.result(this,"attributes"));this.id&&(attrs.id=this.id),this.className&&(attrs["class"]=this.className),attrs.html&&(html=attrs.html,delete attrs.html);var $el=$("<"+this.tagName+">").attr(attrs);html&&$el.html(html),this._setElement($el)}},_setElement:function(element){return this.$el=$element(element),this.el=this.$el[0],this}};!function($){function dragEnter(e){e.preventDefault()}function dragOver(e){e.originalEvent.dataTransfer.dropEffect="copy",$(e.currentTarget).addClass("st-drag-over"),e.preventDefault()}function dragLeave(e){$(e.currentTarget).removeClass("st-drag-over"),e.preventDefault()}function setCaret(collapseToStart){return function(){var range,selection;return range=document.createRange(),range.selectNodeContents(this[0]),range.collapse(collapseToStart),selection=window.getSelection(),selection.removeAllRanges(),selection.addRange(range),this}}$.fn.dropArea=function(){return this.bind("dragenter",dragEnter).bind("dragover",dragOver).bind("dragleave",dragLeave),this},$.fn.noDropArea=function(){return this.unbind("dragenter").unbind("dragover").unbind("dragleave"),this},$.fn.caretToEnd=setCaret(!1),$.fn.caretToStart=setCaret(!0)}(jQuery);var extend=function(protoProps,staticProps){var child,parent=this;child=protoProps&&_.has(protoProps,"constructor")?protoProps.constructor:function(){return parent.apply(this,arguments)},_.extend(child,parent,staticProps);var Surrogate=function(){this.constructor=child};return Surrogate.prototype=parent.prototype,child.prototype=new Surrogate,protoProps&&_.extend(child.prototype,protoProps),child.__super__=parent.prototype,child};SirTrevor.log=function(message){!_.isUndefined(console)&&SirTrevor.DEBUG&&console.log(message)},SirTrevor.generateUUID=function(){return"aaaaaaaa-aaaa-4aaa-baaa-aaaaaaaaaaaa".replace(/[ab]/g,function(c){var random=16*Math.random()%16|0;return"b"===c&&(random=7&random|8),random.toString(16)})},SirTrevor.Locales={en:{general:{add:"Add Content",deleteElement:"Delete Element","delete":"Delete?",drop:"Drag __block__ here",paste:"Or paste URL here",upload:"…or choose a file",close:"close",position:"Change position",wait:"Please wait…",link:"Enter a link",note:"Note",style:"Style",source:"Source"},errors:{title:"You have the following errors:",validation_fail:"__type__ block is invalid",block_empty:"__name__ must not be empty",type_missing:"You must have a block of type __type__",required_type_empty:"A required block type __type__ is empty",load_fail:"There was a problem loading the contents of the document"},autosave:{longExplanation:"This article was loaded from your browsers cache. It was changed locally and not saved on the server. You can keep the changes by saving or discard them.",discard:"Discard changes"},blocks:{text:{title:"Text"},list:{title:"List"},quote:{title:"Cite",credit_field:"Credit"},extended_quote:{title:"Extended Cite",credit_field:"Credit"},extended_image:{title:"Image",caption_field:"Caption",caption_placeholder:"Caption",target_url_field:"Link target URL",target_url_placeholder:"Link target URL",copyright_field:"Copyright",copyright_placeholder:"Copyright",upload_error:"There was a problem with your upload",fullwidth:"Page width",bodywidth:"Article width","default":"Small"},image:{title:"Image",upload_error:"There was a problem with your upload"},definition:{title:"Glossary",term:"Term",description:"Description"},divider:{title:"Divider"},reward_list:{title:"Reward List"},audio:{title:"Audio"},infographic:{title:"Infographic"},video:{title:"Video"},facebookpost:{title:"Facebook Post"},tweet:{title:"Tweet",fetch_error:"There was a problem fetching your tweet"},embedly:{title:"Embedly",fetch_error:"There was a problem fetching your embed",key_missing:"An Embedly API key must be present"},heading:{title:"Heading"},remote_list:{fetch_error:"There was a problem fetching the list!",maximumselected:"You can not select any more items!"},html:{title:"Html"},instagram:{title:"Instagram"}}},de:{general:{add:"Absatz hinzufügen",deleteElement:"Absatz löschen","delete":"Löschen?",drop:"__block__ hierher bewegen",paste:"Oder URL hier einfügen",upload:"…oder Datei auswählen",close:"Schließen",position:"Absatz verschieben",wait:"Bitte warten…",link:"Link eingeben",note:"Anmerkung",style:"Darstellung",source:"Quelle"},errors:{title:"Folgende Fehler sind aufgetreten:",validation_fail:"__type__ Block ist nicht gültig",block_empty:"__name__ darf nicht leer sein",type_missing:"Es wird ein Block vom Typ __type__ benötigt",required_type_empty:"Ein benötigter Block vom Typ __type__ ist leer",load_fail:"Es gab ein Problem beim Laden der Daten für dieses Dokument"},autosave:{longExplanation:"Dieser Artikel wurde aus dem Zwischenspeicher dieses Browsers geladen. Er wurde zuvor geändert und nicht auf dem Server gesichert. Du kannst die Änderungen beibehalten indem du speicherst oder die Änderungen verwerfen.",discard:"Verwerfen"},blocks:{text:{title:"Lauftext"},list:{title:"Liste"},quote:{title:"Zitat",credit_field:"Quelle"},extended_quote:{title:"Erweitertes Zitat",credit_field:"Quelle"},extended_image:{title:"Bild",caption_field:"Bildunterzeile",caption_placeholder:"Bildunterzeile",target_url_field:"URL für das Linkziel",target_url_placeholder:"URL für das Linkziel",copyright_field:"Fotograf",copyright_placeholder:"Fotograf",upload_error:"es gab ein problem beim hochladen",fullwidth:"Seitenbreite",bodywidth:"Artikelbreite","default":"Kleine"},image:{title:"Bild",upload_error:"es gab ein problem beim hochladen"},definition:{title:"Glossar",term:"Begriff",description:"Beschreibung"},divider:{title:"Trenner"},reward_list:{title:"Prämienliste"},audio:{title:"Audio"},infographic:{title:"Infografik"},video:{title:"Video"},facebookpost:{title:"Facebook Post"},tweet:{title:"Tweet",fetch_error:"There was a problem fetching your tweet"},embedly:{title:"Embedly",fetch_error:"There was a problem fetching your embed",key_missing:"An Embedly API key must be present"},heading:{title:"Überschrift"},remote_list:{fetch_error:"Liste konnte nicht geladen werden!",maximumselected:"Du kannst nicht mehr Elemente auswählen!"},html:{title:"Html"},instagram:{title:"Instagram"}}}},void 0===window.i18n||void 0===window.i18n.init?(SirTrevor.log("Using i18n stub"),window.i18n={t:function(key,options){var str,obj,part,i,parts=key.split(":");for(obj="undefined"!=typeof SirTrevorUserLanguage?SirTrevor.Locales[SirTrevorUserLanguage]||SirTrevor.Locales[SirTrevor.LANGUAGE]:SirTrevor.Locales[SirTrevor.LANGUAGE],i=0;i<parts.length;i++)part=parts[i],_.isUndefined(obj[part])||(obj=obj[part]);return str=obj,_.isString(str)?(str.indexOf("__")>=0&&_.each(options,function(value,opt){str=str.replace("__"+opt+"__",value)}),str):""}}):(SirTrevor.log("Using i18next"),i18n.init({resStore:SirTrevor.Locales,fallbackLng:SirTrevor.LANGUAGE,ns:{namespaces:["general","blocks"],defaultNs:"general"}})),function(a,b,c){function g(a,c){var e,d=b.createElement(a||"div");for(e in c)d[e]=c[e];return d}function h(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function j(a,b,c,d){var g=["opacity",b,~~(100*a),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";return e[g]||(i.insertRule("@"+l+"keyframes "+g+"{0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}100%{opacity:"+j+"}}",0),e[g]=1),g}function k(a,b){var f,g,e=a.style;if(e[b]!==c)return b;for(b=b.charAt(0).toUpperCase()+b.slice(1),g=0;g<d.length;g++)if(f=d[g]+b,e[f]!==c)return f}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function m(a){for(var b=1;b<arguments.length;b++){var d=arguments[b];for(var e in d)a[e]===c&&(a[e]=d[e])}return a}function n(a){for(var b={x:a.offsetLeft,y:a.offsetTop};a=a.offsetParent;)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}var f,d=["webkit","Moz","ms","O"],e={},i=function(){var a=g("style");return h(b.getElementsByTagName("head")[0],a),a.sheet||a.styleSheet}(),o={lines:12,length:7,width:5,radius:10,rotate:0,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto"},p=function q(a){return this.spin?void(this.opts=m(a||{},q.defaults,o)):new q(a)};p.defaults={},m(p.prototype,{spin:function(a){this.stop();var h,i,b=this,c=b.opts,d=b.el=l(g(0,{className:c.className}),{position:"relative",zIndex:c.zIndex}),e=c.radius+c.length+c.width;if(a&&(a.insertBefore(d,a.firstChild||null),i=n(a),h=n(d),l(d,{left:("auto"==c.left?i.x-h.x+(a.offsetWidth>>1):c.left+e)+"px",top:("auto"==c.top?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts),!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px,0)",borderRadius:(b.width>>1)+"px"})}for(var d,c=0;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:b.hwaccel?"translate3d(0,0,0)":"",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}}),!function(){function a(a,b){return g("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+-d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var j,d=c.length+c.width,e=2*d,g=2*-(c.width+c.length)+"px",i=l(f(),{position:"absolute",top:g,left:g});if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}):f=k(b,"animation")}(),a.Spinner=p}(window,document),SirTrevor.editorStore=function(editor,method,options){var resp;options=options||{},Version=function(version){var results;try{results=/(\d+)\.(\d+)/.exec(version),this.version=results[0],this.major=results[1],this.minor=results[2]}catch(e){results=/(\d+)/.exec(version),this.version=results[0],this.major=results[1],this.minor="0",this.recreateVersion()}return this},Version.prototype={minorVersion:function(){return parseInt(this.minor,10)},incrementMinorVersion:function(){return this.minor=(this.minorVersion()+1).toString(),this.recreateVersion()},majorVersion:function(){return parseInt(this.major,10)},incrementMajorVersion:function(){return this.major=(this.majorVersion()+1).toString(),this.minor="0",this.recreateVersion()},recreateVersion:function(){return this.version=this.major+"."+this.minor,this},gt:function(version){return this.majorVersion()>version.majorVersion()?!0:this.majorVersion()===version.majorVersion()&&this.minorVersion()>version.minorVersion()?!0:!1},toString:function(){return this.version}};var newVersion,reset=function(){var oldDataStore=editor.dataStore;editor.dataStore={data:[]},void 0!==oldDataStore&&(editor.dataStore.version=oldDataStore.version,editor.dataStore.uuid=oldDataStore.uuid,editor.dataStore.server_version=oldDataStore.server_version,editor.dataStore.server_uuid=oldDataStore.server_uuid),ensureMetadata()},ensureMetadata=function(){ensureUUID(),ensureVersion(),ensureModelName()},ensureModelName=function(){void 0===editor.dataStore.modelName&&(editor.dataStore.modelName=editor.options.modelName)},ensureUUID=function(){void 0===editor.dataStore.uuid&&(editor.dataStore.uuid=SirTrevor.generateUUID())},ensureVersion=function(){void 0===editor.dataStore.version&&(editor.dataStore.version="0.0")},isNewArticle=function(){var content=_.trim(editor.$el.val());return""===content||void 0===JSON.parse(content).server_uuid},getLatestUnsavedFromUUIDs=function(uuids){var name=editor.options.modelName,urlPrefix=editor.options.baseURL;return _.find(uuids,function(uuid){var result=$.ajax({type:"GET",url:urlPrefix+uuid+"/version",async:!1});return!(result.responseJSON&&result.responseJSON[name]&&result.responseJSON[name].server_version)})},parseKeyData=function(key){try{return JSON.parse(localStorage.getItem(key))}catch(e){return{}}},getAllKeys=function(prefix){return prefix=prefix||"st-",_.filter(Object.keys(localStorage),function(key){var modelName=parseKeyData(key).modelName||editor.options.modelName;return 0===key.lastIndexOf(prefix)&&modelName===editor.options.modelName})},getKeysWithoutServerUUID=function(){return _.filter(getAllKeys(),function(key){return void 0===parseKeyData(key).server_uuid}).map(getUUIDFromKey)},newestDocumentForUUID=function(uuid){if(editor.options.localStorage!==!0)return{};var i,prefix="st-"+uuid,versions=getAllKeys(prefix).map(function(e){return new Version(/version-(\d+(?:\.\d+)?)/.exec(e)[1])}),result=versions[0];for(i=0;i<versions.length;i++)versions[i].gt(result)&&(result=versions[i]);return void 0===result?null:{version:result.toString(),dataStore:localStorage[prefix+"-version-"+result.toString()]}},getUUIDFromKey=function(key){return/st-(.*)-version-(\d+(?:\.\d+)?)/.exec(key)[1]},getAllUUIDs=function(){return _.uniq(getAllKeys().map(getUUIDFromKey))},removeAllForUUID=function(uuid){for(var key,document,stop=!1;!stop&&(document=newestDocumentForUUID(uuid),null!==document);)key="st-"+uuid+"-version-"+document.version,stop=!localStorage.hasOwnProperty(key),localStorage.removeItem(key)},removeOldAutosaves=function(){var uuids=getAllUUIDs(),keysToKeep=uuids.map(function(uuid){return"st-"+uuid+"-version-"+newestDocumentForUUID(uuid).version});_.each(getAllKeys(),function(key){-1===$.inArray(key,keysToKeep)&&localStorage.removeItem(key)})},askUserForConfirmation=function(){return!0},promptRestoration=function(){var warn=$('<div class="st-autoload-info">'+i18n.t("autosave:longExplanation")+"<br></div>"),discard=$('<a href="#" class="st-autoload-discard-button">'+i18n.t("autosave:discard")+"</a>"),close=$('<a href="#" class="st-autoload-close-button"><span class="icon--close" aria-hidden="true"></span><span class="visuallyhidden>close</span></a>');warn.append(discard),warn.append(close),close.on("click",function(e){return e.preventDefault(),warn.remove(),!1}),discard.on("click",function(e){return e.preventDefault(),editor.store("restore"),warn.remove(),!1}),editor.$outer.prepend(warn)};switch(method){case"autosave":newVersion=new Version(editor.dataStore.version).incrementMinorVersion().toString(),editor.dataStore.version=newVersion;var store=editor.dataStore,value=store.data.length>0?JSON.stringify(editor.dataStore):"",key="st-"+store.uuid+"-version-"+store.version;window.localStorage.setItem(key,value),removeOldAutosaves();break;case"restore":removeAllForUUID(editor.dataStore.uuid),editor.reinitialize();break;case"create":var document,str,uuids,unsaved,parsedStore,documentVersion,dataStoreVersion,content=_.trim(editor.$el.val());reset();try{str=JSON.parse(content),_.isUndefined(str.data)||(editor.dataStore=str,ensureMetadata())}catch(e){}if(isNewArticle())uuids=getKeysWithoutServerUUID(),unsaved=getLatestUnsavedFromUUIDs(uuids),void 0!==unsaved&&(document=newestDocumentForUUID(unsaved),null!==document&&(parsedStore=JSON.parse(document.dataStore),documentVersion=new Version(parsedStore.version),dataStoreVersion=new Version(editor.dataStore.version),documentVersion.gt(dataStoreVersion)&&askUserForConfirmation()&&(editor.dataStore=JSON.parse(document.dataStore),promptRestoration())));else try{document=newestDocumentForUUID(editor.dataStore.uuid),null!==document&&(parsedStore=JSON.parse(document.dataStore),documentVersion=new Version(parsedStore.version),dataStoreVersion=new Version(editor.dataStore.version),documentVersion.gt(dataStoreVersion)&&askUserForConfirmation()&&-1===document.dataStore.indexOf(JSON.stringify(editor.dataStore.data))&&(editor.dataStore=JSON.parse(document.dataStore),promptRestoration()))}catch(e){editor.errors.push({text:i18n.t("errors:load_fail")}),editor.renderErrors(),SirTrevor.log("Sorry there has been a problem with parsing the JSON"),SirTrevor.log(e)}break;case"reset":reset();break;case"add":options.data&&(editor.dataStore.data.push(options.data),resp=editor.dataStore);break;case"save":editor.dataStore.version=new Version(editor.dataStore.version).incrementMajorVersion().toString(),editor.$el.val(editor.dataStore.data.length>0?JSON.stringify(editor.dataStore):"");break;case"read":resp=editor.dataStore}return resp?resp:void 0},SirTrevor.Submittable=function($form){this.$form=$form,this.intialize()},_.extend(SirTrevor.Submittable.prototype,{intialize:function(){this.$submitBtn=this.$form.find("input[type='submit']");var btnTitles=[];_.each(this.$submitBtn,function(btn){btnTitles.push($(btn).attr("value"))}),this.submitBtnTitles=btnTitles,this.canSubmit=!0,this.globalUploadCount=0,this._bindEvents()},setSubmitButton:function(e,message){this.$submitBtn.attr("value",message)},resetSubmitButton:function(){_.each(this.$submitBtn,function(item,index){$(item).attr("value",this.submitBtnTitles[index])},this)},onUploadStart:function(e){this.globalUploadCount++,SirTrevor.log("onUploadStart called "+this.globalUploadCount),1===this.globalUploadCount&&this._disableSubmitButton()},onUploadStop:function(e){this.globalUploadCount=this.globalUploadCount<=0?0:this.globalUploadCount-1,SirTrevor.log("onUploadStop called "+this.globalUploadCount),0===this.globalUploadCount&&this._enableSubmitButton()},onError:function(e){SirTrevor.log("onError called"),this.canSubmit=!1},_disableSubmitButton:function(message){this.setSubmitButton(null,message||i18n.t("general:wait")),this.$submitBtn.attr("disabled","disabled").addClass("disabled")},_enableSubmitButton:function(){this.resetSubmitButton(),this.$submitBtn.removeAttr("disabled").removeClass("disabled")},_events:{disableSubmitButton:"_disableSubmitButton",enableSubmitButton:"_enableSubmitButton",setSubmitButton:"setSubmitButton",resetSubmitButton:"resetSubmitButton",onError:"onError",onUploadStart:"onUploadStart",onUploadStop:"onUploadStop"},_bindEvents:function(){_.forEach(this._events,function(callback,type){SirTrevor.EventBus.on(type,this[callback],this)},this)}}),SirTrevor.fileUploader=function(block,file,success,error){var uid=[block.blockID,(new Date).getTime(),"raw"].join("-"),data=new FormData,blockData=block.getData(),instance=SirTrevor.getInstance(block.instanceID);data.append("attachment[name]",file.name),data.append("attachment[file]",file),data.append("attachment[uid]",uid),void 0!==blockData&&data.append("block-uuid",blockData.uuid),void 0!==instance.dataStore&&data.append("article-uuid",instance.dataStore.uuid),void 0!==instance.options&&(data.append("model-name",instance.options.modelName),data.append("column-name",instance.options.columnName)),block.resetMessages();var callbackSuccess=function(){SirTrevor.log("Upload callback called"),!_.isUndefined(success)&&_.isFunction(success)&&success.apply(block,arguments)},callbackError=function(){SirTrevor.log("Upload callback error called"),!_.isUndefined(error)&&_.isFunction(error)&&error.apply(block,arguments)},xhr=$.ajax({url:SirTrevor.DEFAULTS.uploadUrl,data:data,cache:!1,contentType:!1,processData:!1,dataType:"json",type:"POST"});return block.addQueuedItem(uid,xhr),xhr.done(callbackSuccess).fail(callbackError).always(_.bind(block.removeQueuedItem,block,uid)),xhr};var url_regex=/^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;_.mixin({isURI:function(string){return url_regex.test(string)},titleize:function(str){return null===str?"":(str=String(str).toLowerCase(),str.replace(/(?:^|\s|-)\S/g,function(c){return c.toUpperCase()}))},classify:function(str){return _.titleize(String(str).replace(/[\W_]/g," ")).replace(/\s/g,"")},classifyList:function(a){return _.map(a,function(i){return _.classify(i)})},capitalize:function(string){return string.charAt(0).toUpperCase()+string.substring(1).toLowerCase()},underscored:function(str){return _.trim(str).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},trim:function(string){return string.replace(/^\s\s*/,"").replace(/\s\s*$/,"")},reverse:function(str){return str.split("").reverse().join("")},flattern:function(obj){var x={};return _.each(obj,function(a,b){x[_.isArray(obj)?a:b]=!0}),x},to_slug:function(str){return str.toLowerCase().replace(/[^\w ]+/g,"").replace(/ +/g,"-")}}),SirTrevor.toHTML=function(markdown,type){type=_.classify(type);var html=markdown,shouldWrap="Text"===type,options=SirTrevor.getInstance().options;options&&options.escapeHTML&&(html=$("<div>").text(html).html().replace(/\&gt\;/g,">")),_.isUndefined(shouldWrap)&&(shouldWrap=!1),shouldWrap&&(html="<div>"+html),html=html.replace(/\[([^\]]+)\]\(([^\)]+)\)/gm,function(match,p1,p2){return"<a href='"+p2+"'>"+p1.replace(/\r?\n/g,"")+"</a>"}),html=_.reverse(_.reverse(html).replace(/_(?!\\)((_\\|[^_])*)_(?=$|[^\\])/gm,function(match,p1){return">i/<"+p1.replace(/\r?\n/g,"").replace(/[\s]+$/,"")+">i<"}).replace(/\*\*(?!\\)((\*\*\\|[^\*\*])*)\*\*(?=$|[^\\])/gm,function(match,p1){return">b/<"+p1.replace(/\r?\n/g,"").replace(/[\s]+$/,"")+">b<"})),html=html.replace(/^\> (.+)$/gm,"$1");var formatName,format;for(formatName in SirTrevor.Formatters)SirTrevor.Formatters.hasOwnProperty(formatName)&&(format=SirTrevor.Formatters[formatName],!_.isUndefined(format.toHTML)&&_.isFunction(format.toHTML)&&(html=format.toHTML(html)));var block;return SirTrevor.Blocks.hasOwnProperty(type)&&(block=SirTrevor.Blocks[type],!_.isUndefined(block.prototype.toHTML)&&_.isFunction(block.prototype.toHTML)&&(html=block.prototype.toHTML(html))),shouldWrap&&(html=html.replace(/\r?\n\r?\n/gm,"</div><div><br></div><div>"),html=html.replace(/\r?\n/gm,"</div><div>")),html=html.replace(/\t/g,"&nbsp;&nbsp;&nbsp;&nbsp;").replace(/\r?\n/g,"<br>").replace(/\*\*/,"").replace(/__/,""),html=html.replace(/\\\*/g,"*").replace(/\\\[/g,"[").replace(/\\\]/g,"]").replace(/\\\_/g,"_").replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\-/g,"-"),shouldWrap&&(html+="</div>"),html},SirTrevor.toMarkdown=function(content,type){function replaceBolds(match,p1,p2,p3){return _.isUndefined(p3)&&(p3=""),p1+"**"+p2.replace(/<(.)?br(.)?>/g,"")+"**"+p3}function replaceItalics(match,p1,p2,p3){return _.isUndefined(p3)&&(p3=""),p1+"_"+p2.replace(/<(.)?br(.)?>/g,"")+"_"+p3}function replaceHyperlinks(match,p1,p2,p3,p4){return p2+"["+p3.trim().replace(/<(.)?br(.)?>/g,"")+"]("+p1+")"+p4}type=_.classify(type);var markdown=content;markdown=markdown.replace(/&nbsp;/g," "),markdown=markdown.replace(/( class=(")?Mso[a-zA-Z]+(")?)/g,"").replace(/<!--(.*?)-->/g,"").replace(/\/\*(.*?)\*\//g,"").replace(/<(\/)*(meta|link|span|\\?xml:|st1:|o:|font)(.*?)>/gi,"");var tagStripper,i,badTags=["style","script","applet","embed","noframes","noscript"];for(i=0;i<badTags.length;i++)tagStripper=new RegExp("<"+badTags[i]+".*?"+badTags[i]+"(.*?)>","gi"),markdown=markdown.replace(tagStripper,"");markdown=markdown.replace(/\*/g,"\\*").replace(/\[/g,"\\[").replace(/\]/g,"\\]").replace(/\_/g,"\\_").replace(/\(/g,"\\(").replace(/\)/g,"\\)").replace(/\-/g,"\\-");var inlineTags=["em","i","strong","b"];for(i=0;i<inlineTags.length;i++)tagStripper=new RegExp("<"+inlineTags[i]+"><br></"+inlineTags[i]+">","gi"),markdown=markdown.replace(tagStripper,"<br>");markdown=markdown.replace(/<(\w+)(?:\s+\w+="[^"]+(?:"\$[^"]+"[^"]+)?")*>\s*<\/\1>/gim,"").replace(/\n/gm," ").replace(/<a.*?href=[""'](.*?)[""'].*?>(\s*)(.*?)(\s*)<\/a>/gim,replaceHyperlinks).replace(/<strong>(\s*)(.*?)(\s)*?<\/strong>/gim,replaceBolds).replace(/<b>(\s*)(.*?)(\s*)?<\/b>/gim,replaceBolds).replace(/<em>(\s*)(.*?)(\s*)?<\/em>/gim,replaceItalics).replace(/<i>(\s*)(.*?)(\s*)?<\/i>/gim,replaceItalics);var formatName,format;for(formatName in SirTrevor.Formatters)SirTrevor.Formatters.hasOwnProperty(formatName)&&(format=SirTrevor.Formatters[formatName],!_.isUndefined(format.toMarkdown)&&_.isFunction(format.toMarkdown)&&(markdown=format.toMarkdown(markdown)));markdown=markdown.replace(/([^<>]+)(<div>)/g,"$1\n$2").replace(/<div><div>/g,"\n<div>").replace(/(?:<div>)([^<>]+)(?:<div>)/g,"$1\n").replace(/(?:<div>)(?:<br>)?([^<>]+)(?:<br>)?(?:<\/div>)/g,"$1\n").replace(/<\/p>/g,"\n\n").replace(/<(.)?br(.)?>/g,"\n").replace(/&lt;/g,"<").replace(/&gt;/g,">");var block;return SirTrevor.Blocks.hasOwnProperty(type)&&(block=SirTrevor.Blocks[type],!_.isUndefined(block.prototype.toMarkdown)&&_.isFunction(block.prototype.toMarkdown)&&(markdown=block.prototype.toMarkdown(markdown))),markdown=SirTrevor.DEFAULTS.toMarkdown.aggresiveHTMLStrip?markdown.replace(/<\/?[^>]+(>|$)/g,""):markdown.replace(/<(?=\S)\/?[^>]+(>|$)/gi,"")},SirTrevor.EventBus=_.extend({},SirTrevor.Events),SirTrevor.BlockMixins.Ajaxable={mixinName:"Ajaxable",ajaxable:!0,initializeAjaxable:function(){this._queued=[]},addQueuedItem:function(name,deferred){SirTrevor.log("Adding queued item for "+this.blockID+" called "+name),SirTrevor.EventBus.trigger("onUploadStart",this.blockID),this._queued.push({name:name,deferred:deferred})},removeQueuedItem:function(name){SirTrevor.log("Removing queued item for "+this.blockID+" called "+name),SirTrevor.EventBus.trigger("onUploadStop",this.blockID),this._queued=_.reject(this._queued,function(queued){return queued.name==name})},hasItemsInQueue:function(){return this._queued.length>0},resolveAllInQueue:function(){_.each(this._queued,function(item){SirTrevor.log("Aborting queued request: "+item.name),item.deferred.abort()},this)}},SirTrevor.BlockMixins.Controllable={mixinName:"Controllable",initializeControllable:function(){SirTrevor.log("Adding controllable to block "+this.blockID),this.$control_ui=$("<div>",{"class":"st-block__control-ui"}),_.each(this.controls,function(handler,cmd){this.addUiControl(cmd,_.bind(handler,this))},this),this.$inner.append(this.$control_ui)},getControlTemplate:function(cmd){return $("<a>",{"data-icon":cmd,"class":"st-icon st-block-control-ui-btn st-block-control-ui-btn--"+cmd})},addUiControl:function(cmd,handler){this.$control_ui.append(this.getControlTemplate(cmd)),this.$control_ui.on("click",".st-block-control-ui-btn--"+cmd,handler)}},SirTrevor.BlockMixins.Droppable={mixinName:"Droppable",valid_drop_file_types:["File","Files","text/plain","text/uri-list"],initializeDroppable:function(){SirTrevor.log("Adding droppable to block "+this.blockID),this.drop_options=_.extend({},SirTrevor.DEFAULTS.Block.drop_options,this.drop_options);var drop_html=$(_.template(this.drop_options.html,{block:this}));this.$editor.hide(),this.$inputs.append(drop_html),this.$dropzone=drop_html,this.$dropzone.dropArea().bind("drop",_.bind(this._handleDrop,this)),this.$inner.addClass("st-block__inner--droppable")},_handleDrop:function(e){e.preventDefault(),e=e.originalEvent;var el=$(e.target),types=e.dataTransfer.types;el.removeClass("st-dropzone--dragover"),!_.isUndefined(types)&&_.some(types,function(type){return _.include(this.valid_drop_file_types,type)},this)&&this.onDrop(e.dataTransfer),SirTrevor.EventBus.trigger("block:content:dropped",this.blockID)}},SirTrevor.BlockMixins.Fetchable={mixinName:"Fetchable",initializeFetchable:function(){this.withMixin(SirTrevor.BlockMixins.Ajaxable)},fetch:function(options,success,failure){var uid=_.uniqueId(this.blockID+"_fetch"),xhr=$.ajax(options);return this.resetMessages(),this.addQueuedItem(uid,xhr),_.isUndefined(success)||xhr.done(_.bind(success,this)),_.isUndefined(failure)||xhr.fail(_.bind(failure,this)),xhr.always(_.bind(this.removeQueuedItem,this,uid)),xhr}},SirTrevor.BlockMixins.Pastable={mixinName:"Pastable",initializePastable:function(){SirTrevor.log("Adding pastable to block "+this.blockID),this.paste_options=_.extend({},SirTrevor.DEFAULTS.Block.paste_options,this.paste_options),this.$inputs.append(_.template(this.paste_options.html,this)),this.$(".st-paste-block").bind("click",function(){$(this).select()}).bind("paste",this._handleContentPaste).bind("submit",this._handleContentPaste)}},SirTrevor.BlockMixins.Uploadable={mixinName:"Uploadable",uploadsCount:0,initializeUploadable:function(){SirTrevor.log("Adding uploadable to block "+this.blockID),this.withMixin(SirTrevor.BlockMixins.Ajaxable),this.upload_options=_.extend({},SirTrevor.DEFAULTS.Block.upload_options,this.upload_options),this.$inputs.append(_.template(this.upload_options.html,this))},uploader:function(file,success,failure){return SirTrevor.fileUploader(this,file,success,failure)}},SirTrevor.BlockNotes=function(){var BlockNotes=function(block_element,instance_id,block){this.$block=block_element,this.instanceID=instance_id,this.block=block,this.changeable=block.changeable,this._ensureElement(),this._bindFunctions(),this.initialize()};return _.extend(BlockNotes.prototype,FunctionBind,Renderable,{bound:["toggle"],notesClassName:"st-block-is-note",className:"btn--editor-panel",visibleClass:"st-block-notes--is-visible",attributes:{html:'<span class="icon--note" aria-hidden="true"></span><span class="btn__label">'+i18n.t("general:note")+"</span>"},OFF_STATE:"no",ON_STATE:"yes",toggle:function(){var val=this.hiddenInput.val();return this.$block.toggleClass(this.notesClassName),this.hiddenInput.val(val===this.ON_STATE?this.OFF_STATE:this.ON_STATE)},instrumentBlock:function(){var data=this.block.getData();this.hiddenInput=$("<input class='st-input-string js-note-input' name='note' type='hidden' value='"+this.OFF_STATE+"'></input>"),this.block.$el.append(this.hiddenInput),data.note===this.ON_STATE&&this.toggle()},initialize:function(){this.instrumentBlock(),this.$el.on("click",this,this.toggle)}}),BlockNotes}(),SirTrevor.BlockReorder=function(){var BlockReorder=function(block_element,instance_id){this.$block=block_element,this.blockID=this.$block.attr("id"),this.instanceID=instance_id,this._ensureElement(),this._bindFunctions(),this.initialize()};return _.extend(BlockReorder.prototype,FunctionBind,Renderable,{bound:["onMouseDown","onClick","onDragStart","onDragEnd","onDrag","onDrop"],className:"btn--editor-panel btn--with-rocker",tagName:"div",attributes:function(){return{html:'<span class="btn--rocker"><button type="button" class="btn--rocker__up"><span class="icon--dropup"></span></button><button type="button" class="btn--rocker__down"><span class="icon--dropdown"></span></button></span><span class="btn__label">'+i18n.t("general:position")+"</span>",
11
+ draggable:"true"}},initialize:function(){this.$el.bind("mousedown touchstart",this.onMouseDown).bind("click",this.onClick).bind("dragstart",this.onDragStart).bind("dragend touchend",this.onDragEnd).bind("drag touchmove",this.onDrag),this.$block.dropArea().bind("drop",this.onDrop)},onMouseDown:function(){SirTrevor.EventBus.trigger("block:reorder:down",this.blockID)},onDrop:function(ev){ev.preventDefault();var dropped_on=this.$block,item_id=ev.originalEvent.dataTransfer.getData("text/plain"),block=$("#"+item_id);_.isUndefined(item_id)||_.isEmpty(block)||dropped_on.attr("id")==item_id||dropped_on.attr("data-instance")!=block.attr("data-instance")||dropped_on.after(block),SirTrevor.EventBus.trigger("block:reorder:dropped",item_id)},onDragStart:function(ev){var btn=$(ev.currentTarget).parent(),self=this,scrollTop=$("body").scrollTop(),position=this.$block.position();ev.originalEvent.dataTransfer.setDragImage(this.$block[0],btn.position().left,btn.position().top),ev.originalEvent.dataTransfer.setData("Text",this.blockID),window.setTimeout(function(){SirTrevor.EventBus.trigger("block:reorder:dragstart",self.blockID),self.$block.addClass("st-block--dragging"),$("body").scrollTop(scrollTop-position.top+self.$block.position().top)},0)},onDragEnd:function(ev){var scrollTop=$("body").scrollTop(),position=this.$block.position();SirTrevor.EventBus.trigger("block:reorder:dragend",this.blockID),this.$block.removeClass("st-block--dragging"),$("body").scrollTop(scrollTop-position.top+this.$block.position().top)},onDrag:function(ev){},onClick:function(event){var $target,idx;event.preventDefault(),$target=$(event.target).closest("button"),idx=this.$block.index(".st-block"),$target.hasClass("btn--rocker__up")?SirTrevor.EventBus.trigger(this.instanceID+":blocks:change_position",this.$block,idx,"before"):$target.hasClass("btn--rocker__down")&&SirTrevor.EventBus.trigger(this.instanceID+":blocks:change_position",this.$block,idx+2,"before")},render:function(){return this}}),BlockReorder}(),SirTrevor.BlockAdd=function(){var BlockAdd=function(block_element){this.$block=block_element,this._ensureElement(),this._bindFunctions(),this.initialize()};return _.extend(BlockAdd.prototype,FunctionBind,Renderable,SirTrevor.Events,{tagName:"a",className:"btn--editor-panel",attributes:{html:'<span class="icon--plus" aria-hidden="true"></span><span class="btn__label">'+i18n.t("general:add")+"</span>"},bound:["create"],create:function(e){SirTrevor.EventBus.trigger("showBlockControls",this.$block)},initialize:function(){this.$el.on("click",this,this.create)}}),BlockAdd}(),SirTrevor.BlockStyles=function(){var BlockStyles=function(block_element,instance_id,block){return block.styleable?(this.$block=block_element,this.instanceID=instance_id,this.block=block,this._ensureElement(),this._bindFunctions(),void this.initialize()):!1};return _.extend(BlockStyles.prototype,FunctionBind,Renderable,SirTrevor.Events,{tagName:"a",className:"btn--editor-panel",attributes:{html:' <span class="btn__label">'+i18n.t("general:style")+"</span>"},bound:["updateValue","onSelectChange"],create:function(e){SirTrevor.EventBus.trigger("showBlockControls",this.$block)},instrumentBlock:function(){var data=this.block.getData();this.hiddenInput=$("<input class='st-input-string js-style-input' name='style' type='hidden' value=''></input>"),this.block.$el.append(this.hiddenInput),this.$el.find("select").val(data.style),this.updateValue(data.style)},availableStyles:function(){return this.block.styles},updateValue:function(val){this.hiddenInput.val(val),this.updateClass(val)},updateClass:function(val){var styles=this.availableStyles(),$el=this.block.$el,classNames=styles.map(function(e){return e.className});$el.removeClass(classNames.join(" "));try{var targetClassName=styles.filter(function(e){return e.value===val}).pop().className;$el.addClass(targetClassName)}catch(e){console.log("Ignoring a style that seems obsolete in current configuration")}},onSelectChange:function(event){var value=event.target.value;this.updateValue(value)},initialize:function(){for(var styles=this.availableStyles(),select="<select>",i=0;i<styles.length;i++)select+='<option value="'+styles[i].value+'">'+styles[i].name+"</option>";select+="</select>",select=$(select),select.on("change",this.onSelectChange),this.$el.prepend(select),this.instrumentBlock()}}),BlockStyles}(),SirTrevor.BlockDeletion=function(){var BlockDeletion=function(){this._ensureElement(),this._bindFunctions()};return _.extend(BlockDeletion.prototype,FunctionBind,Renderable,{tagName:"a",className:"btn--editor-panel btn--editor-panel--delete",attributes:{html:'<span class="icon--bin" aria-hidden="true"></span><span class="btn__label">'+i18n.t("general:deleteElement")+"</span>"}}),BlockDeletion}();var bestNameFromField=function(field){var msg=field.attr("data-st-name")||field.attr("name");return msg||(msg="Field"),_.capitalize(msg)};SirTrevor.BlockValidations={errors:[],valid:function(){return this.performValidations(),0===this.errors.length},performValidations:function(){this.resetErrors();var required_fields=this.$(".st-required");_.each(required_fields,this.validateField,this),_.each(this.validations,this.runValidator,this),this.$el.toggleClass("st-block--with-errors",this.errors.length>0)},validations:[],validateField:function(field){field=$(field);var content=field.attr("contenteditable")?field.text():field.val();0===content.length&&this.setError(field,i18n.t("errors:block_empty",{name:bestNameFromField(field)}))},runValidator:function(validator){_.isUndefined(this[validator])||this[validator].call(this)},setError:function(field,reason){var $msg=this.addMessage(reason,"st-msg--error");field.addClass("st-error"),this.errors.push({field:field,reason:reason,msg:$msg})},resetErrors:function(){_.each(this.errors,function(error){error.field.removeClass("st-error"),error.msg.remove()}),this.$messages.removeClass("st-block__messages--is-visible"),this.errors=[]}},SirTrevor.BlockStore={blockStorage:{},createStore:function(blockData){this.blockStorage={type:_.underscored(this.type),data:blockData||{}}},save:function(){this.toData()},saveAndReturnData:function(){return this.save(),this.blockStorage},saveAndGetData:function(){var store=this.saveAndReturnData();return store.data||store},getData:function(){return this.blockStorage.data},setData:function(blockData){SirTrevor.log("Setting data for block "+this.blockID),_.extend(this.blockStorage.data,blockData||{})},setAndRetrieveData:function(blockData){return this.setData(blockData),this.getData()},setAndLoadData:function(blockData){this.setData(blockData),this.beforeLoadingData()},toData:function(){},loadData:function(){},beforeLoadingData:function(){SirTrevor.log("loadData for "+this.blockID),SirTrevor.EventBus.trigger("block:loadData",this.blockID),this.loadData(this.getData())},_loadData:function(){SirTrevor.log("_loadData is deprecated and will be removed in the future. Please use beforeLoadingData instead."),this.beforeLoadingData()},checkAndLoadData:function(){_.isEmpty(this.getData())||this.beforeLoadingData()}},SirTrevor.SimpleBlock=function(){var SimpleBlock=function(data,instance_id){this.createStore(data),this.blockID=_.uniqueId("st-block-"),this.instanceID=instance_id,this._ensureElement(),this._bindFunctions(),this.initialize.apply(this,arguments)};return _.extend(SimpleBlock.prototype,FunctionBind,SirTrevor.Events,Renderable,SirTrevor.BlockStore,{focus:function(){},valid:function(){return!0},className:"st-block",block_template:_.template("<div class='st-block__inner'><%= editor_html %></div>"),attributes:function(){return{id:this.blockID,"data-type":this.type,"data-instance":this.instanceID}},title:function(){return _.titleize(this.type.replace(/[\W_]/g," "))},blockCSSClass:function(){return this.blockCSSClass=_.to_slug(this.type),this.blockCSSClass},type:"","class":function(){return _.classify(this.type)},editorHTML:"",initialize:function(){},onBlockRender:function(){},beforeBlockRender:function(){},_setBlockInner:function(){var editor_html=_.result(this,"editorHTML");this.$el.append(this.block_template({editor_html:editor_html})),this.$inner=this.$el.find(".st-block__inner"),this.$inner.bind("click",function(e){e.stopPropagation()})},render:function(){return this.beforeBlockRender(),this._setBlockInner(),this._blockPrepare(),this},_blockPrepare:function(){this._initUI(),this._initMessages(),this.checkAndLoadData(),this._initUUID(),this.$el.addClass("st-item-ready"),this.on("onRender",this.onBlockRender),this.save()},_initUUID:function(){var uuid=this.getData().uuid||SirTrevor.generateUUID();this.$el.append($("<input class='st-input-string js-uuid-input' name='uuid' type='hidden' value='"+uuid+"'></input>"))},_withUIComponent:function(component,className,callback){this.$ui.append(component.render().$el),className&&callback&&this.$ui.on("click",className,callback)},_initUI:function(){var ui_element=$("<div>",{"class":"st-block__ui"});this.$inner.append(ui_element),this.$ui=ui_element,this._initUIComponents()},_initMessages:function(){var msgs_element=$("<div>",{"class":"st-block__messages"});this.$inner.prepend(msgs_element),this.$messages=msgs_element},addMessage:function(msg,additionalClass){var $msg=$("<span>",{html:msg,"class":"st-msg "+additionalClass});return this.$messages.append($msg).addClass("st-block__messages--is-visible"),$msg},resetMessages:function(){this.$messages.html("").removeClass("st-block__messages--is-visible")},_initUIComponents:function(){this._withUIComponent(new SirTrevor.BlockReorder(this.$el))}}),SimpleBlock.fn=SimpleBlock.prototype,SimpleBlock.extend=extend,SimpleBlock}(),SirTrevor.Block=function(){var Block=function(data,instance_id){SirTrevor.SimpleBlock.apply(this,arguments)},delete_template=["<div class='st-block__ui-delete-controls'>","<a class='btn--confirm-delete'><span class='icon--tick' aria-hidden='true'></span><span class='visuallyhidden'>Confirm delete</span></a>","<a class='btn--deny-delete'><span class='icon--cross' aria-hidden='true'></span><span class='visuallyhidden'>Do not delete</span></a>","<label class='st-block__delete-label'>","<%= i18n.t('general:delete') %>","</label>","</div>"].join("\n"),drop_options={html:['<div class="st-block__dropzone">','<span class="st-icon"><%= _.result(block, "icon_name") %></span>','<p><%= i18n.t("general:drop", { block: "<span>" + _.result(block, "title") + "</span>" }) %>',"</p></div>"].join("\n"),re_render_on_reorder:!1},paste_options={html:['<input type="text" placeholder="<%= i18n.t("general:paste") %>"',' class="st-block__paste-input st-paste-block">'].join("")},upload_options={html:['<div class="st-block__upload-container">','<input type="file" type="st-file-upload">','<button class="st-upload-btn"><%= i18n.t("general:upload") %></button>',"</div>"].join("\n")};return SirTrevor.DEFAULTS.Block={drop_options:drop_options,paste_options:paste_options,upload_options:upload_options},_.extend(Block.prototype,SirTrevor.SimpleBlock.fn,SirTrevor.BlockValidations,{bound:["_checkArrowKeysUp","_checkArrowKeysDown","_checkReturn","_checkBackspaceAtStartKeyDown","_checkBackspaceAtStartKeyUp","_handleContentPaste","_onFocus","_onBlur","onDrop","onDeleteClick","clearInsertedStyles","getSelectionForFormatter","onBlockRender"],className:"st-block st-icon--add",attributes:function(){return _.extend(SirTrevor.SimpleBlock.fn.attributes.call(this),{"data-icon-after":"add"})},icon_name:"default",validationFailMsg:function(){return i18n.t("errors:validation_fail",{type:this.title()})},editorHTML:'<div class="st-block__editor"></div>',toolbarEnabled:!0,droppable:!1,pastable:!1,uploadable:!1,fetchable:!1,ajaxable:!1,styleable:!1,drop_options:{},paste_options:{},upload_options:{},formattable:!0,removeEmpty:!1,_previousSelection:"",initialize:function(){},toMarkdown:function(markdown){return markdown},toHTML:function(html){return html},withMixin:function(mixin){if(_.isObject(mixin)){var initializeMethod="initialize"+mixin.mixinName;_.isUndefined(this[initializeMethod])&&(_.extend(this,mixin),this[initializeMethod]())}},render:function(){if(this.beforeBlockRender(),this._setBlockInner(),this.$editor=this.$inner.children().first(),this.droppable||this.pastable||this.uploadable){var input_html=$("<div>",{"class":"st-block__inputs"});this.$inner.append(input_html),this.$inputs=input_html}return this.hasTextBlock&&this._initTextBlocks(),this.droppable&&this.withMixin(SirTrevor.BlockMixins.Droppable),this.pastable&&this.withMixin(SirTrevor.BlockMixins.Pastable),this.uploadable&&this.withMixin(SirTrevor.BlockMixins.Uploadable),this.fetchable&&this.withMixin(SirTrevor.BlockMixins.Fetchable),this.controllable&&this.withMixin(SirTrevor.BlockMixins.Controllable),this.formattable&&this._initFormatting(),this.removeEmpty&&this._registerRemoveListener(),this._blockPrepare(),this},_registerRemoveListener:function(){var removeOnOutsideClick=function(){this.isEmpty()&&!this.spinner&&this.trigger("removeBlock",this.blockID)}.bind(this);$(window).on("click",removeOnOutsideClick),this.listenTo(this,"removeBlock",function(){$(window).off("click",removeOnOutsideClick)})},remove:function(){this.ajaxable&&this.resolveAllInQueue(),this.$el.remove()},loading:function(){_.isUndefined(this.spinner)||this.ready(),this.spinner=new Spinner(SirTrevor.DEFAULTS.spinner),this.spinner.spin(this.$el[0]),this.$el.addClass("st--is-loading")},ready:function(){this.$el.removeClass("st--is-loading"),_.isUndefined(this.spinner)||(this.spinner.stop(),delete this.spinner)},toData:function(){SirTrevor.log("toData for "+this.blockID);var dataObj=(this.$el,{});if(this.hasTextBlock()){var content=this.getTextBlock().html();content.length>0&&(dataObj.text=SirTrevor.toMarkdown(content,this.type))}this.$(":input").not(".st-paste-block").length>0&&this.$(":input").each(function(index,input){input.getAttribute("name")&&(dataObj[input.getAttribute("name")]=input.value)}),_.isEmpty(dataObj)||this.setData(dataObj)},focus:function(){this.getTextBlock().focus()},blur:function(){this.getTextBlock().blur()},onFocus:function(){this.getTextBlock().bind("focus",this._onFocus)},onBlur:function(){this.getTextBlock().bind("blur",this._onBlur)},_onFocus:function(){this.trigger("blockFocus",this.$el)},_onBlur:function(){},onDrop:function(dataTransferObj){},onDeleteClick:function(ev){ev.preventDefault();var onDeleteConfirm=function(e){e.preventDefault(),this.trigger("removeBlock",this.blockID)},onDeleteDeny=function(e){e.preventDefault(),this.$el.removeClass("st-block--delete-active"),$delete_el.remove()};if(this.isEmpty())return void onDeleteConfirm.call(this,new Event("click"));this.$inner.find(".btn--editor-panel--delete").append(_.template(delete_template)),this.$el.addClass("st-block--delete-active");var $delete_el=this.$inner.find(".st-block__ui-delete-controls");this.$inner.on("click",".btn--confirm-delete",_.bind(onDeleteConfirm,this)).on("click",".btn--deny-delete",_.bind(onDeleteDeny,this))},pastedMarkdownToHTML:function(content){return SirTrevor.toHTML(SirTrevor.toMarkdown(content,this.type),this.type)},onContentPasted:function(event,target){target.html(this.pastedMarkdownToHTML(target[0].innerHTML)),this.getTextBlock().caretToEnd(),this.splitAtReturns()},beforeLoadingData:function(){this.loading(),(this.droppable||this.uploadable||this.pastable)&&(this.$editor.show(),this.$inputs.hide()),SirTrevor.SimpleBlock.fn.beforeLoadingData.call(this),this.ready()},_handleContentPaste:function(ev){var target=$(ev.currentTarget);_.delay(_.bind(this.onContentPasted,this,ev,target),0)},_getBlockClass:function(){return"st-block--"+this.className},_initUIComponents:function(){this._withUIComponent(new SirTrevor.BlockReorder(this.$el,this.instanceID));var notes=new SirTrevor.BlockNotes(this.$el,this.instanceID,this);this._withUIComponent(notes,".st-block-ui-btn--type-notes"),this._withUIComponent(new SirTrevor.BlockDeletion,".btn--editor-panel--delete",this.onDeleteClick),this._withUIComponent(new SirTrevor.BlockStyles(this.$el,this.instanceID,this)),this._withUIComponent(new SirTrevor.BlockAdd(this.$el)),this.onFocus(),this.onBlur()},_initFormatting:function(){var formatter;for(var name in SirTrevor.Formatters)SirTrevor.Formatters.hasOwnProperty(name)&&(formatter=SirTrevor.Formatters[name],_.isUndefined(formatter.keyCode)||formatter._bindToBlock(this.$el))},_initTextBlocks:function(){this.getTextBlock().bind("paste",this._handleContentPaste).bind("keyup",this._checkReturn).bind("keydown",this._checkArrowKeysDown).bind("keyup",this._checkArrowKeysUp).bind("keydown",this._checkBackspaceAtStartKeyDown).bind("keyup",this._checkBackspaceAtStartKeyUp).bind("keyup",this.getSelectionForFormatter).bind("mouseup",this.getSelectionForFormatter).bind("DOMNodeInserted",this.clearInsertedStyles)},_previousCaretOffset:void 0,_checkArrowKeysDown:function(ev){ev.target;if(void 0!==ev&&-1!==[37,38,39,40].indexOf(ev.keyCode)){if(!window.getSelection().isCollapsed)return;try{var marker=this.insertSplitMarker();this._previousCaretOffset=marker.offset()}finally{this.removeSplitMarker()}}},_checkArrowKeysUp:function(ev){ev.target;if(-1===$.inArray(this.type,["Heading","text","Quote","list"]))return!0;if(void 0!==ev&&-1!==$.inArray(ev.keyCode,[37,38,39,40])){if(!window.getSelection().isCollapsed)return;try{var marker=this.insertSplitMarker(),offset=marker.offset();if(offset.top===this._previousCaretOffset.top){if(38===ev.keyCode)return this.focusPreviousBlock(),!1;if(40===ev.keyCode)return this.focusNextBlock(),!1;if(offset.left===this._previousCaretOffset.left){if(37==ev.keyCode)return this.focusPreviousBlock(),!1;if(39==ev.keyCode)return this.focusNextBlock(),!1}}}finally{this.removeSplitMarker()}}return!0},focusPreviousBlock:function(){var instance=SirTrevor.getInstance(this.instanceID),currentPosition=instance.getBlockPosition(this.$el);if(1>currentPosition)return void console.log("Can't focus previous block: no previous block.");var previousBlock=instance.blocks.filter(function(block){return instance.getBlockPosition(block.$el)===currentPosition-1})[0];return void 0===previousBlock?void console.log("Can't merge with previous block: can't find by position"):-1===$.inArray(previousBlock.type,["Heading","text","Quote","list"])?void console.log("Can't focus previous block: not a text block. ("+previousBlock.type+")"):(previousBlock.focus(),void previousBlock.$editor.caretToEnd())},focusNextBlock:function(){var instance=SirTrevor.getInstance(this.instanceID),currentPosition=instance.getBlockPosition(this.$el);if(currentPosition>=instance.blocks.length)return void console.log("Can't focus next block: no next block.");var nextBlock=instance.blocks.filter(function(block){return instance.getBlockPosition(block.$el)===currentPosition+1})[0];return void 0===nextBlock?void console.log("Can't merge with next block: can't find by position"):-1===$.inArray(nextBlock.type,["Heading","text","Quote","list"])?void console.log("Can't focus next block: not a text block. ("+nextBlock.type+")"):(nextBlock.focus(),void nextBlock.$editor.caretToStart())},_checkReturn:function(ev){var target=ev.target;void 0===ev||ev.altKey||13!==ev.keyCode||_.defer(this.onReturn.bind(this,ev,target),0)},_previousContent:null,_checkBackspaceAtStartKeyUp:function(ev){var currentContent,target=ev.target;void 0!==ev&&8===ev.keyCode&&(currentContent=this.$editor[0].innerHTML,currentContent===this._previousContent&&_.defer(this.onBackspaceAtStart.bind(this,ev,target),0))},_checkBackspaceAtStartKeyDown:function(ev){void 0!==ev&&8===ev.keyCode&&(this._previousContent=this.$editor[0].innerHTML)},onBackspaceAtStart:function(event,target){if(-1!==$.inArray(this.type,["Heading","text"])){var instance=SirTrevor.getInstance(this.instanceID),currentPosition=instance.getBlockPosition(this.$el);if(1>currentPosition)return void console.log("Can't merge with previous block: no previous block.");var previousBlock=instance.blocks.filter(function(block){return instance.getBlockPosition(block.$el)===currentPosition-1})[0];if(void 0===previousBlock)return void console.log("Can't merge with previous block: can't find by position");if(-1===$.inArray(previousBlock.type,["Heading","text"]))return void console.log("Can't merge with previous block: not a text block.");previousBlock.focus(),previousBlock.$editor.caretToEnd(),previousBlock.$editor.append(this.$editor.contents()),instance.removeBlock(this.blockID)}},insertSplitMarker:function(html){var selection,range,element,fragment,node,lastNode,marker='<i id="split-marker"></i>';if(window.getSelection){if(selection=window.getSelection(),selection.getRangeAt&&selection.rangeCount){for(range=selection.getRangeAt(0),range.deleteContents(),element=document.createElement("div"),element.innerHTML=marker,fragment=document.createDocumentFragment();node=element.firstChild;)lastNode=fragment.appendChild(node);range.insertNode(fragment)}}else document.selection&&"Control"!=document.selection.type&&document.selection.createRange().pasteHTML(marker);return $("#split-marker")},removeSplitMarker:function(){var marker=$("#split-marker"),parent=marker.parent();marker.remove();var range=window.getSelection().getRangeAt(0);range.startOffset+range.endOffset!==0&&parent[0].normalize()},removeStartingReturns:function(block){var node,returns,selector="> div:first-child > br:first-child, > br:first-child";for(void 0===block&&(block=this),node=block.$editor,returns=node.find(selector);returns.length>0;)returns.remove(),returns=node.find(selector),node.find("div:empty").remove()},removeTrailingReturns:function(block){var node,returns,selector="div:last-child br:last-child, br:last-child";for(void 0===block&&(block=this),node=block.$editor,node.find("div:empty").remove(),returns=node.find(selector);returns.length>0;)returns.remove(),node.find("div:empty").remove(),returns=node.find(selector)},cleanupNestedDivs:function(block){var node,selector="div div";void 0===block&&(block=this),node=block.$editor,node.find(selector).each(function(i,el){var element=$(el);element.replaceWith(element.contents())}),node.find("div:empty").remove()},splitAtReturns:function(){var next,r=this.$el.find("br").first();if(0!==r.length){r.replaceWith('<i id="split-marker"></i>');try{next=this.splitAtSplitMarker()}finally{this.removeSplitMarker()}next.splitAtReturns()}},splitAtSplitMarker:function(){var newBlock,currentPosition,nextBlockPosition,instance=SirTrevor.getInstance(this.instanceID);try{newBlock=instance.createBlock("text",void 0,void 0,!1),currentPosition=instance.getBlockPosition(this.$el),nextBlockPosition=instance.getBlockPosition(newBlock.$el),nextBlockPosition-currentPosition!==1&&instance.changeBlockPosition(newBlock.$el,currentPosition+1,"After");var range=window.getSelection().getRangeAt(0);range.setStartAfter($("#split-marker")[0]),range.setEndAfter(this.$el.find(".st-text-block").children().last()[0]);var remainder=range.cloneContents();range.deleteContents(),newBlock.$editor.append(remainder),newBlock.$editor.find("div:empty").remove()}finally{this.cleanupNestedDivs(newBlock),newBlock.focus(),newBlock.$editor.caretToStart()}return newBlock},onReturn:function(event,target){if(-1!==$.inArray(this.type,["Heading","text"])){SirTrevor.getInstance(this.instanceID);window.getSelection().modify("extend","left","character"),document.execCommand("removeFormat",!1),this.insertSplitMarker();try{this.splitAtSplitMarker()}finally{this.removeSplitMarker()}}},getSelectionForFormatter:function(){_.defer(function(block){var selection=window.getSelection(),selectionStr=selection.toString().trim(),eventType=""===selectionStr?"hide":"position";SirTrevor.EventBus.trigger("formatter:"+eventType,block)},this)},clearInsertedStyles:function(e){var target=e.target;target.removeAttribute("style")},hasTextBlock:function(){return this.getTextBlock().length>0},getTextBlock:function(){return _.isUndefined(this.text_block)&&(this.text_block=this.$(".st-text-block")),this.text_block},isEmpty:function(){var data=jQuery.extend(!0,{},this.saveAndGetData());return delete data.uuid,delete data.note,delete data.style,_.isEmpty(data)}}),Block.extend=extend,Block}(),SirTrevor.DynamicBlocks=function(){return{}}(),SirTrevor.Formatter=function(){var Format=function(options){this.formatId=_.uniqueId("format-"),this._configure(options||{}),this.initialize.apply(this,arguments)},formatOptions=["title","className","cmd","keyCode","param","onClick","toMarkdown","toHTML"];return _.extend(Format.prototype,{title:"",className:"",cmd:null,keyCode:null,param:null,toMarkdown:function(markdown){return markdown},toHTML:function(html){return html},initialize:function(){},_configure:function(options){this.options&&(options=_.extend({},this.options,options));for(var i=0,l=formatOptions.length;l>i;i++){var attr=formatOptions[i];options[attr]&&(this[attr]=options[attr])}this.options=options},isActive:function(){return document.queryCommandState(this.cmd)},_bindToBlock:function(block){var formatter=this,ctrlDown=!1;block.on("keyup",".st-text-block",function(ev){(17==ev.which||224==ev.which||91==ev.which)&&(ctrlDown=!1)}).on("keydown",".st-text-block",{formatter:formatter},function(ev){(17==ev.which||224==ev.which||91==ev.which)&&(ctrlDown=!0),ev.which==ev.data.formatter.keyCode&&ctrlDown===!0&&(document.execCommand(ev.data.formatter.cmd,!1,!0),ev.preventDefault(),ctrlDown=!1)})}}),Format.extend=extend,Format}(),SirTrevor.Blocks.Quote=function(){var template=_.template(['<blockquote class="st-required st-text-block st-block--quote" contenteditable="true"></blockquote>','<label class="st-input-label"> <%= i18n.t("blocks:quote:credit_field") %></label>','<input maxlength="140" name="cite" placeholder="<%= i18n.t("blocks:quote:credit_field") %>"',' class="st-input-string js-cite-input" type="text" />'].join("\n"));return SirTrevor.Block.extend({type:"quote",title:function(){return i18n.t("blocks:quote:title")},icon_name:"quote",changeable:["Heading","text"],editorHTML:function(){return template(this)},loadData:function(data){this.getTextBlock().html(SirTrevor.toHTML(data.text,this.type)),this.$(".js-cite-input").val(data.cite)},toMarkdown:function(markdown){return markdown.replace(/^(.+)$/gm,"> $1")}})}(),SirTrevor.Blocks.ExtendedQuote=function(){var template=_.template(['<blockquote class="st-required st-text-block st-block--extended-quote" contenteditable="true"></blockquote>','<label class="st-input-label"> <%= i18n.t("blocks:extended_quote:credit_field") %></label>','<input name="cite" placeholder="<%= i18n.t("blocks:extended_quote:credit_field") %>"',' class="st-input-string js-cite-input" type="text" />'].join("\n"));return SirTrevor.Block.extend({type:"extended_quote",title:function(){return i18n.t("blocks:extended_quote:title")},icon_name:"quote-extended",changeable:["Heading","text"],editorHTML:function(){return template(this)},loadData:function(data){this.getTextBlock().html(SirTrevor.toHTML(data.text,this.type)),this.$(".js-cite-input").val(data.cite)},toMarkdown:function(markdown){return markdown.replace(/^(.+)$/gm,"> $1")}})}(),SirTrevor.Blocks.Heading=SirTrevor.Block.extend({type:"Heading",title:function(){return i18n.t("blocks:heading:title")},editorHTML:'<div class="st-required st-text-block st-block--heading" contenteditable="true"></div>',icon_name:"heading",changeable:["text","quote"],loadData:function(data){this.getTextBlock().html(SirTrevor.toHTML(data.text,this.type))}}),SirTrevor.Blocks.Text=SirTrevor.Block.extend({type:"text",title:function(){return i18n.t("blocks:text:title")},editorHTML:'<div class="st-required st-text-block" contenteditable="true"></div>',icon_name:"text",changeable:["Heading","quote"],loadData:function(data){this.getTextBlock().html(SirTrevor.toHTML(data.text,this.type))}}),SirTrevor.Blocks.List=function(){var template='<div class="st-text-block st-required st-block--list" contenteditable="true"><ul><li></li></ul></div>';return SirTrevor.Block.extend({type:"list",title:function(){return i18n.t("blocks:list:title")},icon_name:"list",editorHTML:function(){return _.template(template,this)},loadData:function(data){this.getTextBlock().html("<ul>"+SirTrevor.toHTML(data.text,this.type)+"</ul>")},onBlockRender:function(){this.checkForList=_.bind(this.checkForList,this),this.getTextBlock().on("click keyup",this.checkForList)},checkForList:function(){0===this.$("ul").length&&document.execCommand("insertUnorderedList",!1,!1)},toMarkdown:function(markdown){return markdown.replace(/<\/li>/gm,"\n").replace(/<\/?[^>]+(>|$)/g,"").replace(/^(.+)$/gm," - $1")},toHTML:function(html){return html=html.replace(/^ - (.+)$/gm,"<li>$1</li>").replace(/\n/gm,"")},onContentPasted:function(event,target){var replace=this.pastedMarkdownToHTML(target[0].innerHTML);this.$("ul").html(replace);this.getTextBlock().caretToEnd()},isEmpty:function(){return _.isEmpty(this.saveAndGetData().text)}})}(),SirTrevor.Blocks.Definition=function(){var template=_.template(['<dl class="st-definition st-block--definition"><dt><label class="st-input-label"> <%= i18n.t("blocks:definition:term") %></label>','<input name="term" placeholder="<%= i18n.t("blocks:definition:term") %>"',' class="st-input-string js-term-input" type="text" /></dt>','<dd class="st-required st-text-block" contenteditable="true" data-placeholder="<%= i18n.t("blocks:definition:description") %>"></dd></dl>'].join("\n"));return SirTrevor.Block.extend({type:"definition",title:function(){return i18n.t("blocks:definition:title")},icon_name:"definition",changeable:["Heading","text"],editorHTML:function(){return template(this)},onBlockRender:function(){var placeholders=this.$el.find("[data-placeholder]");placeholders.on("change keydown keypress input",function(){this.textContent?this.setAttribute("data-hide-placeholder","true"):this.removeAttribute("data-hide-placeholder")})},loadData:function(data){this.getTextBlock().html(SirTrevor.toHTML(data.text,this.type)),this.$(".js-term-input").val(data.term)},onContentPasted:function(event,target){target.html(this.pastedMarkdownToHTML(target[0].innerHTML)),this.getTextBlock().caretToEnd()}})}(),SirTrevor.Blocks.Divider=function(){var template='<div class="st-divider st-block--divider"><hr></div>';return SirTrevor.Block.extend({type:"divider",title:function(){return i18n.t("blocks:divider:title")},icon_name:"divider",editorHTML:function(){return _.template(template,this)},toMarkdown:function(markdown){return"---------------------------------------"},toHTML:function(html){return template},isEmpty:function(){return!1}})}(),SirTrevor.Blocks.RewardList=function(){var template=['<div class="st-reward-list st-block--reward-list">','<h1><i class="icon--reward"></i>%s</h1>',"</div>"].join("\n");return SirTrevor.Block.extend({type:"reward_list",title:function(){return i18n.t("blocks:reward_list:title")},icon_name:"reward",editorHTML:function(){return _.template(template.replace("%s",this.title()),this)},isEmpty:function(){return!1}})}(),SirTrevor.Blocks.Image=SirTrevor.Block.extend({type:"image",title:function(){return i18n.t("blocks:image:title")},droppable:!0,uploadable:!0,icon_name:"image",loadData:function(data){this.$editor.html($("<img>",{src:data.file.url}))},onBlockRender:function(){this.$inputs.find("button").bind("click",function(ev){ev.preventDefault()}),this.$inputs.find("input").on("change",_.bind(function(ev){this.onDrop(ev.currentTarget)},this))},onUploadSuccess:function(data){this.setData(data),this.ready()},onUploadError:function(jqXHR,status,errorThrown){this.addMessage(i18n.t("blocks:image:upload_error")),this.ready()},onDrop:function(transferData){var file=transferData.files[0],urlAPI="undefined"!=typeof URL?URL:"undefined"!=typeof webkitURL?webkitURL:null;/image/.test(file.type)&&(this.loading(),this.$inputs.hide(),this.$editor.html($("<img>",{src:urlAPI.createObjectURL(file)})).show(),this.uploader(file,this.onUploadSuccess,this.onUploadError))}}),SirTrevor.Blocks.ExtendedImage=SirTrevor.Blocks.Image.extend({type:"extended_image",title:function(){return i18n.t("blocks:extended_image:title")},droppable:!0,uploadable:!0,styleable:!0,styles:[{name:i18n.t("blocks:extended_image:default"),value:"default",className:"default"
12
+ },{name:i18n.t("blocks:extended_image:bodywidth"),value:"bodywidth",className:"bodywidth"},{name:i18n.t("blocks:extended_image:fullwidth"),value:"fullwidth",className:"fullwidth"}],icon_name:"image",removeEmpty:!0,loadData:function(data){var payload,editor=this.$editor,figure=$("<figure class='media'></figure>"),picture=$("<picture class='media__img'></picture>"),source=data.file&&data.file.url;payload=void 0!==source?$("<img>",{src:source}):$('<h1><i class="icon--exclamation-triangle"></i></h1>'),figure.append(picture.append(payload));var copyright=($("<figcaption class='media__body'></figcaption>"),$(["<label class='st-input-label'>"+i18n.t("blocks:extended_image:copyright_field")+"</label>","<input type='text' maxlength='140' name='copyright' class='st-input-string js-copyright-input'","placeholder='"+i18n.t("blocks:extended_image:copyright_placeholder")+"'></input>"].join("\n")));figure.append(copyright);var caption=$(["<label class='st-input-label'>"+i18n.t("blocks:extended_image:caption_field")+"</label>","<textarea name='caption' class='st-input-string js-caption-input'","placeholder='"+i18n.t("blocks:extended_image:caption_placeholder")+"'></textarea>"].join("\n"));figure.append(caption);var target_url=$(["<label class='st-input-label'>"+i18n.t("blocks:extended_image:target_url_field")+"</label>","<input type='text' maxlength='140' name='target_url' class='st-input-string js-target_url-input'","placeholder='"+i18n.t("blocks:extended_image:target_url_placeholder")+"'></input>"].join("\n"));figure.append(target_url),editor.html("").show(),editor.append(figure),this.$(".js-target_url-input").val(data.target_url),this.$(".js-copyright-input").val(data.copyright),this.$(".js-caption-input").val(data.caption),void 0!==jQuery.fn.autosize&&figure.find(".js-caption-input").autosize()},onBlockRender:function(){this.$inputs.find("button").bind("click",function(ev){ev.preventDefault()}),this.$inputs.find("input").on("change",_.bind(function(ev){this.onDrop(ev.currentTarget)},this))},onUploadSuccess:function(data){this.setData(data),this.ready()},onUploadError:function(jqXHR,status,errorThrown){this.addMessage(i18n.t("blocks:extended_image:upload_error")),this.ready()},onDrop:function(transferData){var file=transferData.files[0],urlAPI="undefined"!=typeof URL?URL:"undefined"!=typeof webkitURL?webkitURL:null;/image/.test(file.type)&&(this.loading(),this.$inputs.hide(),this.loadData({file:{url:urlAPI.createObjectURL(file)}}),this.uploader(file,this.onUploadSuccess,this.onUploadError))}}),SirTrevor.Blocks.Video=function(){return SirTrevor.Block.extend({providers:{vimeo:{regex:/(?:http[s]?:\/\/)?(?:www.)?vimeo.com\/(.+)/,html:'<iframe src="{{protocol}}//player.vimeo.com/video/{{remote_id}}?title=0&byline=0" width="580" height="320" frameborder="0"></iframe>'},youtube:{regex:/(?:http[s]?:\/\/)?(?:www.)?(?:(?:youtube.com\/watch\?(?:.*)(?:v=))|(?:youtu.be\/))([^&].+)/,html:'<iframe src="{{protocol}}//www.youtube.com/embed/{{remote_id}}" width="580" height="320" frameborder="0" allowfullscreen></iframe>'}},type:"video",title:function(){return i18n.t("blocks:video:title")},droppable:!0,pastable:!0,icon_name:"video",styleable:!0,styles:[{name:"Default",value:"default",className:"default"},{name:"Full-width",value:"fullwidth",className:"default"}],removeEmpty:!0,extractSourceInformation:function(){var url=this.$editor.find("iframe").attr("src");this.$editor.parents(".st-block").append("<aside>"+i18n.t("general:source")+": "+url+"</aside>")},loadData:function(data){var embed_string;this.providers.hasOwnProperty(data.source)?(this.providers[data.source].square?this.$editor.addClass("st-block__editor--with-square-media"):this.$editor.addClass("st-block__editor--with-sixteen-by-nine-media"),embed_string=this.providers[data.source].html.replace("{{protocol}}",window.location.protocol).replace("{{remote_id}}",data.remote_id).replace("{{width}}",this.$editor.width())):embed_string='<h1><i class="icon--exclamation-triangle"></i></h1>',this.$editor.html(embed_string),this.extractSourceInformation()},onContentPasted:function(event){this.handleDropPaste($(event.target).val())},handleDropPaste:function(url){if(_.isURI(url)){var match,data;_.each(this.providers,function(provider,index){match=provider.regex.exec(url),null===match||_.isUndefined(match[1])||(data={source:index,remote_id:match[1]},this.setAndLoadData(data))},this)}},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleDropPaste(url)}})}(),SirTrevor.Blocks.Tweet=function(){var tweet_template=_.template(["<blockquote class='twitter-tweet' align='center'>","<p><%= text %></p>","&mdash; <%= user.name %> (@<%= user.screen_name %>)","<a href='<%= status_url %>' data-datetime='<%= created_at %>'><%= created_at %></a>","</blockquote>",'<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>'].join("\n"));return SirTrevor.Block.extend({type:"tweet",droppable:!0,pastable:!0,fetchable:!0,drop_options:{re_render_on_reorder:!0},title:function(){return i18n.t("blocks:tweet:title")},fetchUrl:function(tweetID){return"/tweets/?tweet_id="+tweetID},icon_name:"twitter",loadData:function(data){_.isUndefined(data.status_url)&&(data.status_url=""),this.$inner.find("iframe").remove(),this.$inner.prepend(tweet_template(data))},onContentPasted:function(event){var input=$(event.target),val=input.val();this.handleTwitterDropPaste(val)},handleTwitterDropPaste:function(url){if(!this.validTweetUrl(url))return void SirTrevor.log("Invalid Tweet URL");var tweetID=url.match(/[^\/]+$/);if(!_.isEmpty(tweetID)){this.loading(),tweetID=tweetID[0];var ajaxOptions={url:this.fetchUrl(tweetID),dataType:"json"};this.fetch(ajaxOptions,this.onTweetSuccess,this.onTweetFail)}},validTweetUrl:function(url){return _.isURI(url)&&-1!==url.indexOf("twitter")&&-1!==url.indexOf("status")},onTweetSuccess:function(data){var obj={user:{profile_image_url:data.user.profile_image_url,profile_image_url_https:data.user.profile_image_url_https,screen_name:data.user.screen_name,name:data.user.name},id:data.id_str,text:data.text,created_at:data.created_at,entities:data.entities,status_url:"https://twitter.com/"+data.user.screen_name+"/status/"+data.id_str};this.setAndLoadData(obj),this.ready()},onTweetFail:function(){this.addMessage(i18n.t("blocks:tweet:fetch_error")),this.ready()},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleTwitterDropPaste(url)}})}(),SirTrevor.Blocks.ExtendedTweet=function(){return SirTrevor.Block.extend({providers:{soundcloud:{regex:/((?:http[s]?:\/\/)?(?:www.)?(:?twitter.com\/.*\/status\/(.*?)))(:?\?.*)?$/,html:function(options,success,error){var fail=window.setTimeout(error,5e3);$.getJSON("https://api.twitter.com/1/statuses/oembed.json?callback=?",{format:"js",url:options.remote_id,align:"center",maxwidth:550,hide_thread:1,iframe:!0}).done(function(data){clearTimeout(fail),success(data.html,options)})}}},type:"extended_tweet",title:function(){return i18n.t("blocks:tweet:title")},droppable:!0,pastable:!0,removeEmpty:!0,icon_name:"twitter-outline",extractSourceInformation:function(options){var url=options.remote_id;this.$editor.parents(".st-block").append("<aside>"+i18n.t("general:source")+": "+url+"</aside>")},loadData:function(data){var embed_string,self=this,update_editor=function(embed_string,options){self.$editor.html(embed_string),self.extractSourceInformation(options)},display_error=function(){embed_string='<h1><i class="icon--exclamation-triangle"></i></h1>',self.$editor.html(embed_string)};if(this.providers.hasOwnProperty(data.source)){var html=this.providers[data.source].html;html instanceof Function?html({protocol:window.location.protocol,remote_id:data.remote_id,width:this.$editor.width()},update_editor,display_error):(embed_string=html.replace("{{protocol}}",window.location.protocol).replace("{{remote_id}}",data.remote_id).replace("{{width}}",this.$editor.width()),update_editor())}else display_error()},onContentPasted:function(event){this.handleDropPaste($(event.target).val())},handleDropPaste:function(url){if(_.isURI(url)){var match,data;_.each(this.providers,function(provider,index){match=provider.regex.exec(url),null===match||_.isUndefined(match[1])||(data={source:index,remote_id:match[1]},this.setAndLoadData(data))},this)}},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleDropPaste(url)}})}(),SirTrevor.Blocks.FacebookPost=function(){function initFacebookOnce(){if("undefined"==typeof FB&&!initDone){var facebookInitScript=['<div id="fb-root"></div>',"<script>(function(d, s, id) {"," var js, fjs = d.getElementsByTagName(s)[0];"," if (d.getElementById(id)) return;"," js = d.createElement(s); js.id = id;",' js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0";'," fjs.parentNode.insertBefore(js, fjs);",'}(document, "script", "facebook-jssdk"));</script>'].join("\n");jQuery(document.body).append(facebookInitScript),initDone=!0}}var initDone=!1,facebook_post_template=_.template(['<div class="fb-post" data-href="<%= url %>" data-width="<%= width %>"></div>'].join("\n")),facebookPostRegex=/((?:http[s]?:\/\/)?(?:www.)?(:?facebook.com\/(video\.php|photo\.php|(.*\/(posts|photos)\/))(.*?)))(:?\?.*)?$/;return SirTrevor.Block.extend({type:"facebook_post",title:function(){return i18n.t("blocks:facebookpost:title")},droppable:!0,pastable:!0,icon_name:"facebook-outline",extractSourceInformation:function(url){this.$editor.parents(".st-block").append("<aside>"+i18n.t("general:source")+": "+url+"</aside>")},loadData:function(data){initFacebookOnce(),this.$inner.prepend(facebook_post_template({url:data.url,width:this.$editor.width()||"700"})),this.extractSourceInformation(data.url),"undefined"!=typeof FB&&FB.XFBML.parse()},onContentPasted:function(event){this.handleDropPaste($(event.target).val())},handleDropPaste:function(url){if(_.isURI(url)){if(!this.validPostUrl(url))return void SirTrevor.log("Invalid Facebook Post URL");this.setAndLoadData({url:url}),this.ready()}},validPostUrl:function(url){return url.match(facebookPostRegex)},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleDropPaste(url)}})}(),SirTrevor.Blocks.Infographic=function(){return SirTrevor.Block.extend({providers:{infoactive:{regex:/(?:http[s]?:\/\/)?(?:www.)?infoactive.co\/plays\/(.+)/,html:["<div data-url='https://infoactive.co/plays/{{remote_id}}' id='infoactive-iframe-container-{{remote_id}}'></div>","<script type='text/javascript'>","jQuery.getScript('https://dqzzm1bt1bnva.cloudfront.net/assets/pym-7afa305c2065e6ace0f4cb837fc78658.js', function() {","var iFrameLoader = new pym.Parent('infoactive-iframe-container-{{remote_id}}','https://infoactive.co/plays/{{remote_id}}', {});","});","</script>"].join("\n")}},type:"infographic",title:function(){return i18n.t("blocks:infographic:title")},droppable:!0,pastable:!0,removeEmpty:!0,icon_name:"infographic",extractSourceInformation:function(){var url=this.$editor.find("div[data-url]").attr("data-url");this.$editor.parents(".st-block").append("<aside>"+i18n.t("general:source")+": "+url+"</aside>")},loadData:function(data){var embed_string;this.providers.hasOwnProperty(data.source)?(embed_string=this.providers[data.source].html.replace(/{{protocol}}/g,window.location.protocol).replace(/{{remote_id}}/g,data.remote_id).replace(/{{width}}/g,this.$editor.width()),this.$editor.html(embed_string),this.extractSourceInformation()):(embed_string='<h1><i class="icon--exclamation-triangle"></i></h1>',this.$editor.html(embed_string))},onContentPasted:function(event){this.handleDropPaste($(event.target).val())},handleDropPaste:function(url){if(_.isURI(url)){var match,data;_.each(this.providers,function(provider,index){match=provider.regex.exec(url),null===match||_.isUndefined(match[1])||(data={source:index,remote_id:match[1]},this.setAndLoadData(data))},this)}},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleDropPaste(url)}})}(),SirTrevor.Blocks.Audio=function(){return SirTrevor.Block.extend({providers:{soundcloud:{regex:/((?:http[s]?:\/\/)?(?:www.)?(:?soundcloud.com\/(.*)))/,html:function(options,success,error){var fail=window.setTimeout(error,5e3);$.getJSON("https://soundcloud.com/oembed?callback=?",{format:"js",url:options.remote_id,iframe:!0}).done(function(data){clearTimeout(fail),success(data.html,options)})}}},type:"audio",title:function(){return i18n.t("blocks:audio:title")},droppable:!0,pastable:!0,removeEmpty:!0,icon_name:"audio",extractSourceInformation:function(){var url=this.$editor.find("iframe").attr("src");this.$editor.parents(".st-block").append("<aside>"+i18n.t("general:source")+": "+url+"</aside>")},loadData:function(data){var embed_string,self=this,update_editor=function(embed_string){self.$editor.html(embed_string),self.extractSourceInformation(),self.providers[data.source].square?self.$editor.addClass("st-block__editor--with-square-media"):self.$editor.addClass("st-block__editor--with-sixteen-by-nine-media")},display_error=function(){embed_string='<h1><i class="icon--exclamation-triangle"></i></h1>',self.$editor.html(embed_string)};if(this.providers.hasOwnProperty(data.source)){var html=this.providers[data.source].html;html instanceof Function?html({protocol:window.location.protocol,remote_id:data.remote_id,width:this.$editor.width()},update_editor,display_error):(embed_string=html.replace("{{protocol}}",window.location.protocol).replace("{{remote_id}}",data.remote_id).replace("{{width}}",this.$editor.width()),update_editor())}else display_error()},onContentPasted:function(event){this.handleDropPaste($(event.target).val())},handleDropPaste:function(url){if(_.isURI(url)){var match,data;_.each(this.providers,function(provider,index){match=provider.regex.exec(url),null===match||_.isUndefined(match[1])||(data={source:index,remote_id:match[1]},this.setAndLoadData(data))},this)}},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleDropPaste(url)}})}(),SirTrevor.Blocks.Html=SirTrevor.Block.extend({type:"html",title:function(){return i18n.t("blocks:html:title")},editorHTML:'<div class="st-required st-html-block" contenteditable="true"></div>',icon_name:"text",changeable:[],getBlock:function(){return this.$(".st-html-block")},toData:function(){SirTrevor.log("toData for "+this.blockID);var uuid=this.getData().uuid||SirTrevor.generateUUID(),dataObj=(this.$el,{uuid:uuid}),content=this.getBlock().text();content.length>0&&(dataObj.text=content),_.isEmpty(dataObj)||this.setData(dataObj)},loadData:function(data){this.getBlock().text(data.text)}}),SirTrevor.Blocks.Instagram=function(){return SirTrevor.Block.extend({providers:{instagram:{regex:/((?:http[s]?:\/\/)?(?:www.)?(:?instagr.*\/p\/(.*?)))(:?\?.*)?$/,html:function(options,success,error){var fail=window.setTimeout(error,5e3);$.ajax({url:"//api.instagram.com/oembed",data:{maxwidth:550,url:options.remote_id},jsonp:"callback",dataType:"jsonp"}).done(function(data){clearTimeout(fail),success(data.html,options)})}}},type:"instagram",title:function(){return i18n.t("blocks:instagram:title")},droppable:!0,pastable:!0,removeEmpty:!0,icon_name:"instagram-outline",extractSourceInformation:function(options){var url=options.remote_id;this.$editor.parents(".st-block").append("<aside>"+i18n.t("general:source")+": "+url+"</aside>")},loadData:function(data){var embed_string,self=this,update_editor=function(embed_string,options){self.$editor.html(embed_string),self.extractSourceInformation(options)},display_error=function(){embed_string='<h1><i class="icon--exclamation-triangle"></i></h1>',self.$editor.html(embed_string)},html=this.providers[data.source].html;html({protocol:window.location.protocol,remote_id:data.remote_id,width:this.$editor.width()},update_editor,display_error)},onContentPasted:function(event){this.handleDropPaste($(event.target).val())},handleDropPaste:function(url){if(_.isURI(url)){var match,data;_.each(this.providers,function(provider,index){match=provider.regex.exec(url),null===match||_.isUndefined(match[1])||(data={source:index,remote_id:match[1]},this.setAndLoadData(data))},this)}},onDrop:function(transferData){var url=transferData.getData("text/plain");this.handleDropPaste(url)}})}(),SirTrevor.DynamicBlocks.RemoteSelectableList=function(){return function(parameters){return{type:parameters.model_name,fetchable:!0,selectedElements:[],title:function(){return i18n.t("blocks:remote_list:"+parameters.model_name+":title")},icon_name:parameters.icon,editorHTML:function(){return""},onBlockRender:function(){this.getData().selected||(this.loading(),this.setData({selected:[],model_name:parameters.model_name}),parameters.callback(this.onListSuccess.bind(this),this.onGetFail.bind(this)))},loadData:function(data){return _.isArray(data.selected)&&0!==data.selected.length?void this.renderSelected(data.selected):void this.destroy()},renderSelected:function(selected){var data=JSON.stringify({model_name:parameters.model_name,selected:selected});$.get(parameters.render_endpoint,{content:data},this.onGetRenderSuccess.bind(this)).fail(this.onGetFail.bind(this))},onGetRenderSuccess:function(data){this.ready(),this.$el.append(data)},onListSuccess:function(data){this.setAndLoadData({selected:data,model_name:parameters.model_name}),this.ready()},onGetFail:function(){this.addMessage(i18n.t("blocks:remote_list:fetch_error")),this.ready()}}}}(),function(){var Bold=SirTrevor.Formatter.extend({title:"bold",cmd:"bold",keyCode:66,text:"B"}),Italic=SirTrevor.Formatter.extend({title:"italic",cmd:"italic",keyCode:73,text:"i"}),Link=SirTrevor.Formatter.extend({title:"link",iconName:"link",cmd:"CreateLink",text:"link",onClick:function(){var selectionLink="";try{var sel=document.getSelection();sel.rangeCount&&(selectionLink=sel.getRangeAt(0).commonAncestorContainer.parentElement.href||"")}catch(e){}var link=prompt(i18n.t("general:link"),selectionLink),link_regex=/((ftp|http|https):\/\/.)|mailto(?=\:[-\.\w]+@)/;link&&link.length>0&&(link_regex.test(link)||(link="http://"+link),document.execCommand(this.cmd,!1,link))},isActive:function(){var node,selection=window.getSelection();return selection.rangeCount>0&&(node=selection.getRangeAt(0).startContainer.parentNode),node&&"A"==node.nodeName}}),UnLink=SirTrevor.Formatter.extend({title:"unlink",iconName:"link",cmd:"unlink",text:"link"});SirTrevor.Formatters.Bold=new Bold,SirTrevor.Formatters.Italic=new Italic,SirTrevor.Formatters.Link=new Link,SirTrevor.Formatters.Unlink=new UnLink}(),function(){var Heading=SirTrevor.Formatter.extend({title:"heading",iconName:"Heading",text:"H1",prepare:function(){var selection=window.getSelection();if(0===selection.rangeCount)return void SirTrevor.log("Can't get current selection from formatter!");var node=$(selection.getRangeAt(0).startContainer.parentNode).parents(".st-block").first();this._instance=SirTrevor.getInstance(node.attr("data-instance")),this._block=this._instance.getBlocksByIDs([node.attr("id")])[0]},getCurrentBlock:function(){return this._block},getCurrentInstance:function(){return this._instance},onClick:function(){var instance=this.getCurrentInstance(),block=this.getCurrentBlock();instance.changeBlockType(block,"Heading"===block.type?"text":"Heading")},isActive:function(){return this.prepare(),"Heading"===this.getCurrentBlock().type}}),Quote=SirTrevor.Formatter.extend({title:"quote",iconName:"quote",text:"“",prepare:function(){var selection=window.getSelection();if(0===selection.rangeCount)return void SirTrevor.log("Can't get current selection from formatter!");var node=$(selection.getRangeAt(0).startContainer.parentNode).parents(".st-block").first();this._instance=SirTrevor.getInstance(node.attr("data-instance")),this._block=this._instance.getBlocksByIDs([node.attr("id")])[0]},getCurrentBlock:function(){return this._block},getCurrentInstance:function(){return this._instance},onClick:function(){var instance=this.getCurrentInstance(),block=this.getCurrentBlock();instance.changeBlockType(block,"quote"===block.type?"text":"quote")},isActive:function(){return this.prepare(),"quote"===this.getCurrentBlock().type}});SirTrevor.Formatters.Heading=new Heading,SirTrevor.Formatters.Quote=new Quote}(),SirTrevor.BlockControl=function(){var BlockControl=function(type,instance_scope){this.type=type,this.instance_scope=instance_scope,this.block_type=SirTrevor.Blocks[this.type].prototype,this.can_be_rendered=this.block_type.toolbarEnabled,this._ensureElement()};return _.extend(BlockControl.prototype,FunctionBind,Renderable,SirTrevor.Events,{tagName:"a",className:"st-block-control",attributes:function(){return{"data-type":this.block_type.type}},render:function(){return this.$el.html('<span class="st-icon icon--'+_.result(this.block_type,"icon_name")+'" aria-hidden="true"></span>'+_.result(this.block_type,"title")),this}}),BlockControl}(),SirTrevor.BlockControls=function(){var BlockControls=function(available_types,instance_scope){this.instance_scope=instance_scope,this.available_types=available_types||[],this._ensureElement(),this._bindFunctions(),this.initialize()};return _.extend(BlockControls.prototype,FunctionBind,Renderable,SirTrevor.Events,{bound:["handleControlButtonClick"],block_controls:null,className:"st-block-controls",html:"<a class='st-icon st-icon--close'>"+i18n.t("general:close")+"</a>",initialize:function(){for(var block_type in this.available_types)if(SirTrevor.Blocks.hasOwnProperty(block_type)){var block_control=new SirTrevor.BlockControl(block_type,this.instance_scope);block_control.can_be_rendered&&this.$el.append(block_control.render().$el)}this.$el.delegate(".st-block-control","click",this.handleControlButtonClick)},show:function(){this.$el.addClass("st-block-controls--active"),SirTrevor.EventBus.trigger("block:controls:shown")},hide:function(){this.$el.removeClass("st-block-controls--active"),SirTrevor.EventBus.trigger("block:controls:hidden")},handleControlButtonClick:function(e){e.stopPropagation(),this.trigger("createBlock",$(e.currentTarget).attr("data-type"))}}),BlockControls}(),SirTrevor.FloatingBlockControls=function(){var FloatingBlockControls=function(wrapper,instance_id){this.$wrapper=wrapper,this.instance_id=instance_id,this._ensureElement(),this._bindFunctions(),this.initialize()};return _.extend(FloatingBlockControls.prototype,FunctionBind,Renderable,SirTrevor.Events,{className:"st-block-controls__top",attributes:function(){return{"data-icon":"add"}},bound:["handleBlockMouseOut","handleBlockMouseOver","handleBlockClick","onDrop"],initialize:function(){this.$el.on("click",this.handleBlockClick).dropArea().bind("drop",this.onDrop),this.$wrapper.on("mouseover",".st-block",this.handleBlockMouseOver).on("mouseout",".st-block",this.handleBlockMouseOut).on("click",".st-block--with-plus",this.handleBlockClick)},onDrop:function(ev){ev.preventDefault();var dropped_on=this.$el,item_id=ev.originalEvent.dataTransfer.getData("text/plain"),block=$("#"+item_id);_.isUndefined(item_id)||_.isEmpty(block)||dropped_on.attr("id")==item_id||this.instance_id!=block.attr("data-instance")||dropped_on.after(block),SirTrevor.EventBus.trigger("block:reorder:dropped",item_id)},handleBlockMouseOver:function(e){var block=$(e.currentTarget);block.hasClass("st-block--with-plus")||block.addClass("st-block--with-plus")},handleBlockMouseOut:function(e){var block=$(e.currentTarget);block.hasClass("st-block--with-plus")&&block.removeClass("st-block--with-plus")},handleBlockClick:function(e){e.stopPropagation();var block=$(e.currentTarget);this.trigger("showBlockControls",block)}}),FloatingBlockControls}(),SirTrevor.FormatBar=function(){var FormatBar=function(options){this.options=_.extend({},SirTrevor.DEFAULTS.formatBar,options||{}),this._ensureElement(),this._bindFunctions(),this.initialize.apply(this,arguments)};return _.extend(FormatBar.prototype,FunctionBind,SirTrevor.Events,Renderable,{className:"st-format-bar",bound:["onFormatButtonClick","renderBySelection","hide"],initialize:function(){var formatName,format,btn;SirTrevor.Formatters;this.$btns=[];for(formatName in SirTrevor.Formatters)SirTrevor.Formatters.hasOwnProperty(formatName)&&(format=SirTrevor.Formatters[formatName],btn=$("<button>",{"class":"st-format-btn st-format-btn--"+formatName+" "+(format.iconName?"st-icon":""),text:format.text,"data-type":formatName,"data-cmd":format.cmd}),this.$btns.push(btn),btn.appendTo(this.$el));this.$b=$(document),this.$el.bind("click",".st-format-btn",this.onFormatButtonClick)},hide:function(){this.$el.removeClass("st-format-bar--is-ready")},show:function(){this.$el.addClass("st-format-bar--is-ready")},remove:function(){this.$el.remove()},renderBySelection:function(rectangles){var selection=window.getSelection(),range=selection.getRangeAt(0),boundary=range.getBoundingClientRect(),coords={};coords.top=boundary.top+20+window.pageYOffset-this.$el.height()+"px",coords.left=(boundary.left+boundary.right)/2-this.$el.width()/2+"px",this.highlightSelectedButtons(),this.show(),this.$el.css(coords)},highlightSelectedButtons:function(){var formatter;_.each(this.$btns,function($btn){formatter=SirTrevor.Formatters[$btn.attr("data-type")],$btn.toggleClass("st-format-btn--is-active",formatter.isActive())},this)},onFormatButtonClick:function(ev){ev.stopPropagation();var btn=$(ev.target),format=SirTrevor.Formatters[btn.attr("data-type")];return _.isUndefined(format)?!1:(!_.isUndefined(format.onClick)&&_.isFunction(format.onClick)?format.onClick():document.execCommand(btn.attr("data-cmd"),!1,format.param),this.highlightSelectedButtons(),!1)}}),FormatBar}(),SirTrevor.Editor=function(){var SirTrevorEditor=function(options){this.initialize(options)};return _.extend(SirTrevorEditor.prototype,FunctionBind,SirTrevor.Events,{bound:["onFormSubmit","showBlockControls","hideAllTheThings","hideBlockControls","onNewBlockCreated","changeBlockPosition","onBlockDragStart","onBlockDragEnd","removeBlockDragOver","onBlockDropped","createBlock","restoreDefaultType","autosave","_checkEscapeKeyPressed"],events:{"block:reorder:down":"hideBlockControls","block:reorder:dragstart":"onBlockDragStart","block:reorder:dragend":"onBlockDragEnd","block:content:dropped":"removeBlockDragOver","block:reorder:dropped":"onBlockDropped","block:create:new":"onNewBlockCreated"},initialize:function(options){return SirTrevor.log("Init SirTrevor.Editor"),this.blockTypes={},this.blockCounts={},this.blocks=[],this.errors=[],this.options=_.extend({},SirTrevor.DEFAULTS,options||{}),this.ID=_.uniqueId("st-editor-"),this._ensureAndSetElements()?(!_.isUndefined(this.options.onEditorRender)&&_.isFunction(this.options.onEditorRender)&&(this.onEditorRender=this.options.onEditorRender),this._extendLocales(),this._setRequired(),this._createDynamicBlocks(),this._setBlocksTypes(),this._bindFunctions(),this._setupActiveClass(),this.store("create"),SirTrevor.instances.push(this),this.build(),$(window).on("keyup",this._checkEscapeKeyPressed),void SirTrevor.bindFormSubmit(this.$form)):!1},_setupActiveClass:function(){var focus,current,timeout,root=$("#"+this.ID),className="st-active-block",resetActive=function(){window.clearTimeout(timeout),timeout=window.setTimeout(function(){root.find(".st-block").removeClass(className),current.addClass(className)},200)};root.delegate(".st-block","focus",function(e){focus=$(this),current=focus,resetActive()}),root.delegate(".st-block","mouseout",function(e){}),root.delegate(".st-block","mouseover",function(e){return e.stopPropagation(),$(e.target).hasClass("st-block__ui")||$(e.target).parents(".st-block__ui").length>0?!1:(current=$(this),void resetActive())})},build:function(){this.$el.hide(),this.block_controls=new SirTrevor.BlockControls(this.blockTypes,this.ID),this.fl_block_controls=new SirTrevor.FloatingBlockControls(this.$wrapper,this.ID),this.formatBar=new SirTrevor.FormatBar(this.options.formatBar),this.listenTo(this.block_controls,"createBlock",this.createBlock),this.listenTo(this.fl_block_controls,"showBlockControls",this.showBlockControls),SirTrevor.EventBus.on("showBlockControls",this.showBlockControls),this._setEvents(),SirTrevor.EventBus.on(this.ID+":blocks:change_position",this.changeBlockPosition),SirTrevor.EventBus.on("formatter:position",this.formatBar.renderBySelection),SirTrevor.EventBus.on("formatter:hide",this.formatBar.hide),SirTrevor.EventBus.on(this.ID+":blocks:count_update",this.restoreDefaultType),this.$wrapper.prepend(this.fl_block_controls.render().$el),$(document.body).append(this.formatBar.render().$el),this.$outer.append(this.block_controls.render().$el),$(window).bind("click.sirtrevor",this.hideAllTheThings);var store=this.store("read");store.data.length>0?_.each(store.data,function(block){SirTrevor.log("Creating: "+block.type),this.createBlock(block.type,block.data)},this):this.options.defaultType!==!1&&this.restoreDefaultType(),this.$wrapper.addClass("st-ready"),this.options.localStorage===!0&&window.setInterval(this.autosave,2e4),_.isUndefined(this.onEditorRender)||this.onEditorRender()},autosave:function(){this.store("reset");var blockIterator=function(block,index){var _block=_.find(this.blocks,function(b){return b.blockID==$(block).attr("id")});return _.isUndefined(_block)?!1:void this.saveBlockStateToStore(_block)};_.each(this.$wrapper.find(".st-block"),blockIterator,this),this.store("autosave")},restoreDefaultType:function(count){var instance=this;if(void 0===count||0===count){var container=instance.block_controls.current_container;instance.block_controls.current_container=void 0,instance.createBlock(instance.options.defaultType),instance.block_controls.current_container=container}},destroy:function(){this.formatBar.destroy(),this.fl_block_controls.destroy(),this.block_controls.destroy(),_.each(this.blocks,function(block){this.removeBlock(block.blockID)},this),this.stopListening();var el=this.$el.detach();SirTrevor.instances=_.reject(SirTrevor.instances,_.bind(function(instance){return instance.ID==this.ID},this)),this.store("reset"),this.$outer.replaceWith(el)},reinitialize:function(options){this.destroy(),this.initialize(options||this.options)},_setEvents:function(){_.each(this.events,function(callback,type){SirTrevor.EventBus.on(type,this[callback],this)},this)},hideAllTheThings:function(e){this.block_controls.hide(),this.formatBar.hide(),_.isUndefined(this.block_controls.current_container)||this.block_controls.current_container.removeClass("with-st-controls")},showBlockControls:function(container){_.isUndefined(this.block_controls.current_container)||this.block_controls.current_container.removeClass("with-st-controls"),this.block_controls.show(),container.append(this.block_controls.$el.detach()),container.addClass("with-st-controls"),this.block_controls.current_container=container},store:function(method,options){return SirTrevor.editorStore(this,method,options||{})},createBlock:function(type,data,render_at,focus){if(type=_.classify(type),this._blockLimitReached())return SirTrevor.log("Cannot add any more blocks. Limit reached."),!1;if(!this._isBlockTypeAvailable(type))return SirTrevor.log("Block type not available "+type),!1;if(!this._canAddBlockType(type))return SirTrevor.log("Block Limit reached for type "+type),!1;var block=new SirTrevor.Blocks[type](data,this.ID);return this._renderInPosition(block.render().$el),this.listenTo(block,"removeBlock",this.removeBlock),this.blocks.push(block),this._incrementBlockTypeCount(type),focus!==!1&&block.focus(),SirTrevor.EventBus.trigger(data?"block:create:existing":"block:create:new",block),SirTrevor.log("Block created of type "+type),block.trigger("onRender"),this.$wrapper.toggleClass("st--block-limit-reached",this._blockLimitReached()),this.triggerBlockCountUpdate(),block},onNewBlockCreated:function(block){block.instanceID===this.ID&&this.hideBlockControls()},scrollTo:function(element){},blockFocus:function(block){this.block_controls.current_container=null},_checkEscapeKeyPressed:function(e){27==e.keyCode&&this.hideBlockControls()},hideBlockControls:function(){_.isUndefined(this.block_controls.current_container)||this.block_controls.current_container.removeClass("with-st-controls"),this.block_controls.hide()},removeBlockDragOver:function(){
13
+ this.$outer.find(".st-drag-over").removeClass("st-drag-over")},triggerBlockCountUpdate:function(){SirTrevor.EventBus.trigger(this.ID+":blocks:count_update",this.blocks.length)},changeBlockType:function(block,type){var replacement=this.createBlock(type),currentPosition=this.getBlockPosition(block.$el);this.changeBlockPosition(replacement.$el,currentPosition+1,"After"),replacement.$editor.append(block.$editor.contents()),this.removeBlock(block.blockID),replacement.focus()},changeBlockPosition:function($block,selectedPosition,where){selectedPosition-=1;var blockPosition=this.getBlockPosition($block),$blockBy=this.$wrapper.find(".st-block").eq(selectedPosition);this.getBlockPosition($blockBy);-1===$.inArray(where,["Before","After"])&&(where=blockPosition>selectedPosition?"Before":"After"),$blockBy&&$blockBy.attr("id")!==$block.attr("id")&&(this.hideAllTheThings(),$block["insert"+where]($blockBy))},onBlockDropped:function(block_id){this.hideAllTheThings();var block=this.findBlockById(block_id);_.isUndefined(block)||_.isEmpty(block.getData())||!block.drop_options.re_render_on_reorder||block.beforeLoadingData()},onBlockDragStart:function(){this.hideBlockControls(),this.$wrapper.addClass("st-outer--is-reordering")},onBlockDragEnd:function(){this.removeBlockDragOver(),this.$wrapper.removeClass("st-outer--is-reordering")},_renderInPosition:function(block){this.block_controls.current_container?this.block_controls.current_container.after(block):this.$wrapper.append(block)},_incrementBlockTypeCount:function(type){this.blockCounts[type]=_.isUndefined(this.blockCounts[type])?1:this.blockCounts[type]+1},_getBlockTypeCount:function(type){return _.isUndefined(this.blockCounts[type])?0:this.blockCounts[type]},_canAddBlockType:function(type){var block_type_limit=this._getBlockTypeLimit(type);return!(0!==block_type_limit&&this._getBlockTypeCount(type)>=block_type_limit)},_blockLimitReached:function(){return 0!==this.options.blockLimit&&this.blocks.length>=this.options.blockLimit},removeBlock:function(block_id){var block=this.findBlockById(block_id),type=_.classify(block.type),controls=block.$el.find(".st-block-controls");controls.length&&(this.block_controls.hide(),this.$wrapper.prepend(controls)),this.blockCounts[type]=this.blockCounts[type]-1,this.blocks=_.reject(this.blocks,function(item){return item.blockID==block.blockID}),this.stopListening(block),block.remove(),SirTrevor.EventBus.trigger("block:remove",block),this.triggerBlockCountUpdate(),this.$wrapper.toggleClass("st--block-limit-reached",this._blockLimitReached())},performValidations:function(block,should_validate){var errors=0;return!SirTrevor.SKIP_VALIDATION&&should_validate&&(block.valid()||(this.errors.push({text:_.result(block,"validationFailMsg")}),SirTrevor.log("Block "+block.blockID+" failed validation"),++errors)),errors},saveBlockStateToStore:function(block){var store=block.saveAndReturnData();store&&!_.isEmpty(store.data)&&(SirTrevor.log("Adding data for block "+block.blockID+" to block store"),this.store("add",{data:store}))},onFormSubmit:function(should_validate){return this.removeEmptyBlocks(),should_validate=should_validate===!1?!1:!0,SirTrevor.log("Handling form submission for Editor "+this.ID),this.removeErrors(),this.store("reset"),this.validateBlocks(should_validate),this.validateBlockTypesExist(should_validate),this.renderErrors(),this.store("save"),this.errors.length},findEmptyTextBlocks:function(){var instance=this;return result=[],this.blocks.forEach(function(block){instance.saveBlockStateToStore(block);var data=block.getData();-1===$.inArray(block.type,["Heading","text"])||void 0!==data.text&&""!==data.text.trim()||result.push(block)}),result},findEmptyRemoveBlocks:function(){var instance=this;return result=[],this.blocks.forEach(function(block){instance.saveBlockStateToStore(block),block.removeEmpty&&block.isEmpty()&&result.push(block)}),result},removeEmptyBlocks:function(){var blocksToDelete=this.findEmptyTextBlocks().concat(this.findEmptyRemoveBlocks()),instance=this;blocksToDelete.forEach(function(block){instance.removeBlock(block.blockID)})},validateBlocks:function(should_validate){if(!this.required&&SirTrevor.SKIP_VALIDATION&&!should_validate)return!1;var blockIterator=function(block,index){var _block=_.find(this.blocks,function(b){return b.blockID==$(block).attr("id")});return _.isUndefined(_block)?!1:(this.performValidations(_block,should_validate),void this.saveBlockStateToStore(_block))};_.each(this.$wrapper.find(".st-block"),blockIterator,this)},validateBlockTypesExist:function(should_validate){if(!this.required&&SirTrevor.SKIP_VALIDATION&&!should_validate)return!1;var blockTypeIterator=function(type,index){if(this._isBlockTypeAvailable(type))if(0===this._getBlockTypeCount(type))SirTrevor.log("Failed validation on required block type "+type),this.errors.push({text:i18n.t("errors:type_missing",{type:type})});else{var blocks=_.filter(this.getBlocksByType(type),function(b){return!b.isEmpty()});if(blocks.length>0)return!1;this.errors.push({text:i18n.t("errors:required_type_empty",{type:type})}),SirTrevor.log("A required block type "+type+" is empty")}};_.isArray(this.required)&&_.each(this.required,blockTypeIterator,this)},renderErrors:function(){if(0===this.errors.length)return!1;_.isUndefined(this.$errors)&&(this.$errors=this._errorsContainer());var str="<ul>";_.each(this.errors,function(error){str+='<li class="st-errors__msg">'+error.text+"</li>"}),str+="</ul>",this.$errors.append(str),this.$errors.show()},_errorsContainer:function(){if(_.isUndefined(this.options.errorsContainer)){var $container=$("<div>",{"class":"st-errors",html:"<p>"+i18n.t("errors:title")+" </p>"});return this.$outer.prepend($container),$container}return $element(this.options.errorsContainer)},removeErrors:function(){return 0===this.errors.length?!1:(this.$errors.hide().find("ul").html(""),void(this.errors=[]))},findBlockById:function(block_id){return _.find(this.blocks,function(b){return b.blockID==block_id})},getBlocksByType:function(block_type){return _.filter(this.blocks,function(b){return _.classify(b.type)==block_type})},getBlocksByIDs:function(block_ids){return _.filter(this.blocks,function(b){return _.contains(block_ids,b.blockID)})},getBlockPosition:function($block){return this.$wrapper.find(".st-block").index($block)},_getBlockTypeLimit:function(t){return this._isBlockTypeAvailable(t)?parseInt(_.isUndefined(this.options.blockTypeLimits[t])?0:this.options.blockTypeLimits[t],10):0},_isBlockTypeAvailable:function(t){return!_.isUndefined(this.blockTypes[t])},_ensureAndSetElements:function(){if(_.isUndefined(this.options.el)||_.isEmpty(this.options.el))return SirTrevor.log("You must provide an el"),!1;this.$el=this.options.el,this.el=this.options.el[0],this.$form=this.$el.parents("form");var $outer=$("<div>").attr({id:this.ID,"class":"st-outer",dropzone:"copy link move"}),$wrapper=$("<div>").attr({"class":"st-blocks"});return this.$el.wrap($outer).wrap($wrapper),this.$outer=this.$form.find("#"+this.ID),this.$wrapper=this.$outer.find(".st-blocks"),!0},_createDynamicBlocks:function(){var options=this.options;_.isUndefined(options.dynamicBlocks)||_.each(options.dynamicBlocks,function(dynamicBlockParams,dynamicBlockName){_.each(dynamicBlockParams,function(dynamicBlockParam){var dynamicBlock=SirTrevor.DynamicBlocks[dynamicBlockName](dynamicBlockParam),type=_.classify("DynamicBlock"+dynamicBlockName+dynamicBlock.type);dynamicBlock.type=type,SirTrevor.Blocks[type]=SirTrevor.Block.extend(dynamicBlock),_.isUndefined(options.blockTypes)||options.blockTypes.push(type)})})},_setBlocksTypes:function(){this.blockTypes=_.flattern(_.isUndefined(this.options.blockTypes)?SirTrevor.Blocks:this.options.blockTypes)},_setRequired:function(){_.isArray(this.options.required)&&!_.isEmpty(this.options.required)?this.required=this.options.required:this.required=!1},_extendLocales:function(){function deepObjectExtend(target,source){return _.each(source,function(value,key){target.hasOwnProperty(key)&&"object"==typeof target?deepObjectExtend(target[key],value):target[key]=value}),target}_.isObject(this.options.locales)&&deepObjectExtend(SirTrevor.Locales,this.options.locales)}}),SirTrevorEditor}(),SirTrevor.setDefaults=function(options){SirTrevor.DEFAULTS=_.extend(SirTrevor.DEFAULTS,options||{})},SirTrevor.bindFormSubmit=function(form){formBound||(new SirTrevor.Submittable(form),form.on("submit.sirtrevor",this.onFormSubmit),formBound=!0)},SirTrevor.onBeforeSubmit=function(should_validate){var errors=0;return _.each(SirTrevor.instances,function(inst,i){errors+=inst.onFormSubmit(should_validate)}),SirTrevor.log("Total errors: "+errors),errors},SirTrevor.onFormSubmit=function(ev){var errors=SirTrevor.onBeforeSubmit();errors>0&&(SirTrevor.EventBus.trigger("onError"),ev.preventDefault())},SirTrevor.getInstance=function(identifier){return _.isUndefined(identifier)?this.instances[0]:_.isString(identifier)?_.find(this.instances,function(editor){return editor.ID===identifier}):this.instances[identifier]},SirTrevor.setBlockOptions=function(type,options){var block=SirTrevor.Blocks[type];_.isUndefined(block)||_.extend(block.prototype,options||{})},SirTrevor.runOnAllInstances=function(method){_.has(SirTrevor.Editor.prototype,method)?([].unshift.call(arguments,SirTrevor.instances),_.invoke.apply(_,arguments)):SirTrevor.log("method doesn't exist")}}(jQuery,_);
@@ -0,0 +1 @@
1
+ underscorejs.org
@@ -0,0 +1,9 @@
1
+ ## How to contribute to Underscore.js
2
+
3
+ * Before you open a ticket or send a pull request, [search](https://github.com/documentcloud/underscore/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one.
4
+
5
+ * Before sending a pull request for a feature, be sure to have [tests](http://underscorejs.org/test/).
6
+
7
+ * Use the same coding style as the rest of the [codebase](https://github.com/documentcloud/underscore/blob/master/underscore.js).
8
+
9
+ * In your pull request, do not add documentation or re-build the minified `underscore-min.js` file. We'll do those things before cutting a new release.
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ __
2
+ /\ \ __
3
+ __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____
4
+ /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\
5
+ \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\
6
+ \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
7
+ \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/
8
+ \ \____/
9
+ \/___/
10
+
11
+ Underscore.js is a utility-belt library for JavaScript that provides
12
+ support for the usual functional suspects (each, map, reduce, filter...)
13
+ without extending any core JavaScript objects.
14
+
15
+ For Docs, License, Tests, and pre-packed downloads, see:
16
+ http://underscorejs.org
17
+
18
+ Many thanks to our contributors:
19
+ https://github.com/documentcloud/underscore/contributors
@@ -0,0 +1,10 @@
1
+ desc "Use Uglify JS to compress Underscore.js"
2
+ task :build do
3
+ sh "uglifyjs underscore.js -c \"evaluate=false\" -m -o underscore-min.js"
4
+ end
5
+
6
+ desc "Build the docco documentation"
7
+ task :doc do
8
+ sh "docco underscore.js"
9
+ end
10
+
@@ -0,0 +1,192 @@
1
+ /*--------------------- Layout and Typography ----------------------------*/
2
+ body {
3
+ font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
4
+ font-size: 15px;
5
+ line-height: 22px;
6
+ color: #252519;
7
+ margin: 0; padding: 0;
8
+ }
9
+ a {
10
+ color: #261a3b;
11
+ }
12
+ a:visited {
13
+ color: #261a3b;
14
+ }
15
+ p {
16
+ margin: 0 0 15px 0;
17
+ }
18
+ h1, h2, h3, h4, h5, h6 {
19
+ margin: 0px 0 15px 0;
20
+ }
21
+ h1 {
22
+ margin-top: 40px;
23
+ }
24
+ hr {
25
+ border: 0 none;
26
+ border-top: 1px solid #e5e5ee;
27
+ height: 1px;
28
+ margin: 20px 0;
29
+ }
30
+ #container {
31
+ position: relative;
32
+ }
33
+ #background {
34
+ position: fixed;
35
+ top: 0; left: 525px; right: 0; bottom: 0;
36
+ background: #f5f5ff;
37
+ border-left: 1px solid #e5e5ee;
38
+ z-index: -1;
39
+ }
40
+ #jump_to, #jump_page {
41
+ background: white;
42
+ -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
43
+ -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
44
+ font: 10px Arial;
45
+ text-transform: uppercase;
46
+ cursor: pointer;
47
+ text-align: right;
48
+ }
49
+ #jump_to, #jump_wrapper {
50
+ position: fixed;
51
+ right: 0; top: 0;
52
+ padding: 5px 10px;
53
+ }
54
+ #jump_wrapper {
55
+ padding: 0;
56
+ display: none;
57
+ }
58
+ #jump_to:hover #jump_wrapper {
59
+ display: block;
60
+ }
61
+ #jump_page {
62
+ padding: 5px 0 3px;
63
+ margin: 0 0 25px 25px;
64
+ }
65
+ #jump_page .source {
66
+ display: block;
67
+ padding: 5px 10px;
68
+ text-decoration: none;
69
+ border-top: 1px solid #eee;
70
+ }
71
+ #jump_page .source:hover {
72
+ background: #f5f5ff;
73
+ }
74
+ #jump_page .source:first-child {
75
+ }
76
+ table td {
77
+ border: 0;
78
+ outline: 0;
79
+ }
80
+ td.docs, th.docs {
81
+ max-width: 450px;
82
+ min-width: 450px;
83
+ min-height: 5px;
84
+ padding: 10px 25px 1px 50px;
85
+ overflow-x: hidden;
86
+ vertical-align: top;
87
+ text-align: left;
88
+ }
89
+ .docs pre {
90
+ margin: 15px 0 15px;
91
+ padding-left: 15px;
92
+ }
93
+ .docs p tt, .docs p code {
94
+ background: #f8f8ff;
95
+ border: 1px solid #dedede;
96
+ font-size: 12px;
97
+ padding: 0 0.2em;
98
+ }
99
+ .pilwrap {
100
+ position: relative;
101
+ }
102
+ .pilcrow {
103
+ font: 12px Arial;
104
+ text-decoration: none;
105
+ color: #454545;
106
+ position: absolute;
107
+ top: 3px; left: -20px;
108
+ padding: 1px 2px;
109
+ opacity: 0;
110
+ -webkit-transition: opacity 0.2s linear;
111
+ }
112
+ td.docs:hover .pilcrow {
113
+ opacity: 1;
114
+ }
115
+ td.code, th.code {
116
+ padding: 14px 15px 16px 25px;
117
+ width: 100%;
118
+ vertical-align: top;
119
+ background: #f5f5ff;
120
+ border-left: 1px solid #e5e5ee;
121
+ }
122
+ pre, tt, code {
123
+ font-size: 12px; line-height: 18px;
124
+ font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
125
+ margin: 0; padding: 0;
126
+ }
127
+
128
+
129
+ /*---------------------- Syntax Highlighting -----------------------------*/
130
+ td.linenos { background-color: #f0f0f0; padding-right: 10px; }
131
+ span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
132
+ body .hll { background-color: #ffffcc }
133
+ body .c { color: #408080; font-style: italic } /* Comment */
134
+ body .err { border: 1px solid #FF0000 } /* Error */
135
+ body .k { color: #954121 } /* Keyword */
136
+ body .o { color: #666666 } /* Operator */
137
+ body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
138
+ body .cp { color: #BC7A00 } /* Comment.Preproc */
139
+ body .c1 { color: #408080; font-style: italic } /* Comment.Single */
140
+ body .cs { color: #408080; font-style: italic } /* Comment.Special */
141
+ body .gd { color: #A00000 } /* Generic.Deleted */
142
+ body .ge { font-style: italic } /* Generic.Emph */
143
+ body .gr { color: #FF0000 } /* Generic.Error */
144
+ body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
145
+ body .gi { color: #00A000 } /* Generic.Inserted */
146
+ body .go { color: #808080 } /* Generic.Output */
147
+ body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
148
+ body .gs { font-weight: bold } /* Generic.Strong */
149
+ body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
150
+ body .gt { color: #0040D0 } /* Generic.Traceback */
151
+ body .kc { color: #954121 } /* Keyword.Constant */
152
+ body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
153
+ body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
154
+ body .kp { color: #954121 } /* Keyword.Pseudo */
155
+ body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
156
+ body .kt { color: #B00040 } /* Keyword.Type */
157
+ body .m { color: #666666 } /* Literal.Number */
158
+ body .s { color: #219161 } /* Literal.String */
159
+ body .na { color: #7D9029 } /* Name.Attribute */
160
+ body .nb { color: #954121 } /* Name.Builtin */
161
+ body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
162
+ body .no { color: #880000 } /* Name.Constant */
163
+ body .nd { color: #AA22FF } /* Name.Decorator */
164
+ body .ni { color: #999999; font-weight: bold } /* Name.Entity */
165
+ body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
166
+ body .nf { color: #0000FF } /* Name.Function */
167
+ body .nl { color: #A0A000 } /* Name.Label */
168
+ body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
169
+ body .nt { color: #954121; font-weight: bold } /* Name.Tag */
170
+ body .nv { color: #19469D } /* Name.Variable */
171
+ body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
172
+ body .w { color: #bbbbbb } /* Text.Whitespace */
173
+ body .mf { color: #666666 } /* Literal.Number.Float */
174
+ body .mh { color: #666666 } /* Literal.Number.Hex */
175
+ body .mi { color: #666666 } /* Literal.Number.Integer */
176
+ body .mo { color: #666666 } /* Literal.Number.Oct */
177
+ body .sb { color: #219161 } /* Literal.String.Backtick */
178
+ body .sc { color: #219161 } /* Literal.String.Char */
179
+ body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
180
+ body .s2 { color: #219161 } /* Literal.String.Double */
181
+ body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
182
+ body .sh { color: #219161 } /* Literal.String.Heredoc */
183
+ body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
184
+ body .sx { color: #954121 } /* Literal.String.Other */
185
+ body .sr { color: #BB6688 } /* Literal.String.Regex */
186
+ body .s1 { color: #219161 } /* Literal.String.Single */
187
+ body .ss { color: #19469D } /* Literal.String.Symbol */
188
+ body .bp { color: #954121 } /* Name.Builtin.Pseudo */
189
+ body .vc { color: #19469D } /* Name.Variable.Class */
190
+ body .vg { color: #19469D } /* Name.Variable.Global */
191
+ body .vi { color: #19469D } /* Name.Variable.Instance */
192
+ body .il { color: #666666 } /* Literal.Number.Integer.Long */
@@ -0,0 +1,823 @@
1
+ <!DOCTYPE html> <html> <head> <title>underscore.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> underscore.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <pre><code>Underscore.js 1.4.4
2
+ http://underscorejs.org
3
+ (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
4
+ Underscore may be freely distributed under the MIT license.
5
+ </code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <h2>Baseline setup</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Establish the root object, <code>window</code> in the browser, or <code>global</code> on the server.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">root</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Save the previous value of the <code>_</code> variable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">previousUnderscore</span> <span class="o">=</span> <span class="nx">root</span><span class="p">.</span><span class="nx">_</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Establish the object that gets returned to break out of a loop iteration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">breaker</span> <span class="o">=</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Save bytes in the minified (but not gzipped) version:</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">ArrayProto</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="nx">ObjProto</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="nx">FuncProto</span> <span class="o">=</span> <span class="nb">Function</span><span class="p">.</span><span class="nx">prototype</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Create quick reference variables for speed access to core prototypes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">push</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">push</span><span class="p">,</span>
6
+ <span class="nx">slice</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">slice</span><span class="p">,</span>
7
+ <span class="nx">concat</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">concat</span><span class="p">,</span>
8
+ <span class="nx">toString</span> <span class="o">=</span> <span class="nx">ObjProto</span><span class="p">.</span><span class="nx">toString</span><span class="p">,</span>
9
+ <span class="nx">hasOwnProperty</span> <span class="o">=</span> <span class="nx">ObjProto</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>All <strong>ECMAScript 5</strong> native function implementations that we hope to use
10
+ are declared here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span>
11
+ <span class="nx">nativeForEach</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">forEach</span><span class="p">,</span>
12
+ <span class="nx">nativeMap</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">map</span><span class="p">,</span>
13
+ <span class="nx">nativeReduce</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">reduce</span><span class="p">,</span>
14
+ <span class="nx">nativeReduceRight</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">reduceRight</span><span class="p">,</span>
15
+ <span class="nx">nativeFilter</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">filter</span><span class="p">,</span>
16
+ <span class="nx">nativeEvery</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">every</span><span class="p">,</span>
17
+ <span class="nx">nativeSome</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">some</span><span class="p">,</span>
18
+ <span class="nx">nativeIndexOf</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">,</span>
19
+ <span class="nx">nativeLastIndexOf</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">lastIndexOf</span><span class="p">,</span>
20
+ <span class="nx">nativeIsArray</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">isArray</span><span class="p">,</span>
21
+ <span class="nx">nativeKeys</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">,</span>
22
+ <span class="nx">nativeBind</span> <span class="o">=</span> <span class="nx">FuncProto</span><span class="p">.</span><span class="nx">bind</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Create a safe reference to the Underscore object for use below.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
23
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">_</span><span class="p">)</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">;</span>
24
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="k">this</span> <span class="k">instanceof</span> <span class="nx">_</span><span class="p">))</span> <span class="k">return</span> <span class="k">new</span> <span class="nx">_</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
25
+ <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">;</span>
26
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Export the Underscore object for <strong>Node.js</strong>, with
27
+ backwards-compatibility for the old <code>require()</code> API. If we're in
28
+ the browser, add <code>_</code> as a global object via a string identifier,
29
+ for Closure Compiler "advanced" mode.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">exports</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
30
+ <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">module</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">)</span> <span class="p">{</span>
31
+ <span class="nx">exports</span> <span class="o">=</span> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="nx">_</span><span class="p">;</span>
32
+ <span class="p">}</span>
33
+ <span class="nx">exports</span><span class="p">.</span><span class="nx">_</span> <span class="o">=</span> <span class="nx">_</span><span class="p">;</span>
34
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
35
+ <span class="nx">root</span><span class="p">.</span><span class="nx">_</span> <span class="o">=</span> <span class="nx">_</span><span class="p">;</span>
36
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Current version.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">VERSION</span> <span class="o">=</span> <span class="s1">&#39;1.4.4&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <h2>Collection Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>The cornerstone, an <code>each</code> implementation, aka <code>forEach</code>.
37
+ Handles objects with the built-in <code>forEach</code>, arrays, and raw objects.
38
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>forEach</code> if available.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">each</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">forEach</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
39
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
40
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeForEach</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">forEach</span> <span class="o">===</span> <span class="nx">nativeForEach</span><span class="p">)</span> <span class="p">{</span>
41
+ <span class="nx">obj</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
42
+ <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="o">+</span><span class="nx">obj</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
43
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
44
+ <span class="k">if</span> <span class="p">(</span><span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)</span> <span class="o">===</span> <span class="nx">breaker</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
45
+ <span class="p">}</span>
46
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
47
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
48
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
49
+ <span class="k">if</span> <span class="p">(</span><span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">],</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)</span> <span class="o">===</span> <span class="nx">breaker</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
50
+ <span class="p">}</span>
51
+ <span class="p">}</span>
52
+ <span class="p">}</span>
53
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Return the results of applying the iterator to each element.
54
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>map</code> if available.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">collect</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
55
+ <span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="p">[];</span>
56
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
57
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeMap</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">map</span> <span class="o">===</span> <span class="nx">nativeMap</span><span class="p">)</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
58
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
59
+ <span class="nx">results</span><span class="p">[</span><span class="nx">results</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">);</span>
60
+ <span class="p">});</span>
61
+ <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
62
+ <span class="p">};</span>
63
+
64
+ <span class="kd">var</span> <span class="nx">reduceError</span> <span class="o">=</span> <span class="s1">&#39;Reduce of empty array with no initial value&#39;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p><strong>Reduce</strong> builds up a single result from a list of values, aka <code>inject</code>,
65
+ or <code>foldl</code>. Delegates to <strong>ECMAScript 5</strong>'s native <code>reduce</code> if available.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">reduce</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">foldl</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">inject</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">memo</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
66
+ <span class="kd">var</span> <span class="nx">initial</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">;</span>
67
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">[];</span>
68
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeReduce</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">reduce</span> <span class="o">===</span> <span class="nx">nativeReduce</span><span class="p">)</span> <span class="p">{</span>
69
+ <span class="k">if</span> <span class="p">(</span><span class="nx">context</span><span class="p">)</span> <span class="nx">iterator</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
70
+ <span class="k">return</span> <span class="nx">initial</span> <span class="o">?</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">memo</span><span class="p">)</span> <span class="o">:</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">reduce</span><span class="p">(</span><span class="nx">iterator</span><span class="p">);</span>
71
+ <span class="p">}</span>
72
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
73
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">initial</span><span class="p">)</span> <span class="p">{</span>
74
+ <span class="nx">memo</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
75
+ <span class="nx">initial</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
76
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
77
+ <span class="nx">memo</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">memo</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">);</span>
78
+ <span class="p">}</span>
79
+ <span class="p">});</span>
80
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">initial</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="nx">reduceError</span><span class="p">);</span>
81
+ <span class="k">return</span> <span class="nx">memo</span><span class="p">;</span>
82
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>The right-associative version of reduce, also known as <code>foldr</code>.
83
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>reduceRight</code> if available.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">reduceRight</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">foldr</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">memo</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
84
+ <span class="kd">var</span> <span class="nx">initial</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">;</span>
85
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">[];</span>
86
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeReduceRight</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">reduceRight</span> <span class="o">===</span> <span class="nx">nativeReduceRight</span><span class="p">)</span> <span class="p">{</span>
87
+ <span class="k">if</span> <span class="p">(</span><span class="nx">context</span><span class="p">)</span> <span class="nx">iterator</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
88
+ <span class="k">return</span> <span class="nx">initial</span> <span class="o">?</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">reduceRight</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">memo</span><span class="p">)</span> <span class="o">:</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">reduceRight</span><span class="p">(</span><span class="nx">iterator</span><span class="p">);</span>
89
+ <span class="p">}</span>
90
+ <span class="kd">var</span> <span class="nx">length</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
91
+ <span class="k">if</span> <span class="p">(</span><span class="nx">length</span> <span class="o">!==</span> <span class="o">+</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
92
+ <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
93
+ <span class="nx">length</span> <span class="o">=</span> <span class="nx">keys</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
94
+ <span class="p">}</span>
95
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
96
+ <span class="nx">index</span> <span class="o">=</span> <span class="nx">keys</span> <span class="o">?</span> <span class="nx">keys</span><span class="p">[</span><span class="o">--</span><span class="nx">length</span><span class="p">]</span> <span class="o">:</span> <span class="o">--</span><span class="nx">length</span><span class="p">;</span>
97
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">initial</span><span class="p">)</span> <span class="p">{</span>
98
+ <span class="nx">memo</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
99
+ <span class="nx">initial</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
100
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
101
+ <span class="nx">memo</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">memo</span><span class="p">,</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">index</span><span class="p">],</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">);</span>
102
+ <span class="p">}</span>
103
+ <span class="p">});</span>
104
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">initial</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="nx">reduceError</span><span class="p">);</span>
105
+ <span class="k">return</span> <span class="nx">memo</span><span class="p">;</span>
106
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Return the first value which passes a truth test. Aliased as <code>detect</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">find</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">detect</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
107
+ <span class="kd">var</span> <span class="nx">result</span><span class="p">;</span>
108
+ <span class="nx">any</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
109
+ <span class="k">if</span> <span class="p">(</span><span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">))</span> <span class="p">{</span>
110
+ <span class="nx">result</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
111
+ <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
112
+ <span class="p">}</span>
113
+ <span class="p">});</span>
114
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
115
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Return all the elements that pass a truth test.
116
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>filter</code> if available.
117
+ Aliased as <code>select</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">filter</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">select</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
118
+ <span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="p">[];</span>
119
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
120
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeFilter</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">filter</span> <span class="o">===</span> <span class="nx">nativeFilter</span><span class="p">)</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
121
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
122
+ <span class="k">if</span> <span class="p">(</span><span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">))</span> <span class="nx">results</span><span class="p">[</span><span class="nx">results</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
123
+ <span class="p">});</span>
124
+ <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
125
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>Return all the elements for which a truth test fails.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">reject</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
126
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
127
+ <span class="k">return</span> <span class="o">!</span><span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">);</span>
128
+ <span class="p">},</span> <span class="nx">context</span><span class="p">);</span>
129
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Determine whether all of the elements match a truth test.
130
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>every</code> if available.
131
+ Aliased as <code>all</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">every</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">all</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
132
+ <span class="nx">iterator</span> <span class="o">||</span> <span class="p">(</span><span class="nx">iterator</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">);</span>
133
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
134
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
135
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeEvery</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">every</span> <span class="o">===</span> <span class="nx">nativeEvery</span><span class="p">)</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">every</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
136
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
137
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">result</span> <span class="o">=</span> <span class="nx">result</span> <span class="o">&amp;&amp;</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)))</span> <span class="k">return</span> <span class="nx">breaker</span><span class="p">;</span>
138
+ <span class="p">});</span>
139
+ <span class="k">return</span> <span class="o">!!</span><span class="nx">result</span><span class="p">;</span>
140
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Determine if at least one element in the object matches a truth test.
141
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>some</code> if available.
142
+ Aliased as <code>any</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">any</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">some</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
143
+ <span class="nx">iterator</span> <span class="o">||</span> <span class="p">(</span><span class="nx">iterator</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">);</span>
144
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
145
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
146
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeSome</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">some</span> <span class="o">===</span> <span class="nx">nativeSome</span><span class="p">)</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">);</span>
147
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
148
+ <span class="k">if</span> <span class="p">(</span><span class="nx">result</span> <span class="o">||</span> <span class="p">(</span><span class="nx">result</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)))</span> <span class="k">return</span> <span class="nx">breaker</span><span class="p">;</span>
149
+ <span class="p">});</span>
150
+ <span class="k">return</span> <span class="o">!!</span><span class="nx">result</span><span class="p">;</span>
151
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Determine if the array or object contains a given value (using <code>===</code>).
152
+ Aliased as <code>include</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">contains</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">include</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">target</span><span class="p">)</span> <span class="p">{</span>
153
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
154
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeIndexOf</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">indexOf</span> <span class="o">===</span> <span class="nx">nativeIndexOf</span><span class="p">)</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">target</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
155
+ <span class="k">return</span> <span class="nx">any</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
156
+ <span class="k">return</span> <span class="nx">value</span> <span class="o">===</span> <span class="nx">target</span><span class="p">;</span>
157
+ <span class="p">});</span>
158
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>Invoke a method (with arguments) on every item in a collection.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">invoke</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
159
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
160
+ <span class="kd">var</span> <span class="nx">isFunc</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">method</span><span class="p">);</span>
161
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
162
+ <span class="k">return</span> <span class="p">(</span><span class="nx">isFunc</span> <span class="o">?</span> <span class="nx">method</span> <span class="o">:</span> <span class="nx">value</span><span class="p">[</span><span class="nx">method</span><span class="p">]).</span><span class="nx">apply</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
163
+ <span class="p">});</span>
164
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Convenience version of a common use case of <code>map</code>: fetching a property.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
165
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">){</span> <span class="k">return</span> <span class="nx">value</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span> <span class="p">});</span>
166
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Convenience version of a common use case of <code>filter</code>: selecting only objects
167
+ containing specific <code>key:value</code> pairs.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">where</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">,</span> <span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
168
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">(</span><span class="nx">attrs</span><span class="p">))</span> <span class="k">return</span> <span class="nx">first</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="p">[];</span>
169
+ <span class="k">return</span> <span class="nx">_</span><span class="p">[</span><span class="nx">first</span> <span class="o">?</span> <span class="s1">&#39;find&#39;</span> <span class="o">:</span> <span class="s1">&#39;filter&#39;</span><span class="p">](</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
170
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">attrs</span><span class="p">)</span> <span class="p">{</span>
171
+ <span class="k">if</span> <span class="p">(</span><span class="nx">attrs</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">!==</span> <span class="nx">value</span><span class="p">[</span><span class="nx">key</span><span class="p">])</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
172
+ <span class="p">}</span>
173
+ <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
174
+ <span class="p">});</span>
175
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>Convenience version of a common use case of <code>find</code>: getting the first object
176
+ containing specific <code>key:value</code> pairs.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">findWhere</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">)</span> <span class="p">{</span>
177
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">where</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">attrs</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
178
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>Return the maximum element or (element-based computation).
179
+ Can't optimize arrays of integers longer than 65,535 elements.
180
+ See: https://bugs.webkit.org/show_bug.cgi?id=80797</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">max</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
181
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">iterator</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="o">+</span><span class="nx">obj</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">65535</span><span class="p">)</span> <span class="p">{</span>
182
+ <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nb">Math</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
183
+ <span class="p">}</span>
184
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">iterator</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">(</span><span class="nx">obj</span><span class="p">))</span> <span class="k">return</span> <span class="o">-</span><span class="kc">Infinity</span><span class="p">;</span>
185
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{</span><span class="nx">computed</span> <span class="o">:</span> <span class="o">-</span><span class="kc">Infinity</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="o">-</span><span class="kc">Infinity</span><span class="p">};</span>
186
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
187
+ <span class="kd">var</span> <span class="nx">computed</span> <span class="o">=</span> <span class="nx">iterator</span> <span class="o">?</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="o">:</span> <span class="nx">value</span><span class="p">;</span>
188
+ <span class="nx">computed</span> <span class="o">&gt;=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">computed</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">result</span> <span class="o">=</span> <span class="p">{</span><span class="nx">value</span> <span class="o">:</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">computed</span> <span class="o">:</span> <span class="nx">computed</span><span class="p">});</span>
189
+ <span class="p">});</span>
190
+ <span class="k">return</span> <span class="nx">result</span><span class="p">.</span><span class="nx">value</span><span class="p">;</span>
191
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Return the minimum element (or element-based computation).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">min</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
192
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">iterator</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="o">+</span><span class="nx">obj</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">65535</span><span class="p">)</span> <span class="p">{</span>
193
+ <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nb">Math</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
194
+ <span class="p">}</span>
195
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">iterator</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">(</span><span class="nx">obj</span><span class="p">))</span> <span class="k">return</span> <span class="kc">Infinity</span><span class="p">;</span>
196
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{</span><span class="nx">computed</span> <span class="o">:</span> <span class="kc">Infinity</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="kc">Infinity</span><span class="p">};</span>
197
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
198
+ <span class="kd">var</span> <span class="nx">computed</span> <span class="o">=</span> <span class="nx">iterator</span> <span class="o">?</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="o">:</span> <span class="nx">value</span><span class="p">;</span>
199
+ <span class="nx">computed</span> <span class="o">&lt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">computed</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">result</span> <span class="o">=</span> <span class="p">{</span><span class="nx">value</span> <span class="o">:</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">computed</span> <span class="o">:</span> <span class="nx">computed</span><span class="p">});</span>
200
+ <span class="p">});</span>
201
+ <span class="k">return</span> <span class="nx">result</span><span class="p">.</span><span class="nx">value</span><span class="p">;</span>
202
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>Shuffle an array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">shuffle</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
203
+ <span class="kd">var</span> <span class="nx">rand</span><span class="p">;</span>
204
+ <span class="kd">var</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
205
+ <span class="kd">var</span> <span class="nx">shuffled</span> <span class="o">=</span> <span class="p">[];</span>
206
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
207
+ <span class="nx">rand</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">random</span><span class="p">(</span><span class="nx">index</span><span class="o">++</span><span class="p">);</span>
208
+ <span class="nx">shuffled</span><span class="p">[</span><span class="nx">index</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">shuffled</span><span class="p">[</span><span class="nx">rand</span><span class="p">];</span>
209
+ <span class="nx">shuffled</span><span class="p">[</span><span class="nx">rand</span><span class="p">]</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
210
+ <span class="p">});</span>
211
+ <span class="k">return</span> <span class="nx">shuffled</span><span class="p">;</span>
212
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>An internal function to generate lookup iterators.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">lookupIterator</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
213
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="o">?</span> <span class="nx">value</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">){</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">value</span><span class="p">];</span> <span class="p">};</span>
214
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Sort the object's values by a criterion produced by an iterator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">sortBy</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
215
+ <span class="kd">var</span> <span class="nx">iterator</span> <span class="o">=</span> <span class="nx">lookupIterator</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
216
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span> <span class="p">{</span>
217
+ <span class="k">return</span> <span class="p">{</span>
218
+ <span class="nx">value</span> <span class="o">:</span> <span class="nx">value</span><span class="p">,</span>
219
+ <span class="nx">index</span> <span class="o">:</span> <span class="nx">index</span><span class="p">,</span>
220
+ <span class="nx">criteria</span> <span class="o">:</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">list</span><span class="p">)</span>
221
+ <span class="p">};</span>
222
+ <span class="p">}).</span><span class="nx">sort</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">)</span> <span class="p">{</span>
223
+ <span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">left</span><span class="p">.</span><span class="nx">criteria</span><span class="p">;</span>
224
+ <span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="nx">right</span><span class="p">.</span><span class="nx">criteria</span><span class="p">;</span>
225
+ <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">!==</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
226
+ <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">&gt;</span> <span class="nx">b</span> <span class="o">||</span> <span class="nx">a</span> <span class="o">===</span> <span class="k">void</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
227
+ <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">&lt;</span> <span class="nx">b</span> <span class="o">||</span> <span class="nx">b</span> <span class="o">===</span> <span class="k">void</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
228
+ <span class="p">}</span>
229
+ <span class="k">return</span> <span class="nx">left</span><span class="p">.</span><span class="nx">index</span> <span class="o">&lt;</span> <span class="nx">right</span><span class="p">.</span><span class="nx">index</span> <span class="o">?</span> <span class="o">-</span><span class="mi">1</span> <span class="o">:</span> <span class="mi">1</span><span class="p">;</span>
230
+ <span class="p">}),</span> <span class="s1">&#39;value&#39;</span><span class="p">);</span>
231
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>An internal function used for aggregate "group by" operations.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">group</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">behavior</span><span class="p">)</span> <span class="p">{</span>
232
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{};</span>
233
+ <span class="kd">var</span> <span class="nx">iterator</span> <span class="o">=</span> <span class="nx">lookupIterator</span><span class="p">(</span><span class="nx">value</span> <span class="o">||</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">);</span>
234
+ <span class="nx">each</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
235
+ <span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
236
+ <span class="nx">behavior</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
237
+ <span class="p">});</span>
238
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
239
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>Groups the object's values by a criterion. Pass either a string attribute
240
+ to group by, or a function that returns the criterion.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">groupBy</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
241
+ <span class="k">return</span> <span class="nx">group</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
242
+ <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">?</span> <span class="nx">result</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">:</span> <span class="p">(</span><span class="nx">result</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">[])).</span><span class="nx">push</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
243
+ <span class="p">});</span>
244
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Counts instances of an object that group by a certain criterion. Pass
245
+ either a string attribute to count by, or a function that returns the
246
+ criterion.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">countBy</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
247
+ <span class="k">return</span> <span class="nx">group</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
248
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="nx">result</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
249
+ <span class="nx">result</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
250
+ <span class="p">});</span>
251
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>Use a comparator function to figure out the smallest index at which
252
+ an object should be inserted so as to maintain order. Uses binary search.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">sortedIndex</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
253
+ <span class="nx">iterator</span> <span class="o">=</span> <span class="nx">iterator</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span> <span class="o">:</span> <span class="nx">lookupIterator</span><span class="p">(</span><span class="nx">iterator</span><span class="p">);</span>
254
+ <span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
255
+ <span class="kd">var</span> <span class="nx">low</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">high</span> <span class="o">=</span> <span class="nx">array</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
256
+ <span class="k">while</span> <span class="p">(</span><span class="nx">low</span> <span class="o">&lt;</span> <span class="nx">high</span><span class="p">)</span> <span class="p">{</span>
257
+ <span class="kd">var</span> <span class="nx">mid</span> <span class="o">=</span> <span class="p">(</span><span class="nx">low</span> <span class="o">+</span> <span class="nx">high</span><span class="p">)</span> <span class="o">&gt;&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span>
258
+ <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">array</span><span class="p">[</span><span class="nx">mid</span><span class="p">])</span> <span class="o">&lt;</span> <span class="nx">value</span> <span class="o">?</span> <span class="nx">low</span> <span class="o">=</span> <span class="nx">mid</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="nx">high</span> <span class="o">=</span> <span class="nx">mid</span><span class="p">;</span>
259
+ <span class="p">}</span>
260
+ <span class="k">return</span> <span class="nx">low</span><span class="p">;</span>
261
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>Safely convert anything iterable into a real, live array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">toArray</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
262
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">obj</span><span class="p">)</span> <span class="k">return</span> <span class="p">[];</span>
263
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">obj</span><span class="p">))</span> <span class="k">return</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
264
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="o">+</span><span class="nx">obj</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">);</span>
265
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">values</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
266
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>Return the number of elements in an object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">size</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
267
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
268
+ <span class="k">return</span> <span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="o">+</span><span class="nx">obj</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">?</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">:</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">obj</span><span class="p">).</span><span class="nx">length</span><span class="p">;</span>
269
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <h2>Array Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>Get the first element of an array. Passing <strong>n</strong> will return the first N
270
+ values in the array. Aliased as <code>head</code> and <code>take</code>. The <strong>guard</strong> check
271
+ allows it to work with <code>_.map</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">first</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">head</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">take</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">guard</span><span class="p">)</span> <span class="p">{</span>
272
+ <span class="k">if</span> <span class="p">(</span><span class="nx">array</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="k">void</span> <span class="mi">0</span><span class="p">;</span>
273
+ <span class="k">return</span> <span class="p">(</span><span class="nx">n</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">guard</span> <span class="o">?</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">n</span><span class="p">)</span> <span class="o">:</span> <span class="nx">array</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
274
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>Returns everything but the last entry of the array. Especially useful on
275
+ the arguments object. Passing <strong>n</strong> will return all the values in
276
+ the array, excluding the last N. The <strong>guard</strong> check allows it to work with
277
+ <code>_.map</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">initial</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">guard</span><span class="p">)</span> <span class="p">{</span>
278
+ <span class="k">return</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">array</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="p">((</span><span class="nx">n</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="o">||</span> <span class="nx">guard</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="nx">n</span><span class="p">));</span>
279
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>Get the last element of an array. Passing <strong>n</strong> will return the last N
280
+ values in the array. The <strong>guard</strong> check allows it to work with <code>_.map</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">last</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">guard</span><span class="p">)</span> <span class="p">{</span>
281
+ <span class="k">if</span> <span class="p">(</span><span class="nx">array</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="k">void</span> <span class="mi">0</span><span class="p">;</span>
282
+ <span class="k">if</span> <span class="p">((</span><span class="nx">n</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">guard</span><span class="p">)</span> <span class="p">{</span>
283
+ <span class="k">return</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">array</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">n</span><span class="p">,</span> <span class="mi">0</span><span class="p">));</span>
284
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
285
+ <span class="k">return</span> <span class="nx">array</span><span class="p">[</span><span class="nx">array</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>
286
+ <span class="p">}</span>
287
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>Returns everything but the first entry of the array. Aliased as <code>tail</code> and <code>drop</code>.
288
+ Especially useful on the arguments object. Passing an <strong>n</strong> will return
289
+ the rest N values in the array. The <strong>guard</strong>
290
+ check allows it to work with <code>_.map</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">rest</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">tail</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">drop</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">guard</span><span class="p">)</span> <span class="p">{</span>
291
+ <span class="k">return</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="p">(</span><span class="nx">n</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="o">||</span> <span class="nx">guard</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">:</span> <span class="nx">n</span><span class="p">);</span>
292
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>Trim out all falsy values from an array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">compact</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="p">{</span>
293
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">);</span>
294
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Internal implementation of a recursive <code>flatten</code> function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">flatten</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">shallow</span><span class="p">,</span> <span class="nx">output</span><span class="p">)</span> <span class="p">{</span>
295
+ <span class="nx">each</span><span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
296
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">value</span><span class="p">))</span> <span class="p">{</span>
297
+ <span class="nx">shallow</span> <span class="o">?</span> <span class="nx">push</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">output</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">:</span> <span class="nx">flatten</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">shallow</span><span class="p">,</span> <span class="nx">output</span><span class="p">);</span>
298
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
299
+ <span class="nx">output</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
300
+ <span class="p">}</span>
301
+ <span class="p">});</span>
302
+ <span class="k">return</span> <span class="nx">output</span><span class="p">;</span>
303
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>Return a completely flattened version of an array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">flatten</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">shallow</span><span class="p">)</span> <span class="p">{</span>
304
+ <span class="k">return</span> <span class="nx">flatten</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">shallow</span><span class="p">,</span> <span class="p">[]);</span>
305
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Return a version of the array that does not contain the specified value(s).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">without</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="p">{</span>
306
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">difference</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
307
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Produce a duplicate-free version of the array. If the array has already
308
+ been sorted, you have the option of using a faster algorithm.
309
+ Aliased as <code>unique</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">uniq</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">unique</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">isSorted</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
310
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">isSorted</span><span class="p">))</span> <span class="p">{</span>
311
+ <span class="nx">context</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">;</span>
312
+ <span class="nx">iterator</span> <span class="o">=</span> <span class="nx">isSorted</span><span class="p">;</span>
313
+ <span class="nx">isSorted</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
314
+ <span class="p">}</span>
315
+ <span class="kd">var</span> <span class="nx">initial</span> <span class="o">=</span> <span class="nx">iterator</span> <span class="o">?</span> <span class="nx">_</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="o">:</span> <span class="nx">array</span><span class="p">;</span>
316
+ <span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="p">[];</span>
317
+ <span class="kd">var</span> <span class="nx">seen</span> <span class="o">=</span> <span class="p">[];</span>
318
+ <span class="nx">each</span><span class="p">(</span><span class="nx">initial</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
319
+ <span class="k">if</span> <span class="p">(</span><span class="nx">isSorted</span> <span class="o">?</span> <span class="p">(</span><span class="o">!</span><span class="nx">index</span> <span class="o">||</span> <span class="nx">seen</span><span class="p">[</span><span class="nx">seen</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">!==</span> <span class="nx">value</span><span class="p">)</span> <span class="o">:</span> <span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">contains</span><span class="p">(</span><span class="nx">seen</span><span class="p">,</span> <span class="nx">value</span><span class="p">))</span> <span class="p">{</span>
320
+ <span class="nx">seen</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
321
+ <span class="nx">results</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">array</span><span class="p">[</span><span class="nx">index</span><span class="p">]);</span>
322
+ <span class="p">}</span>
323
+ <span class="p">});</span>
324
+ <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
325
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Produce an array that contains the union: each distinct element from all of
326
+ the passed-in arrays.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">union</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
327
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">uniq</span><span class="p">(</span><span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">ArrayProto</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
328
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>Produce an array that contains every item shared between all the
329
+ passed-in arrays.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">intersection</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="p">{</span>
330
+ <span class="kd">var</span> <span class="nx">rest</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
331
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">uniq</span><span class="p">(</span><span class="nx">array</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
332
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">every</span><span class="p">(</span><span class="nx">rest</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">other</span><span class="p">)</span> <span class="p">{</span>
333
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">other</span><span class="p">,</span> <span class="nx">item</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span>
334
+ <span class="p">});</span>
335
+ <span class="p">});</span>
336
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>Take the difference between one array and a number of other arrays.
337
+ Only the elements present in just the first array will remain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">difference</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="p">{</span>
338
+ <span class="kd">var</span> <span class="nx">rest</span> <span class="o">=</span> <span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">ArrayProto</span><span class="p">,</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
339
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">){</span> <span class="k">return</span> <span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">contains</span><span class="p">(</span><span class="nx">rest</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span> <span class="p">});</span>
340
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>Zip together multiple lists into a single array -- elements that share
341
+ an index go together.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">zip</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
342
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
343
+ <span class="kd">var</span> <span class="nx">length</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="s1">&#39;length&#39;</span><span class="p">));</span>
344
+ <span class="kd">var</span> <span class="nx">results</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">length</span><span class="p">);</span>
345
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
346
+ <span class="nx">results</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="s2">&quot;&quot;</span> <span class="o">+</span> <span class="nx">i</span><span class="p">);</span>
347
+ <span class="p">}</span>
348
+ <span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
349
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Converts lists into objects. Pass either a single array of <code>[key, value]</code>
350
+ pairs, or two parallel arrays of the same length -- one of keys, and one of
351
+ the corresponding values.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">values</span><span class="p">)</span> <span class="p">{</span>
352
+ <span class="k">if</span> <span class="p">(</span><span class="nx">list</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="p">{};</span>
353
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{};</span>
354
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">list</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
355
+ <span class="k">if</span> <span class="p">(</span><span class="nx">values</span><span class="p">)</span> <span class="p">{</span>
356
+ <span class="nx">result</span><span class="p">[</span><span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">values</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
357
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
358
+ <span class="nx">result</span><span class="p">[</span><span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
359
+ <span class="p">}</span>
360
+ <span class="p">}</span>
361
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
362
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>If the browser doesn't supply us with indexOf (I'm looking at you, <strong>MSIE</strong>),
363
+ we need this function. Return the position of the first occurrence of an
364
+ item in an array, or -1 if the item is not included in the array.
365
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>indexOf</code> if available.
366
+ If the array is large and already in sort order, pass <code>true</code>
367
+ for <strong>isSorted</strong> to use binary search.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">isSorted</span><span class="p">)</span> <span class="p">{</span>
368
+ <span class="k">if</span> <span class="p">(</span><span class="nx">array</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
369
+ <span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">=</span> <span class="nx">array</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
370
+ <span class="k">if</span> <span class="p">(</span><span class="nx">isSorted</span><span class="p">)</span> <span class="p">{</span>
371
+ <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">isSorted</span> <span class="o">==</span> <span class="s1">&#39;number&#39;</span><span class="p">)</span> <span class="p">{</span>
372
+ <span class="nx">i</span> <span class="o">=</span> <span class="p">(</span><span class="nx">isSorted</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">l</span> <span class="o">+</span> <span class="nx">isSorted</span><span class="p">)</span> <span class="o">:</span> <span class="nx">isSorted</span><span class="p">);</span>
373
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
374
+ <span class="nx">i</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">sortedIndex</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">item</span><span class="p">);</span>
375
+ <span class="k">return</span> <span class="nx">array</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">===</span> <span class="nx">item</span> <span class="o">?</span> <span class="nx">i</span> <span class="o">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
376
+ <span class="p">}</span>
377
+ <span class="p">}</span>
378
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeIndexOf</span> <span class="o">&amp;&amp;</span> <span class="nx">array</span><span class="p">.</span><span class="nx">indexOf</span> <span class="o">===</span> <span class="nx">nativeIndexOf</span><span class="p">)</span> <span class="k">return</span> <span class="nx">array</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="nx">isSorted</span><span class="p">);</span>
379
+ <span class="k">for</span> <span class="p">(;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">l</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">array</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">===</span> <span class="nx">item</span><span class="p">)</span> <span class="k">return</span> <span class="nx">i</span><span class="p">;</span>
380
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
381
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p>Delegates to <strong>ECMAScript 5</strong>'s native <code>lastIndexOf</code> if available.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">lastIndexOf</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">from</span><span class="p">)</span> <span class="p">{</span>
382
+ <span class="k">if</span> <span class="p">(</span><span class="nx">array</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
383
+ <span class="kd">var</span> <span class="nx">hasIndex</span> <span class="o">=</span> <span class="nx">from</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">;</span>
384
+ <span class="k">if</span> <span class="p">(</span><span class="nx">nativeLastIndexOf</span> <span class="o">&amp;&amp;</span> <span class="nx">array</span><span class="p">.</span><span class="nx">lastIndexOf</span> <span class="o">===</span> <span class="nx">nativeLastIndexOf</span><span class="p">)</span> <span class="p">{</span>
385
+ <span class="k">return</span> <span class="nx">hasIndex</span> <span class="o">?</span> <span class="nx">array</span><span class="p">.</span><span class="nx">lastIndexOf</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="nx">from</span><span class="p">)</span> <span class="o">:</span> <span class="nx">array</span><span class="p">.</span><span class="nx">lastIndexOf</span><span class="p">(</span><span class="nx">item</span><span class="p">);</span>
386
+ <span class="p">}</span>
387
+ <span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="p">(</span><span class="nx">hasIndex</span> <span class="o">?</span> <span class="nx">from</span> <span class="o">:</span> <span class="nx">array</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
388
+ <span class="k">while</span> <span class="p">(</span><span class="nx">i</span><span class="o">--</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">array</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">===</span> <span class="nx">item</span><span class="p">)</span> <span class="k">return</span> <span class="nx">i</span><span class="p">;</span>
389
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
390
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>Generate an integer Array containing an arithmetic progression. A port of
391
+ the native Python <code>range()</code> function. See
392
+ <a href="http://docs.python.org/library/functions.html#range">the Python documentation</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">range</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">stop</span><span class="p">,</span> <span class="nx">step</span><span class="p">)</span> <span class="p">{</span>
393
+ <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
394
+ <span class="nx">stop</span> <span class="o">=</span> <span class="nx">start</span> <span class="o">||</span> <span class="mi">0</span><span class="p">;</span>
395
+ <span class="nx">start</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
396
+ <span class="p">}</span>
397
+ <span class="nx">step</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">||</span> <span class="mi">1</span><span class="p">;</span>
398
+
399
+ <span class="kd">var</span> <span class="nx">len</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">ceil</span><span class="p">((</span><span class="nx">stop</span> <span class="o">-</span> <span class="nx">start</span><span class="p">)</span> <span class="o">/</span> <span class="nx">step</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span>
400
+ <span class="kd">var</span> <span class="nx">idx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
401
+ <span class="kd">var</span> <span class="nx">range</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">len</span><span class="p">);</span>
402
+
403
+ <span class="k">while</span><span class="p">(</span><span class="nx">idx</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
404
+ <span class="nx">range</span><span class="p">[</span><span class="nx">idx</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="nx">start</span><span class="p">;</span>
405
+ <span class="nx">start</span> <span class="o">+=</span> <span class="nx">step</span><span class="p">;</span>
406
+ <span class="p">}</span>
407
+
408
+ <span class="k">return</span> <span class="nx">range</span><span class="p">;</span>
409
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <h2>Function (ahem) Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>Create a function bound to a given object (assigning <code>this</code>, and arguments,
410
+ optionally). Delegates to <strong>ECMAScript 5</strong>'s native <code>Function.bind</code> if
411
+ available.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
412
+ <span class="k">if</span> <span class="p">(</span><span class="nx">func</span><span class="p">.</span><span class="nx">bind</span> <span class="o">===</span> <span class="nx">nativeBind</span> <span class="o">&amp;&amp;</span> <span class="nx">nativeBind</span><span class="p">)</span> <span class="k">return</span> <span class="nx">nativeBind</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
413
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
414
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
415
+ <span class="k">return</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">args</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">)));</span>
416
+ <span class="p">};</span>
417
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>Partially apply a function by creating a version that has had some of its
418
+ arguments pre-filled, without changing its dynamic <code>this</code> context.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">partial</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">)</span> <span class="p">{</span>
419
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
420
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
421
+ <span class="k">return</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">)));</span>
422
+ <span class="p">};</span>
423
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>Bind all of an object's methods to that object. Useful for ensuring that
424
+ all callbacks defined on an object belong to it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">bindAll</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
425
+ <span class="kd">var</span> <span class="nx">funcs</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
426
+ <span class="k">if</span> <span class="p">(</span><span class="nx">funcs</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="nx">funcs</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">functions</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
427
+ <span class="nx">each</span><span class="p">(</span><span class="nx">funcs</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">f</span><span class="p">)</span> <span class="p">{</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">f</span><span class="p">]</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">[</span><span class="nx">f</span><span class="p">],</span> <span class="nx">obj</span><span class="p">);</span> <span class="p">});</span>
428
+ <span class="k">return</span> <span class="nx">obj</span><span class="p">;</span>
429
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>Memoize an expensive function by storing its results.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">memoize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">hasher</span><span class="p">)</span> <span class="p">{</span>
430
+ <span class="kd">var</span> <span class="nx">memo</span> <span class="o">=</span> <span class="p">{};</span>
431
+ <span class="nx">hasher</span> <span class="o">||</span> <span class="p">(</span><span class="nx">hasher</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span><span class="p">);</span>
432
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
433
+ <span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">hasher</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
434
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">memo</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">?</span> <span class="nx">memo</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">:</span> <span class="p">(</span><span class="nx">memo</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
435
+ <span class="p">};</span>
436
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>Delays a function for the given number of milliseconds, and then calls
437
+ it with the arguments supplied.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">delay</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">wait</span><span class="p">)</span> <span class="p">{</span>
438
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
439
+ <span class="k">return</span> <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span> <span class="p">},</span> <span class="nx">wait</span><span class="p">);</span>
440
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <p>Defers a function, scheduling it to run after the current call stack has
441
+ cleared.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">defer</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">)</span> <span class="p">{</span>
442
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">delay</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="p">[</span><span class="nx">func</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nx">concat</span><span class="p">(</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">)));</span>
443
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <p>Returns a function, that, when invoked, will only be triggered at most once
444
+ during a given window of time.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">throttle</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">wait</span><span class="p">)</span> <span class="p">{</span>
445
+ <span class="kd">var</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">args</span><span class="p">,</span> <span class="nx">timeout</span><span class="p">,</span> <span class="nx">result</span><span class="p">;</span>
446
+ <span class="kd">var</span> <span class="nx">previous</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
447
+ <span class="kd">var</span> <span class="nx">later</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
448
+ <span class="nx">previous</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">;</span>
449
+ <span class="nx">timeout</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
450
+ <span class="nx">result</span> <span class="o">=</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
451
+ <span class="p">};</span>
452
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
453
+ <span class="kd">var</span> <span class="nx">now</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">;</span>
454
+ <span class="kd">var</span> <span class="nx">remaining</span> <span class="o">=</span> <span class="nx">wait</span> <span class="o">-</span> <span class="p">(</span><span class="nx">now</span> <span class="o">-</span> <span class="nx">previous</span><span class="p">);</span>
455
+ <span class="nx">context</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
456
+ <span class="nx">args</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">;</span>
457
+ <span class="k">if</span> <span class="p">(</span><span class="nx">remaining</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
458
+ <span class="nx">clearTimeout</span><span class="p">(</span><span class="nx">timeout</span><span class="p">);</span>
459
+ <span class="nx">timeout</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
460
+ <span class="nx">previous</span> <span class="o">=</span> <span class="nx">now</span><span class="p">;</span>
461
+ <span class="nx">result</span> <span class="o">=</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
462
+ <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">timeout</span><span class="p">)</span> <span class="p">{</span>
463
+ <span class="nx">timeout</span> <span class="o">=</span> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">later</span><span class="p">,</span> <span class="nx">remaining</span><span class="p">);</span>
464
+ <span class="p">}</span>
465
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
466
+ <span class="p">};</span>
467
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>Returns a function, that, as long as it continues to be invoked, will not
468
+ be triggered. The function will be called after it stops being called for
469
+ N milliseconds. If <code>immediate</code> is passed, trigger the function on the
470
+ leading edge, instead of the trailing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">debounce</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">wait</span><span class="p">,</span> <span class="nx">immediate</span><span class="p">)</span> <span class="p">{</span>
471
+ <span class="kd">var</span> <span class="nx">timeout</span><span class="p">,</span> <span class="nx">result</span><span class="p">;</span>
472
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
473
+ <span class="kd">var</span> <span class="nx">context</span> <span class="o">=</span> <span class="k">this</span><span class="p">,</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">;</span>
474
+ <span class="kd">var</span> <span class="nx">later</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
475
+ <span class="nx">timeout</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
476
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">immediate</span><span class="p">)</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
477
+ <span class="p">};</span>
478
+ <span class="kd">var</span> <span class="nx">callNow</span> <span class="o">=</span> <span class="nx">immediate</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">timeout</span><span class="p">;</span>
479
+ <span class="nx">clearTimeout</span><span class="p">(</span><span class="nx">timeout</span><span class="p">);</span>
480
+ <span class="nx">timeout</span> <span class="o">=</span> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">later</span><span class="p">,</span> <span class="nx">wait</span><span class="p">);</span>
481
+ <span class="k">if</span> <span class="p">(</span><span class="nx">callNow</span><span class="p">)</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
482
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
483
+ <span class="p">};</span>
484
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p>Returns a function that will be executed at most one time, no matter how
485
+ often you call it. Useful for lazy initialization.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">once</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">)</span> <span class="p">{</span>
486
+ <span class="kd">var</span> <span class="nx">ran</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">memo</span><span class="p">;</span>
487
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
488
+ <span class="k">if</span> <span class="p">(</span><span class="nx">ran</span><span class="p">)</span> <span class="k">return</span> <span class="nx">memo</span><span class="p">;</span>
489
+ <span class="nx">ran</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
490
+ <span class="nx">memo</span> <span class="o">=</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
491
+ <span class="nx">func</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
492
+ <span class="k">return</span> <span class="nx">memo</span><span class="p">;</span>
493
+ <span class="p">};</span>
494
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>Returns the first function passed as an argument to the second,
495
+ allowing you to adjust arguments, run code before and after, and
496
+ conditionally execute the original function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">wrap</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">wrapper</span><span class="p">)</span> <span class="p">{</span>
497
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
498
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="p">[</span><span class="nx">func</span><span class="p">];</span>
499
+ <span class="nx">push</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
500
+ <span class="k">return</span> <span class="nx">wrapper</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
501
+ <span class="p">};</span>
502
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <p>Returns a function that is the composition of a list of functions, each
503
+ consuming the return value of the function that follows.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">compose</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
504
+ <span class="kd">var</span> <span class="nx">funcs</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">;</span>
505
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
506
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">;</span>
507
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">funcs</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
508
+ <span class="nx">args</span> <span class="o">=</span> <span class="p">[</span><span class="nx">funcs</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">)];</span>
509
+ <span class="p">}</span>
510
+ <span class="k">return</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
511
+ <span class="p">};</span>
512
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">&#182;</a> </div> <p>Returns a function that will only be executed after being called N times.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">after</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">times</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="p">{</span>
513
+ <span class="k">if</span> <span class="p">(</span><span class="nx">times</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="nx">func</span><span class="p">();</span>
514
+ <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
515
+ <span class="k">if</span> <span class="p">(</span><span class="o">--</span><span class="nx">times</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
516
+ <span class="k">return</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
517
+ <span class="p">}</span>
518
+ <span class="p">};</span>
519
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">&#182;</a> </div> <h2>Object Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">&#182;</a> </div> <p>Retrieve the names of an object's properties.
520
+ Delegates to <strong>ECMAScript 5</strong>'s native <code>Object.keys</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span> <span class="o">=</span> <span class="nx">nativeKeys</span> <span class="o">||</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
521
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">!==</span> <span class="nb">Object</span><span class="p">(</span><span class="nx">obj</span><span class="p">))</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s1">&#39;Invalid object&#39;</span><span class="p">);</span>
522
+ <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="p">[];</span>
523
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="nx">keys</span><span class="p">[</span><span class="nx">keys</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span> <span class="o">=</span> <span class="nx">key</span><span class="p">;</span>
524
+ <span class="k">return</span> <span class="nx">keys</span><span class="p">;</span>
525
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">&#182;</a> </div> <p>Retrieve the values of an object's properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">values</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
526
+ <span class="kd">var</span> <span class="nx">values</span> <span class="o">=</span> <span class="p">[];</span>
527
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="nx">values</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]);</span>
528
+ <span class="k">return</span> <span class="nx">values</span><span class="p">;</span>
529
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">&#182;</a> </div> <p>Convert an object into a list of <code>[key, value]</code> pairs.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">pairs</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
530
+ <span class="kd">var</span> <span class="nx">pairs</span> <span class="o">=</span> <span class="p">[];</span>
531
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="nx">pairs</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="nx">key</span><span class="p">,</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]]);</span>
532
+ <span class="k">return</span> <span class="nx">pairs</span><span class="p">;</span>
533
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">&#182;</a> </div> <p>Invert the keys and values of an object. The values must be serializable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">invert</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
534
+ <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{};</span>
535
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="nx">result</span><span class="p">[</span><span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">key</span><span class="p">;</span>
536
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
537
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">&#182;</a> </div> <p>Return a sorted list of the function names available on the object.
538
+ Aliased as <code>methods</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">functions</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">methods</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
539
+ <span class="kd">var</span> <span class="nx">names</span> <span class="o">=</span> <span class="p">[];</span>
540
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
541
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]))</span> <span class="nx">names</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
542
+ <span class="p">}</span>
543
+ <span class="k">return</span> <span class="nx">names</span><span class="p">.</span><span class="nx">sort</span><span class="p">();</span>
544
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">&#182;</a> </div> <p>Extend a given object with all the properties in passed-in object(s).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
545
+ <span class="nx">each</span><span class="p">(</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="p">{</span>
546
+ <span class="k">if</span> <span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="p">{</span>
547
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">source</span><span class="p">)</span> <span class="p">{</span>
548
+ <span class="nx">obj</span><span class="p">[</span><span class="nx">prop</span><span class="p">]</span> <span class="o">=</span> <span class="nx">source</span><span class="p">[</span><span class="nx">prop</span><span class="p">];</span>
549
+ <span class="p">}</span>
550
+ <span class="p">}</span>
551
+ <span class="p">});</span>
552
+ <span class="k">return</span> <span class="nx">obj</span><span class="p">;</span>
553
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-76">&#182;</a> </div> <p>Return a copy of the object only containing the whitelisted properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">pick</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
554
+ <span class="kd">var</span> <span class="nx">copy</span> <span class="o">=</span> <span class="p">{};</span>
555
+ <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">ArrayProto</span><span class="p">,</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
556
+ <span class="nx">each</span><span class="p">(</span><span class="nx">keys</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
557
+ <span class="k">if</span> <span class="p">(</span><span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="nx">copy</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
558
+ <span class="p">});</span>
559
+ <span class="k">return</span> <span class="nx">copy</span><span class="p">;</span>
560
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-77">&#182;</a> </div> <p>Return a copy of the object without the blacklisted properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">omit</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
561
+ <span class="kd">var</span> <span class="nx">copy</span> <span class="o">=</span> <span class="p">{};</span>
562
+ <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nx">concat</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">ArrayProto</span><span class="p">,</span> <span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
563
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
564
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">contains</span><span class="p">(</span><span class="nx">keys</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="nx">copy</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
565
+ <span class="p">}</span>
566
+ <span class="k">return</span> <span class="nx">copy</span><span class="p">;</span>
567
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-78">&#182;</a> </div> <p>Fill in a given object with default properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">defaults</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
568
+ <span class="nx">each</span><span class="p">(</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="p">{</span>
569
+ <span class="k">if</span> <span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="p">{</span>
570
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">source</span><span class="p">)</span> <span class="p">{</span>
571
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span><span class="p">[</span><span class="nx">prop</span><span class="p">]</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">prop</span><span class="p">]</span> <span class="o">=</span> <span class="nx">source</span><span class="p">[</span><span class="nx">prop</span><span class="p">];</span>
572
+ <span class="p">}</span>
573
+ <span class="p">}</span>
574
+ <span class="p">});</span>
575
+ <span class="k">return</span> <span class="nx">obj</span><span class="p">;</span>
576
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">&#182;</a> </div> <p>Create a (shallow-cloned) duplicate of an object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">clone</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
577
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">isObject</span><span class="p">(</span><span class="nx">obj</span><span class="p">))</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">;</span>
578
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">?</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">slice</span><span class="p">()</span> <span class="o">:</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">({},</span> <span class="nx">obj</span><span class="p">);</span>
579
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">&#182;</a> </div> <p>Invokes interceptor with the obj, and then returns obj.
580
+ The primary purpose of this method is to "tap into" a method chain, in
581
+ order to perform operations on intermediate results within the chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">tap</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">interceptor</span><span class="p">)</span> <span class="p">{</span>
582
+ <span class="nx">interceptor</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
583
+ <span class="k">return</span> <span class="nx">obj</span><span class="p">;</span>
584
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-81">&#182;</a> </div> <p>Internal recursive comparison function for <code>isEqual</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">eq</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">,</span> <span class="nx">aStack</span><span class="p">,</span> <span class="nx">bStack</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-82">&#182;</a> </div> <p>Identical objects are equal. <code>0 === -0</code>, but they aren't identical.
585
+ See the Harmony <code>egal</code> proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">===</span> <span class="nx">b</span><span class="p">)</span> <span class="k">return</span> <span class="nx">a</span> <span class="o">!==</span> <span class="mi">0</span> <span class="o">||</span> <span class="mi">1</span> <span class="o">/</span> <span class="nx">a</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">/</span> <span class="nx">b</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-83">&#182;</a> </div> <p>A strict comparison is necessary because <code>null == undefined</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="nx">b</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="nx">a</span> <span class="o">===</span> <span class="nx">b</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">&#182;</a> </div> <p>Unwrap any wrapped objects.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="k">instanceof</span> <span class="nx">_</span><span class="p">)</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">a</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
586
+ <span class="k">if</span> <span class="p">(</span><span class="nx">b</span> <span class="k">instanceof</span> <span class="nx">_</span><span class="p">)</span> <span class="nx">b</span> <span class="o">=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-85">&#182;</a> </div> <p>Compare <code>[[Class]]</code> names.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">className</span> <span class="o">=</span> <span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">a</span><span class="p">);</span>
587
+ <span class="k">if</span> <span class="p">(</span><span class="nx">className</span> <span class="o">!=</span> <span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">b</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
588
+ <span class="k">switch</span> <span class="p">(</span><span class="nx">className</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-86">&#182;</a> </div> <p>Strings, numbers, dates, and booleans are compared by value.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="s1">&#39;[object String]&#39;</span><span class="o">:</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-87">&#182;</a> </div> <p>Primitives and their corresponding object wrappers are equivalent; thus, <code>"5"</code> is
589
+ equivalent to <code>new String("5")</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">a</span> <span class="o">==</span> <span class="nb">String</span><span class="p">(</span><span class="nx">b</span><span class="p">);</span>
590
+ <span class="k">case</span> <span class="s1">&#39;[object Number]&#39;</span><span class="o">:</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-88">&#182;</a> </div> <p><code>NaN</code>s are equivalent, but non-reflexive. An <code>egal</code> comparison is performed for
591
+ other numeric values.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">a</span> <span class="o">!=</span> <span class="o">+</span><span class="nx">a</span> <span class="o">?</span> <span class="nx">b</span> <span class="o">!=</span> <span class="o">+</span><span class="nx">b</span> <span class="o">:</span> <span class="p">(</span><span class="nx">a</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">?</span> <span class="mi">1</span> <span class="o">/</span> <span class="nx">a</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">/</span> <span class="nx">b</span> <span class="o">:</span> <span class="nx">a</span> <span class="o">==</span> <span class="o">+</span><span class="nx">b</span><span class="p">);</span>
592
+ <span class="k">case</span> <span class="s1">&#39;[object Date]&#39;</span><span class="o">:</span>
593
+ <span class="k">case</span> <span class="s1">&#39;[object Boolean]&#39;</span><span class="o">:</span></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">&#182;</a> </div> <p>Coerce dates and booleans to numeric primitive values. Dates are compared by their
594
+ millisecond representations. Note that invalid dates with millisecond representations
595
+ of <code>NaN</code> are not equivalent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="o">+</span><span class="nx">a</span> <span class="o">==</span> <span class="o">+</span><span class="nx">b</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-90">&#182;</a> </div> <p>RegExps are compared by their source patterns and flags.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="s1">&#39;[object RegExp]&#39;</span><span class="o">:</span>
596
+ <span class="k">return</span> <span class="nx">a</span><span class="p">.</span><span class="nx">source</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">source</span> <span class="o">&amp;&amp;</span>
597
+ <span class="nx">a</span><span class="p">.</span><span class="nx">global</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">global</span> <span class="o">&amp;&amp;</span>
598
+ <span class="nx">a</span><span class="p">.</span><span class="nx">multiline</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">multiline</span> <span class="o">&amp;&amp;</span>
599
+ <span class="nx">a</span><span class="p">.</span><span class="nx">ignoreCase</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">ignoreCase</span><span class="p">;</span>
600
+ <span class="p">}</span>
601
+ <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">a</span> <span class="o">!=</span> <span class="s1">&#39;object&#39;</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">b</span> <span class="o">!=</span> <span class="s1">&#39;object&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-91">&#182;</a> </div> <p>Assume equality for cyclic structures. The algorithm for detecting cyclic
602
+ structures is adapted from ES 5.1 section 15.12.3, abstract operation <code>JO</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">length</span> <span class="o">=</span> <span class="nx">aStack</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
603
+ <span class="k">while</span> <span class="p">(</span><span class="nx">length</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">&#182;</a> </div> <p>Linear search. Performance is inversely proportional to the number of
604
+ unique nested structures.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">aStack</span><span class="p">[</span><span class="nx">length</span><span class="p">]</span> <span class="o">==</span> <span class="nx">a</span><span class="p">)</span> <span class="k">return</span> <span class="nx">bStack</span><span class="p">[</span><span class="nx">length</span><span class="p">]</span> <span class="o">==</span> <span class="nx">b</span><span class="p">;</span>
605
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-93">&#182;</a> </div> <p>Add the first object to the stack of traversed objects.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">aStack</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">a</span><span class="p">);</span>
606
+ <span class="nx">bStack</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">b</span><span class="p">);</span>
607
+ <span class="kd">var</span> <span class="nx">size</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">result</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-94">&#182;</a> </div> <p>Recursively compare objects and arrays.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">className</span> <span class="o">==</span> <span class="s1">&#39;[object Array]&#39;</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-95">&#182;</a> </div> <p>Compare array lengths to determine if a deep comparison is necessary.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">size</span> <span class="o">=</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
608
+ <span class="nx">result</span> <span class="o">=</span> <span class="nx">size</span> <span class="o">==</span> <span class="nx">b</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
609
+ <span class="k">if</span> <span class="p">(</span><span class="nx">result</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-96">&#182;</a> </div> <p>Deep compare the contents, ignoring non-numeric properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">while</span> <span class="p">(</span><span class="nx">size</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
610
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">result</span> <span class="o">=</span> <span class="nx">eq</span><span class="p">(</span><span class="nx">a</span><span class="p">[</span><span class="nx">size</span><span class="p">],</span> <span class="nx">b</span><span class="p">[</span><span class="nx">size</span><span class="p">],</span> <span class="nx">aStack</span><span class="p">,</span> <span class="nx">bStack</span><span class="p">)))</span> <span class="k">break</span><span class="p">;</span>
611
+ <span class="p">}</span>
612
+ <span class="p">}</span>
613
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-97">&#182;</a> </div> <p>Objects with different constructors are not equivalent, but <code>Object</code>s
614
+ from different frames are.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">aCtor</span> <span class="o">=</span> <span class="nx">a</span><span class="p">.</span><span class="nx">constructor</span><span class="p">,</span> <span class="nx">bCtor</span> <span class="o">=</span> <span class="nx">b</span><span class="p">.</span><span class="nx">constructor</span><span class="p">;</span>
615
+ <span class="k">if</span> <span class="p">(</span><span class="nx">aCtor</span> <span class="o">!==</span> <span class="nx">bCtor</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">aCtor</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">aCtor</span> <span class="k">instanceof</span> <span class="nx">aCtor</span><span class="p">)</span> <span class="o">&amp;&amp;</span>
616
+ <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">bCtor</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">bCtor</span> <span class="k">instanceof</span> <span class="nx">bCtor</span><span class="p">)))</span> <span class="p">{</span>
617
+ <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
618
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-98">&#182;</a> </div> <p>Deep compare objects.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">a</span><span class="p">)</span> <span class="p">{</span>
619
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-99">&#182;</a> </div> <p>Count the expected number of properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">size</span><span class="o">++</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-100">&#182;</a> </div> <p>Deep compare each member.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">result</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">eq</span><span class="p">(</span><span class="nx">a</span><span class="p">[</span><span class="nx">key</span><span class="p">],</span> <span class="nx">b</span><span class="p">[</span><span class="nx">key</span><span class="p">],</span> <span class="nx">aStack</span><span class="p">,</span> <span class="nx">bStack</span><span class="p">)))</span> <span class="k">break</span><span class="p">;</span>
620
+ <span class="p">}</span>
621
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-101">&#182;</a> </div> <p>Ensure that both objects contain the same number of properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">result</span><span class="p">)</span> <span class="p">{</span>
622
+ <span class="k">for</span> <span class="p">(</span><span class="nx">key</span> <span class="k">in</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
623
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span><span class="nx">size</span><span class="o">--</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
624
+ <span class="p">}</span>
625
+ <span class="nx">result</span> <span class="o">=</span> <span class="o">!</span><span class="nx">size</span><span class="p">;</span>
626
+ <span class="p">}</span>
627
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-102">&#182;</a> </div> <p>Remove the first object from the stack of traversed objects.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">aStack</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
628
+ <span class="nx">bStack</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
629
+ <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
630
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-103">&#182;</a> </div> <p>Perform a deep comparison to check if two objects are equal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isEqual</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
631
+ <span class="k">return</span> <span class="nx">eq</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">,</span> <span class="p">[],</span> <span class="p">[]);</span>
632
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-104">&#182;</a> </div> <p>Is a given array, string, or object empty?
633
+ An "empty" object has no enumerable own-properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isEmpty</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
634
+ <span class="k">if</span> <span class="p">(</span><span class="nx">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
635
+ <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">||</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isString</span><span class="p">(</span><span class="nx">obj</span><span class="p">))</span> <span class="k">return</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">;</span>
636
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
637
+ <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
638
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-105">&#182;</a> </div> <p>Is a given value a DOM element?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isElement</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
639
+ <span class="k">return</span> <span class="o">!!</span><span class="p">(</span><span class="nx">obj</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">nodeType</span> <span class="o">===</span> <span class="mi">1</span><span class="p">);</span>
640
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-106">&#182;</a> </div> <p>Is a given value an array?
641
+ Delegates to ECMA5's native Array.isArray</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isArray</span> <span class="o">=</span> <span class="nx">nativeIsArray</span> <span class="o">||</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
642
+ <span class="k">return</span> <span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">==</span> <span class="s1">&#39;[object Array]&#39;</span><span class="p">;</span>
643
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-107">&#182;</a> </div> <p>Is a given variable an object?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isObject</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
644
+ <span class="k">return</span> <span class="nx">obj</span> <span class="o">===</span> <span class="nb">Object</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
645
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-108">&#182;</a> </div> <p>Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">each</span><span class="p">([</span><span class="s1">&#39;Arguments&#39;</span><span class="p">,</span> <span class="s1">&#39;Function&#39;</span><span class="p">,</span> <span class="s1">&#39;String&#39;</span><span class="p">,</span> <span class="s1">&#39;Number&#39;</span><span class="p">,</span> <span class="s1">&#39;Date&#39;</span><span class="p">,</span> <span class="s1">&#39;RegExp&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
646
+ <span class="nx">_</span><span class="p">[</span><span class="s1">&#39;is&#39;</span> <span class="o">+</span> <span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
647
+ <span class="k">return</span> <span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">==</span> <span class="s1">&#39;[object &#39;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s1">&#39;]&#39;</span><span class="p">;</span>
648
+ <span class="p">};</span>
649
+ <span class="p">});</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-109">&#182;</a> </div> <p>Define a fallback version of the method in browsers (ahem, IE), where
650
+ there isn't any inspectable "Arguments" type.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">isArguments</span><span class="p">(</span><span class="nx">arguments</span><span class="p">))</span> <span class="p">{</span>
651
+ <span class="nx">_</span><span class="p">.</span><span class="nx">isArguments</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
652
+ <span class="k">return</span> <span class="o">!!</span><span class="p">(</span><span class="nx">obj</span> <span class="o">&amp;&amp;</span> <span class="nx">_</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="s1">&#39;callee&#39;</span><span class="p">));</span>
653
+ <span class="p">};</span>
654
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-110">&#182;</a> </div> <p>Optimize <code>isFunction</code> if appropriate.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="p">(</span><span class="sr">/./</span><span class="p">)</span> <span class="o">!==</span> <span class="s1">&#39;function&#39;</span><span class="p">)</span> <span class="p">{</span>
655
+ <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
656
+ <span class="k">return</span> <span class="k">typeof</span> <span class="nx">obj</span> <span class="o">===</span> <span class="s1">&#39;function&#39;</span><span class="p">;</span>
657
+ <span class="p">};</span>
658
+ <span class="p">}</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-111">&#182;</a> </div> <p>Is a given object a finite number?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nb">isFinite</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
659
+ <span class="k">return</span> <span class="nb">isFinite</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nb">isNaN</span><span class="p">(</span><span class="nb">parseFloat</span><span class="p">(</span><span class="nx">obj</span><span class="p">));</span>
660
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-112">&#182;</a> </div> <p>Is the given value <code>NaN</code>? (NaN is the only number which does not equal itself).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nb">isNaN</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
661
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isNumber</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span> <span class="o">!=</span> <span class="o">+</span><span class="nx">obj</span><span class="p">;</span>
662
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-113">&#182;</a> </div> <p>Is a given value a boolean?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isBoolean</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
663
+ <span class="k">return</span> <span class="nx">obj</span> <span class="o">===</span> <span class="kc">true</span> <span class="o">||</span> <span class="nx">obj</span> <span class="o">===</span> <span class="kc">false</span> <span class="o">||</span> <span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="o">==</span> <span class="s1">&#39;[object Boolean]&#39;</span><span class="p">;</span>
664
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-114">&#182;</a> </div> <p>Is a given value equal to null?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isNull</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
665
+ <span class="k">return</span> <span class="nx">obj</span> <span class="o">===</span> <span class="kc">null</span><span class="p">;</span>
666
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-115">&#182;</a> </div> <p>Is a given variable undefined?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
667
+ <span class="k">return</span> <span class="nx">obj</span> <span class="o">===</span> <span class="k">void</span> <span class="mi">0</span><span class="p">;</span>
668
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-116">&#182;</a> </div> <p>Shortcut function for checking if an object has a given property directly
669
+ on itself (in other words, not on a prototype).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">has</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
670
+ <span class="k">return</span> <span class="nx">hasOwnProperty</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">);</span>
671
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-117">&#182;</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-118">&#182;</a> </div> <p>Run Underscore.js in <em>noConflict</em> mode, returning the <code>_</code> variable to its
672
+ previous owner. Returns a reference to the Underscore object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">noConflict</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
673
+ <span class="nx">root</span><span class="p">.</span><span class="nx">_</span> <span class="o">=</span> <span class="nx">previousUnderscore</span><span class="p">;</span>
674
+ <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
675
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-119">&#182;</a> </div> <p>Keep the identity function around for default iterators.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">identity</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
676
+ <span class="k">return</span> <span class="nx">value</span><span class="p">;</span>
677
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-120">&#182;</a> </div> <p>Run a function <strong>n</strong> times.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">times</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
678
+ <span class="kd">var</span> <span class="nx">accum</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
679
+ <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">n</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="nx">accum</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">iterator</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">i</span><span class="p">);</span>
680
+ <span class="k">return</span> <span class="nx">accum</span><span class="p">;</span>
681
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-121">&#182;</a> </div> <p>Return a random integer between min and max (inclusive).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">random</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">min</span><span class="p">,</span> <span class="nx">max</span><span class="p">)</span> <span class="p">{</span>
682
+ <span class="k">if</span> <span class="p">(</span><span class="nx">max</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
683
+ <span class="nx">max</span> <span class="o">=</span> <span class="nx">min</span><span class="p">;</span>
684
+ <span class="nx">min</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
685
+ <span class="p">}</span>
686
+ <span class="k">return</span> <span class="nx">min</span> <span class="o">+</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="p">(</span><span class="nx">max</span> <span class="o">-</span> <span class="nx">min</span> <span class="o">+</span> <span class="mi">1</span><span class="p">));</span>
687
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-122">&#182;</a> </div> <p>List of HTML entities for escaping.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">entityMap</span> <span class="o">=</span> <span class="p">{</span>
688
+ <span class="nx">escape</span><span class="o">:</span> <span class="p">{</span>
689
+ <span class="s1">&#39;&amp;&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;amp;&#39;</span><span class="p">,</span>
690
+ <span class="s1">&#39;&lt;&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;lt;&#39;</span><span class="p">,</span>
691
+ <span class="s1">&#39;&gt;&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;gt;&#39;</span><span class="p">,</span>
692
+ <span class="s1">&#39;&quot;&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;quot;&#39;</span><span class="p">,</span>
693
+ <span class="s2">&quot;&#39;&quot;</span><span class="o">:</span> <span class="s1">&#39;&amp;#x27;&#39;</span><span class="p">,</span>
694
+ <span class="s1">&#39;/&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;#x2F;&#39;</span>
695
+ <span class="p">}</span>
696
+ <span class="p">};</span>
697
+ <span class="nx">entityMap</span><span class="p">.</span><span class="nx">unescape</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">invert</span><span class="p">(</span><span class="nx">entityMap</span><span class="p">.</span><span class="nx">escape</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-123">&#182;</a> </div> <p>Regexes containing the keys and values listed immediately above.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">entityRegexes</span> <span class="o">=</span> <span class="p">{</span>
698
+ <span class="nx">escape</span><span class="o">:</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">&#39;[&#39;</span> <span class="o">+</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">entityMap</span><span class="p">.</span><span class="nx">escape</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">),</span>
699
+ <span class="nx">unescape</span><span class="o">:</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">entityMap</span><span class="p">.</span><span class="nx">unescape</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;|&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">)</span>
700
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-124">&#182;</a> </div> <p>Functions for escaping and unescaping strings to/from HTML interpolation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span><span class="s1">&#39;escape&#39;</span><span class="p">,</span> <span class="s1">&#39;unescape&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
701
+ <span class="nx">_</span><span class="p">[</span><span class="nx">method</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">string</span><span class="p">)</span> <span class="p">{</span>
702
+ <span class="k">if</span> <span class="p">(</span><span class="nx">string</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
703
+ <span class="k">return</span> <span class="p">(</span><span class="s1">&#39;&#39;</span> <span class="o">+</span> <span class="nx">string</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="nx">entityRegexes</span><span class="p">[</span><span class="nx">method</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">match</span><span class="p">)</span> <span class="p">{</span>
704
+ <span class="k">return</span> <span class="nx">entityMap</span><span class="p">[</span><span class="nx">method</span><span class="p">][</span><span class="nx">match</span><span class="p">];</span>
705
+ <span class="p">});</span>
706
+ <span class="p">};</span>
707
+ <span class="p">});</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-125">&#182;</a> </div> <p>If the value of the named property is a function then invoke it;
708
+ otherwise, return it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">result</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">property</span><span class="p">)</span> <span class="p">{</span>
709
+ <span class="k">if</span> <span class="p">(</span><span class="nx">object</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
710
+ <span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">object</span><span class="p">[</span><span class="nx">property</span><span class="p">];</span>
711
+ <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="o">?</span> <span class="nx">value</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">object</span><span class="p">)</span> <span class="o">:</span> <span class="nx">value</span><span class="p">;</span>
712
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-126">&#182;</a> </div> <p>Add your own custom functions to the Underscore object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">mixin</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
713
+ <span class="nx">each</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">functions</span><span class="p">(</span><span class="nx">obj</span><span class="p">),</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">){</span>
714
+ <span class="kd">var</span> <span class="nx">func</span> <span class="o">=</span> <span class="nx">_</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">name</span><span class="p">];</span>
715
+ <span class="nx">_</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
716
+ <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">];</span>
717
+ <span class="nx">push</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
718
+ <span class="k">return</span> <span class="nx">result</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">args</span><span class="p">));</span>
719
+ <span class="p">};</span>
720
+ <span class="p">});</span>
721
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">&#182;</a> </div> <p>Generate a unique integer id (unique within the entire client session).
722
+ Useful for temporary DOM ids.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">idCounter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
723
+ <span class="nx">_</span><span class="p">.</span><span class="nx">uniqueId</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">prefix</span><span class="p">)</span> <span class="p">{</span>
724
+ <span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="o">++</span><span class="nx">idCounter</span> <span class="o">+</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
725
+ <span class="k">return</span> <span class="nx">prefix</span> <span class="o">?</span> <span class="nx">prefix</span> <span class="o">+</span> <span class="nx">id</span> <span class="o">:</span> <span class="nx">id</span><span class="p">;</span>
726
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">&#182;</a> </div> <p>By default, Underscore uses ERB-style template delimiters, change the
727
+ following template settings to use alternative delimiters.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">templateSettings</span> <span class="o">=</span> <span class="p">{</span>
728
+ <span class="nx">evaluate</span> <span class="o">:</span> <span class="sr">/&lt;%([\s\S]+?)%&gt;/g</span><span class="p">,</span>
729
+ <span class="nx">interpolate</span> <span class="o">:</span> <span class="sr">/&lt;%=([\s\S]+?)%&gt;/g</span><span class="p">,</span>
730
+ <span class="nx">escape</span> <span class="o">:</span> <span class="sr">/&lt;%-([\s\S]+?)%&gt;/g</span>
731
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-129">&#182;</a> </div> <p>When customizing <code>templateSettings</code>, if you don't want to define an
732
+ interpolation, evaluation or escaping regex, we need one that is
733
+ guaranteed not to match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">noMatch</span> <span class="o">=</span> <span class="sr">/(.)^/</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-130">&#182;</a> </div> <p>Certain characters need to be escaped so that they can be put into a
734
+ string literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">escapes</span> <span class="o">=</span> <span class="p">{</span>
735
+ <span class="s2">&quot;&#39;&quot;</span><span class="o">:</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">,</span>
736
+ <span class="s1">&#39;\\&#39;</span><span class="o">:</span> <span class="s1">&#39;\\&#39;</span><span class="p">,</span>
737
+ <span class="s1">&#39;\r&#39;</span><span class="o">:</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span>
738
+ <span class="s1">&#39;\n&#39;</span><span class="o">:</span> <span class="s1">&#39;n&#39;</span><span class="p">,</span>
739
+ <span class="s1">&#39;\t&#39;</span><span class="o">:</span> <span class="s1">&#39;t&#39;</span><span class="p">,</span>
740
+ <span class="s1">&#39;\u2028&#39;</span><span class="o">:</span> <span class="s1">&#39;u2028&#39;</span><span class="p">,</span>
741
+ <span class="s1">&#39;\u2029&#39;</span><span class="o">:</span> <span class="s1">&#39;u2029&#39;</span>
742
+ <span class="p">};</span>
743
+
744
+ <span class="kd">var</span> <span class="nx">escaper</span> <span class="o">=</span> <span class="sr">/\\|&#39;|\r|\n|\t|\u2028|\u2029/g</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">&#182;</a> </div> <p>JavaScript micro-templating, similar to John Resig's implementation.
745
+ Underscore templating handles arbitrary delimiters, preserves whitespace,
746
+ and correctly escapes quotes within interpolated code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">text</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">settings</span><span class="p">)</span> <span class="p">{</span>
747
+ <span class="kd">var</span> <span class="nx">render</span><span class="p">;</span>
748
+ <span class="nx">settings</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">defaults</span><span class="p">({},</span> <span class="nx">settings</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">templateSettings</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">&#182;</a> </div> <p>Combine delimiters into one regular expression via alternation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">matcher</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">([</span>
749
+ <span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">escape</span> <span class="o">||</span> <span class="nx">noMatch</span><span class="p">).</span><span class="nx">source</span><span class="p">,</span>
750
+ <span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">interpolate</span> <span class="o">||</span> <span class="nx">noMatch</span><span class="p">).</span><span class="nx">source</span><span class="p">,</span>
751
+ <span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">evaluate</span> <span class="o">||</span> <span class="nx">noMatch</span><span class="p">).</span><span class="nx">source</span>
752
+ <span class="p">].</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;|&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;|$&#39;</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-133">&#182;</a> </div> <p>Compile the template source, escaping string literals appropriately.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
753
+ <span class="kd">var</span> <span class="nx">source</span> <span class="o">=</span> <span class="s2">&quot;__p+=&#39;&quot;</span><span class="p">;</span>
754
+ <span class="nx">text</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">matcher</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">match</span><span class="p">,</span> <span class="nx">escape</span><span class="p">,</span> <span class="nx">interpolate</span><span class="p">,</span> <span class="nx">evaluate</span><span class="p">,</span> <span class="nx">offset</span><span class="p">)</span> <span class="p">{</span>
755
+ <span class="nx">source</span> <span class="o">+=</span> <span class="nx">text</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">offset</span><span class="p">)</span>
756
+ <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">escaper</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">match</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="s1">&#39;\\&#39;</span> <span class="o">+</span> <span class="nx">escapes</span><span class="p">[</span><span class="nx">match</span><span class="p">];</span> <span class="p">});</span>
757
+
758
+ <span class="k">if</span> <span class="p">(</span><span class="nx">escape</span><span class="p">)</span> <span class="p">{</span>
759
+ <span class="nx">source</span> <span class="o">+=</span> <span class="s2">&quot;&#39;+\n((__t=(&quot;</span> <span class="o">+</span> <span class="nx">escape</span> <span class="o">+</span> <span class="s2">&quot;))==null?&#39;&#39;:_.escape(__t))+\n&#39;&quot;</span><span class="p">;</span>
760
+ <span class="p">}</span>
761
+ <span class="k">if</span> <span class="p">(</span><span class="nx">interpolate</span><span class="p">)</span> <span class="p">{</span>
762
+ <span class="nx">source</span> <span class="o">+=</span> <span class="s2">&quot;&#39;+\n((__t=(&quot;</span> <span class="o">+</span> <span class="nx">interpolate</span> <span class="o">+</span> <span class="s2">&quot;))==null?&#39;&#39;:__t)+\n&#39;&quot;</span><span class="p">;</span>
763
+ <span class="p">}</span>
764
+ <span class="k">if</span> <span class="p">(</span><span class="nx">evaluate</span><span class="p">)</span> <span class="p">{</span>
765
+ <span class="nx">source</span> <span class="o">+=</span> <span class="s2">&quot;&#39;;\n&quot;</span> <span class="o">+</span> <span class="nx">evaluate</span> <span class="o">+</span> <span class="s2">&quot;\n__p+=&#39;&quot;</span><span class="p">;</span>
766
+ <span class="p">}</span>
767
+ <span class="nx">index</span> <span class="o">=</span> <span class="nx">offset</span> <span class="o">+</span> <span class="nx">match</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
768
+ <span class="k">return</span> <span class="nx">match</span><span class="p">;</span>
769
+ <span class="p">});</span>
770
+ <span class="nx">source</span> <span class="o">+=</span> <span class="s2">&quot;&#39;;\n&quot;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">&#182;</a> </div> <p>If a variable is not specified, place data values in local scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">settings</span><span class="p">.</span><span class="nx">variable</span><span class="p">)</span> <span class="nx">source</span> <span class="o">=</span> <span class="s1">&#39;with(obj||{}){\n&#39;</span> <span class="o">+</span> <span class="nx">source</span> <span class="o">+</span> <span class="s1">&#39;}\n&#39;</span><span class="p">;</span>
771
+
772
+ <span class="nx">source</span> <span class="o">=</span> <span class="s2">&quot;var __t,__p=&#39;&#39;,__j=Array.prototype.join,&quot;</span> <span class="o">+</span>
773
+ <span class="s2">&quot;print=function(){__p+=__j.call(arguments,&#39;&#39;);};\n&quot;</span> <span class="o">+</span>
774
+ <span class="nx">source</span> <span class="o">+</span> <span class="s2">&quot;return __p;\n&quot;</span><span class="p">;</span>
775
+
776
+ <span class="k">try</span> <span class="p">{</span>
777
+ <span class="nx">render</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Function</span><span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">variable</span> <span class="o">||</span> <span class="s1">&#39;obj&#39;</span><span class="p">,</span> <span class="s1">&#39;_&#39;</span><span class="p">,</span> <span class="nx">source</span><span class="p">);</span>
778
+ <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
779
+ <span class="nx">e</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="nx">source</span><span class="p">;</span>
780
+ <span class="k">throw</span> <span class="nx">e</span><span class="p">;</span>
781
+ <span class="p">}</span>
782
+
783
+ <span class="k">if</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="k">return</span> <span class="nx">render</span><span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">_</span><span class="p">);</span>
784
+ <span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
785
+ <span class="k">return</span> <span class="nx">render</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">_</span><span class="p">);</span>
786
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">&#182;</a> </div> <p>Provide the compiled function source as a convenience for precompilation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">template</span><span class="p">.</span><span class="nx">source</span> <span class="o">=</span> <span class="s1">&#39;function(&#39;</span> <span class="o">+</span> <span class="p">(</span><span class="nx">settings</span><span class="p">.</span><span class="nx">variable</span> <span class="o">||</span> <span class="s1">&#39;obj&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;){\n&#39;</span> <span class="o">+</span> <span class="nx">source</span> <span class="o">+</span> <span class="s1">&#39;}&#39;</span><span class="p">;</span>
787
+
788
+ <span class="k">return</span> <span class="nx">template</span><span class="p">;</span>
789
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-136">&#182;</a> </div> <p>Add a "chain" function, which will delegate to the wrapper.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">chain</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
790
+ <span class="k">return</span> <span class="nx">_</span><span class="p">(</span><span class="nx">obj</span><span class="p">).</span><span class="nx">chain</span><span class="p">();</span>
791
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">&#182;</a> </div> <h2>OOP</h2>
792
+
793
+ <p>If Underscore is called as a function, it returns a wrapped object that
794
+ can be used OO-style. This wrapper holds altered versions of all the
795
+ underscore functions. Wrapped objects may be chained.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">&#182;</a> </div> <p>Helper function to continue chaining intermediate results.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
796
+ <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_chain</span> <span class="o">?</span> <span class="nx">_</span><span class="p">(</span><span class="nx">obj</span><span class="p">).</span><span class="nx">chain</span><span class="p">()</span> <span class="o">:</span> <span class="nx">obj</span><span class="p">;</span>
797
+ <span class="p">};</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">&#182;</a> </div> <p>Add all of the Underscore functions to the wrapper object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">mixin</span><span class="p">(</span><span class="nx">_</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">&#182;</a> </div> <p>Add all mutator Array functions to the wrapper.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">each</span><span class="p">([</span><span class="s1">&#39;pop&#39;</span><span class="p">,</span> <span class="s1">&#39;push&#39;</span><span class="p">,</span> <span class="s1">&#39;reverse&#39;</span><span class="p">,</span> <span class="s1">&#39;shift&#39;</span><span class="p">,</span> <span class="s1">&#39;sort&#39;</span><span class="p">,</span> <span class="s1">&#39;splice&#39;</span><span class="p">,</span> <span class="s1">&#39;unshift&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
798
+ <span class="kd">var</span> <span class="nx">method</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">[</span><span class="nx">name</span><span class="p">];</span>
799
+ <span class="nx">_</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
800
+ <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
801
+ <span class="nx">method</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
802
+ <span class="k">if</span> <span class="p">((</span><span class="nx">name</span> <span class="o">==</span> <span class="s1">&#39;shift&#39;</span> <span class="o">||</span> <span class="nx">name</span> <span class="o">==</span> <span class="s1">&#39;splice&#39;</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="k">delete</span> <span class="nx">obj</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
803
+ <span class="k">return</span> <span class="nx">result</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
804
+ <span class="p">};</span>
805
+ <span class="p">});</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">&#182;</a> </div> <p>Add all accessor Array functions to the wrapper.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">each</span><span class="p">([</span><span class="s1">&#39;concat&#39;</span><span class="p">,</span> <span class="s1">&#39;join&#39;</span><span class="p">,</span> <span class="s1">&#39;slice&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
806
+ <span class="kd">var</span> <span class="nx">method</span> <span class="o">=</span> <span class="nx">ArrayProto</span><span class="p">[</span><span class="nx">name</span><span class="p">];</span>
807
+ <span class="nx">_</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
808
+ <span class="k">return</span> <span class="nx">result</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">method</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">));</span>
809
+ <span class="p">};</span>
810
+ <span class="p">});</span>
811
+
812
+ <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">&#182;</a> </div> <p>Start chaining a wrapped Underscore object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">chain</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
813
+ <span class="k">this</span><span class="p">.</span><span class="nx">_chain</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
814
+ <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
815
+ <span class="p">},</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">&#182;</a> </div> <p>Extracts the result from a wrapped and chained object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">value</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
816
+ <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_wrapped</span><span class="p">;</span>
817
+ <span class="p">}</span>
818
+
819
+ <span class="p">});</span>
820
+
821
+ <span class="p">}).</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
822
+
823
+ </pre></div> </td> </tr> </tbody> </table> </div> </body> </html>