yellow-brick-road 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. data/README.rst +148 -0
  2. data/Rakefile +37 -0
  3. data/lib/tasks/yellow-brick-road_tasks.rake +4 -0
  4. data/lib/yellow-brick-road.rb +6 -0
  5. data/lib/yellow-brick-road/config.rb +15 -0
  6. data/lib/yellow-brick-road/directive_processor.rb +68 -0
  7. data/lib/yellow-brick-road/engine.rb +22 -0
  8. data/lib/yellow-brick-road/soy_processor.rb +56 -0
  9. data/lib/yellow-brick-road/utils.rb +38 -0
  10. data/lib/yellow-brick-road/version.rb +3 -0
  11. data/test/dummy/Rakefile +7 -0
  12. data/test/dummy/app/assets/javascripts/application.js +12 -0
  13. data/test/dummy/app/assets/javascripts/closure-deps.js +4 -0
  14. data/test/dummy/app/assets/javascripts/my-closure/simple.js.soy +14 -0
  15. data/test/dummy/app/assets/javascripts/my-closure/start.js +25 -0
  16. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  17. data/test/dummy/app/controllers/application_controller.rb +7 -0
  18. data/test/dummy/app/helpers/application_helper.rb +2 -0
  19. data/test/dummy/app/views/application/index.html.erb +0 -0
  20. data/test/dummy/app/views/layouts/application.html.erb +18 -0
  21. data/test/dummy/config.ru +4 -0
  22. data/test/dummy/config/application.rb +51 -0
  23. data/test/dummy/config/boot.rb +10 -0
  24. data/test/dummy/config/environment.rb +5 -0
  25. data/test/dummy/config/environments/development.rb +30 -0
  26. data/test/dummy/config/environments/production.rb +60 -0
  27. data/test/dummy/config/environments/test.rb +39 -0
  28. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  29. data/test/dummy/config/initializers/inflections.rb +10 -0
  30. data/test/dummy/config/initializers/mime_types.rb +5 -0
  31. data/test/dummy/config/initializers/secret_token.rb +7 -0
  32. data/test/dummy/config/initializers/session_store.rb +8 -0
  33. data/test/dummy/config/initializers/wrap_parameters.rb +10 -0
  34. data/test/dummy/config/initializers/yellow_brick_road.rb +2 -0
  35. data/test/dummy/config/locales/en.yml +5 -0
  36. data/test/dummy/config/routes.rb +58 -0
  37. data/test/dummy/log/development.log +13924 -0
  38. data/test/dummy/log/test.log +0 -0
  39. data/test/dummy/public/404.html +26 -0
  40. data/test/dummy/public/422.html +26 -0
  41. data/test/dummy/public/500.html +26 -0
  42. data/test/dummy/public/favicon.ico +0 -0
  43. data/test/dummy/script/rails +6 -0
  44. data/test/dummy/tmp/cache/assets/BE0/120/sprockets%2F751842b8c6750008c7310d182600d173 +142 -0
  45. data/test/dummy/tmp/cache/assets/C19/950/sprockets%2F142437f1d8d9424007b4a882a5429333 +1372 -0
  46. data/test/dummy/tmp/cache/assets/C4B/D00/sprockets%2F400f22c081529179ce3d079457de3009 +806 -0
  47. data/test/dummy/tmp/cache/assets/C5A/EE0/sprockets%2Fb711429ed948c503b718d077037780f8 +0 -0
  48. data/test/dummy/tmp/cache/assets/C5B/A80/sprockets%2F508569b474262724c61a461f7777dab7 +1118 -0
  49. data/test/dummy/tmp/cache/assets/C6C/660/sprockets%2F2c298b3b02232a21527680685a3efc30 +9289 -0
  50. data/test/dummy/tmp/cache/assets/C72/8A0/sprockets%2F167b265129e30d87d253c406db305c60 +293 -0
  51. data/test/dummy/tmp/cache/assets/C7E/9F0/sprockets%2F89862076204c62c4593ac20de32da909 +9 -0
  52. data/test/dummy/tmp/cache/assets/C8B/5F0/sprockets%2Fc6a4470b5c21e285e829a99365839b24 +0 -0
  53. data/test/dummy/tmp/cache/assets/C92/D20/sprockets%2F2e618f7805f445889aec94885a500f03 +457 -0
  54. data/test/dummy/tmp/cache/assets/C98/FD0/sprockets%2Fb11442af041f96e87a43a1dc11231745 +283 -0
  55. data/test/dummy/tmp/cache/assets/CA3/520/sprockets%2F5379d7143c6c52b11b88dc0ab5436133 +277 -0
  56. data/test/dummy/tmp/cache/assets/CA5/450/sprockets%2F6bb727c9312a749134ad67323a317f0d +73 -0
  57. data/test/dummy/tmp/cache/assets/CA5/4F0/sprockets%2Feeb7de7771527700af194c0441d29101 +709 -0
  58. data/test/dummy/tmp/cache/assets/CA6/E90/sprockets%2F611f68180f43c4181f06ae5c5f8201e2 +1546 -0
  59. data/test/dummy/tmp/cache/assets/CA7/310/sprockets%2F45664cf816315200b574e029fde6f10a +0 -0
  60. data/test/dummy/tmp/cache/assets/CA9/9D0/sprockets%2F2672e32464cf7267c4ba3d028f54b153 +224 -0
  61. data/test/dummy/tmp/cache/assets/CAB/5A0/sprockets%2F7f50e0289f150c8636ac9253129bc13c +2556 -0
  62. data/test/dummy/tmp/cache/assets/CB5/7E0/sprockets%2F42ff6672683b2029233a800e7539eeee +474 -0
  63. data/test/dummy/tmp/cache/assets/CB6/DC0/sprockets%2F2f9882155bb2d4d3ab5d708951857c60 +494 -0
  64. data/test/dummy/tmp/cache/assets/CBB/680/sprockets%2F1dc336d96fb52df34b458185559922b5 +1018 -0
  65. data/test/dummy/tmp/cache/assets/CBC/640/sprockets%2F67d2e0d9e5129d237e575d2780c64b47 +1260 -0
  66. data/test/dummy/tmp/cache/assets/CBE/550/sprockets%2Fd680cac830e0b3408ba910f0b0421147 +25 -0
  67. data/test/dummy/tmp/cache/assets/CC7/790/sprockets%2F69941f32a12e4f99d4a57f65386d870d +608 -0
  68. data/test/dummy/tmp/cache/assets/CCB/F80/sprockets%2Fa865701ef2ec41155e524772c31a1a2b +1088 -0
  69. data/test/dummy/tmp/cache/assets/CCE/580/sprockets%2F879411ed27ed1c557d57853d8f579b56 +0 -0
  70. data/test/dummy/tmp/cache/assets/CD0/070/sprockets%2F6748fe8481965f260d9c56b7f9f508a2 +1530 -0
  71. data/test/dummy/tmp/cache/assets/CD4/750/sprockets%2Faf3505141ecb3169ce41ce519d136924 +0 -0
  72. data/test/dummy/tmp/cache/assets/CD6/A90/sprockets%2F3f55ac75b9fb8426312116bcb940a580 +2539 -0
  73. data/test/dummy/tmp/cache/assets/CD9/6C0/sprockets%2F5e2458bc52da90ba349a66035e3b6752 +0 -0
  74. data/test/dummy/tmp/cache/assets/CD9/F50/sprockets%2F9008bf696500cfae1d61f045f209181e +256 -0
  75. data/test/dummy/tmp/cache/assets/CDB/B40/sprockets%2F53529a22c994570a0df4742c0bfe61f4 +0 -0
  76. data/test/dummy/tmp/cache/assets/CDC/D10/sprockets%2F1e775b4ff06b4401c07503ce95a839b5 +75 -0
  77. data/test/dummy/tmp/cache/assets/CDE/CD0/sprockets%2F141066798b4acf07053f7e3a6cb4e555 +1613 -0
  78. data/test/dummy/tmp/cache/assets/CE1/760/sprockets%2F245fe11803630fe30d0cf8a869886ab5 +357 -0
  79. data/test/dummy/tmp/cache/assets/CE1/FA0/sprockets%2F863d1650ef066e4a2168bc57c7c0e096 +0 -0
  80. data/test/dummy/tmp/cache/assets/CE2/310/sprockets%2Fd38075d5592ecaf82e43526c03b467c4 +1545 -0
  81. data/test/dummy/tmp/cache/assets/CE2/420/sprockets%2F30f2e8f30477e80cf6416dfe27307c07 +204 -0
  82. data/test/dummy/tmp/cache/assets/CE2/D70/sprockets%2F467c44b63644e0f44dd06a585f36f1a6 +522 -0
  83. data/test/dummy/tmp/cache/assets/CE3/670/sprockets%2Fddd11860b444cd0f9996be0c46762318 +796 -0
  84. data/test/dummy/tmp/cache/assets/CE4/0B0/sprockets%2Ff11535d785c0d34349c64d673bd4b28f +1105 -0
  85. data/test/dummy/tmp/cache/assets/CE4/590/sprockets%2Fd68edcc87a4ae302794093081b45b819 +10 -0
  86. data/test/dummy/tmp/cache/assets/CE4/D60/sprockets%2F61772e4a60b616f74da91b838a2f4f82 +0 -0
  87. data/test/dummy/tmp/cache/assets/CE6/DD0/sprockets%2F2fe073024a2bf26bd98458388b57af37 +1355 -0
  88. data/test/dummy/tmp/cache/assets/CE7/160/sprockets%2Fba1f9939f031b4356ec1869d40fc2747 +1261 -0
  89. data/test/dummy/tmp/cache/assets/CE8/C70/sprockets%2Fc6c9ba3c677b5e2af8520395192c9445 +173 -0
  90. data/test/dummy/tmp/cache/assets/CEA/8B0/sprockets%2Ff77e549cb6d37604105f35d4e67d8c21 +511 -0
  91. data/test/dummy/tmp/cache/assets/CEA/AA0/sprockets%2F5f816982c86d2e6b72b2f5f65c51d070 +1529 -0
  92. data/test/dummy/tmp/cache/assets/CEA/C10/sprockets%2F9dcd541e67c299ab076a44a2183872f8 +0 -0
  93. data/test/dummy/tmp/cache/assets/CF1/5A0/sprockets%2F1a697695edf2bb7b49a2896904218bc7 +115 -0
  94. data/test/dummy/tmp/cache/assets/CF4/480/sprockets%2F5e99c77e93f4a522c84357e62b25e0f7 +43 -0
  95. data/test/dummy/tmp/cache/assets/CF7/460/sprockets%2Fd12ea9733fe3c92456f57f9145569b9c +0 -0
  96. data/test/dummy/tmp/cache/assets/CF7/470/sprockets%2F2897897a166ca3369fecb88f83f211b5 +435 -0
  97. data/test/dummy/tmp/cache/assets/CFA/760/sprockets%2Fa9024adba14091e0635c6874d1db4e22 +0 -0
  98. data/test/dummy/tmp/cache/assets/D01/F30/sprockets%2Fe639a15b6e0cca37d12443b408e1166f +25 -0
  99. data/test/dummy/tmp/cache/assets/D02/9F0/sprockets%2Fb99eae308897fe88cb9414b96824098b +0 -0
  100. data/test/dummy/tmp/cache/assets/D03/330/sprockets%2F1e003cdb3e7dcc9307e84090ad457127 +454 -0
  101. data/test/dummy/tmp/cache/assets/D03/8B0/sprockets%2Ff74632bddf2c0b2018ca7b736309380e +365 -0
  102. data/test/dummy/tmp/cache/assets/D05/0A0/sprockets%2Fe57658220260db13eb5577aef42cb61b +257 -0
  103. data/test/dummy/tmp/cache/assets/D05/920/sprockets%2F909507434dcc270db4853e4c147f0aac +31 -0
  104. data/test/dummy/tmp/cache/assets/D08/510/sprockets%2Fa567be6cb6d7310096f1739b25a5a3f0 +50 -0
  105. data/test/dummy/tmp/cache/assets/D08/9F0/sprockets%2F1d61d2c89ca50957066bacc5b69011f5 +1424 -0
  106. data/test/dummy/tmp/cache/assets/D0A/790/sprockets%2Feb16913e6504c9b0d3be431de39e4751 +300 -0
  107. data/test/dummy/tmp/cache/assets/D0C/C50/sprockets%2Fd6613bee8b40d50459af6b52a7084f34 +796 -0
  108. data/test/dummy/tmp/cache/assets/D0D/030/sprockets%2Fba3f13b4a444679e8bc2549226ec743b +21 -0
  109. data/test/dummy/tmp/cache/assets/D0D/350/sprockets%2F2670bce036d485e15d059c0f1e98f24a +207 -0
  110. data/test/dummy/tmp/cache/assets/D13/270/sprockets%2F497cb163e6317e3fc1565d832f406cfb +348 -0
  111. data/test/dummy/tmp/cache/assets/D13/380/sprockets%2F786d003c9c7fb759dd26c1030c087cf6 +813 -0
  112. data/test/dummy/tmp/cache/assets/D13/7C0/sprockets%2F528d22310a9ab8e6fba08d82844ce795 +0 -0
  113. data/test/dummy/tmp/cache/assets/D15/F60/sprockets%2Fa28394e3f80365b5bc86794dd46daa22 +0 -0
  114. data/test/dummy/tmp/cache/assets/D18/500/sprockets%2Fd22c2d97d1db2154f2f7592906e957ea +1001 -0
  115. data/test/dummy/tmp/cache/assets/D1B/C70/sprockets%2F1c04848b1e1d6e8e33b8581f8c8128ff +223 -0
  116. data/test/dummy/tmp/cache/assets/D1C/600/sprockets%2Fa0601f99147f59ddd6266e6aff077e14 +0 -0
  117. data/test/dummy/tmp/cache/assets/D1E/470/sprockets%2Fb3933e694547b78bf6fb15f44a4623fe +53 -0
  118. data/test/dummy/tmp/cache/assets/D1F/480/sprockets%2F545164168becf42b289efc8708f1db68 +1278 -0
  119. data/test/dummy/tmp/cache/assets/D21/630/sprockets%2F0a14114729c14637f2e8f122acabd1ab +823 -0
  120. data/test/dummy/tmp/cache/assets/D24/A90/sprockets%2F21c8a0d48c51b8585ba03bc112ecd153 +692 -0
  121. data/test/dummy/tmp/cache/assets/D25/D30/sprockets%2F3b937f4c16d2aa0a28fc02a0e922712b +1441 -0
  122. data/test/dummy/tmp/cache/assets/D25/F30/sprockets%2Fe251527c0c018f4b4ad44b2ad7064fb0 +2255 -0
  123. data/test/dummy/tmp/cache/assets/D26/DE0/sprockets%2F761ac1bdb0739cc56fa0c1224b137b09 +0 -0
  124. data/test/dummy/tmp/cache/assets/D2A/C30/sprockets%2F978fe7268754f451c59b9ccb323ffa56 +0 -0
  125. data/test/dummy/tmp/cache/assets/D2B/0F0/sprockets%2Fbf223af03335cfc08a71e549e10c0e27 +2539 -0
  126. data/test/dummy/tmp/cache/assets/D2E/6D0/sprockets%2F9e7fda3affb389313cc50223f01c0324 +0 -0
  127. data/test/dummy/tmp/cache/assets/D2F/110/sprockets%2F3730ffe2ed34c1219d580bd1615ea7b0 +2239 -0
  128. data/test/dummy/tmp/cache/assets/D2F/F10/sprockets%2F9cac242f0bf5ec00079ea3a463e26552 +153 -0
  129. data/test/dummy/tmp/cache/assets/D30/1D0/sprockets%2Fd690a26a0b0ae138c1c48d257a7674bc +589 -0
  130. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  131. data/test/dummy/tmp/cache/assets/D36/940/sprockets%2Fb4ba462ac9f4aac561c36e60367c1378 +572 -0
  132. data/test/dummy/tmp/cache/assets/D37/090/sprockets%2F2f2e71ebbc240014ebf648f0917e854a +798 -0
  133. data/test/dummy/tmp/cache/assets/D3A/440/sprockets%2F6d332243647c841dea36ed822cdfc23e +165 -0
  134. data/test/dummy/tmp/cache/assets/D3B/5A0/sprockets%2F82e05cf8c88ba8cb1c87e50d51372a03 +0 -0
  135. data/test/dummy/tmp/cache/assets/D41/B30/sprockets%2Fba1b93913dd01d83ac9a96df334456f8 +0 -0
  136. data/test/dummy/tmp/cache/assets/D43/D90/sprockets%2F04f3a5926d5a7672456dc7afa73d0c7f +38 -0
  137. data/test/dummy/tmp/cache/assets/D45/1F0/sprockets%2F1bfa855d9c10ff2431a9a548958cc5e4 +83 -0
  138. data/test/dummy/tmp/cache/assets/D45/B10/sprockets%2F643f3d9b216e48df952b7f150a46a7ec +60 -0
  139. data/test/dummy/tmp/cache/assets/D46/040/sprockets%2F199546844e5939721a5afcbcce4ea43a +143 -0
  140. data/test/dummy/tmp/cache/assets/D49/320/sprockets%2Fd8123eb229e34c9f507f7b1876f1c4ee +506 -0
  141. data/test/dummy/tmp/cache/assets/D49/750/sprockets%2Ff41ef1c0832b7294fb15588ff5c783cb +0 -0
  142. data/test/dummy/tmp/cache/assets/D49/930/sprockets%2F1071926698fa55abc71e1b6fd966dfe1 +72 -0
  143. data/test/dummy/tmp/cache/assets/D49/D10/sprockets%2Fb67b8d7cc7579352a91694f9ae10cdb0 +127 -0
  144. data/test/dummy/tmp/cache/assets/D4A/160/sprockets%2Fcbd8988b5e18d153eff6230d72e9046a +516 -0
  145. data/test/dummy/tmp/cache/assets/D4A/2B0/sprockets%2Ffcdf002d38fd938bf7226b46b76706c8 +1101 -0
  146. data/test/dummy/tmp/cache/assets/D4E/2F0/sprockets%2F77cb87ae57f0d8c25cdaa74181a64997 +1441 -0
  147. data/test/dummy/tmp/cache/assets/D4F/060/sprockets%2Fa9e66b39ada7394a29bf44f3a682f665 +511 -0
  148. data/test/dummy/tmp/cache/assets/D50/BD0/sprockets%2F88650dd57ef64075462e6dae757dbe2c +0 -0
  149. data/test/dummy/tmp/cache/assets/D53/CA0/sprockets%2Fa85032e82709a043fbb2ec00e04f2bbd +0 -0
  150. data/test/dummy/tmp/cache/assets/D54/BF0/sprockets%2F91970514ff528e8d2bfd81f1ec83c9c8 +240 -0
  151. data/test/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +10 -0
  152. data/test/dummy/tmp/cache/assets/D56/500/sprockets%2F75ebadd035f1324b194034af92eac3a0 +0 -0
  153. data/test/dummy/tmp/cache/assets/D5A/900/sprockets%2F5729f77d97fdee53b1942cf17f6f05e4 +474 -0
  154. data/test/dummy/tmp/cache/assets/D5A/D50/sprockets%2F81bace3db2c2f1241175ff3c5009d08c +0 -0
  155. data/test/dummy/tmp/cache/assets/D5B/C70/sprockets%2Fe64119a9db7017b7ab3b0da1b6076f0d +44 -0
  156. data/test/dummy/tmp/cache/assets/D5E/4D0/sprockets%2F756f25e4ad861a050cdc41bb8414e4ab +126 -0
  157. data/test/dummy/tmp/cache/assets/D5E/730/sprockets%2Fd30caf70b387c4604326bdda32aeb549 +0 -0
  158. data/test/dummy/tmp/cache/assets/D5E/AA0/sprockets%2F790dd07caaaacb30ceb0174664e90817 +136 -0
  159. data/test/dummy/tmp/cache/assets/D64/D30/sprockets%2Fe4bd8f60a3a446274c3cb2f5d16563ac +590 -0
  160. data/test/dummy/tmp/cache/assets/D66/400/sprockets%2Fecb7401d20daf25605a7afad3a793778 +0 -0
  161. data/test/dummy/tmp/cache/assets/D67/250/sprockets%2F8422eb26855ca9c953a3bf1aeade8004 +0 -0
  162. data/test/dummy/tmp/cache/assets/D69/900/sprockets%2F28ae64f52cb18f77b1a1bd9c51293da4 +0 -0
  163. data/test/dummy/tmp/cache/assets/D6A/870/sprockets%2F1ece6a51b42f9280f4cee9020c94b72e +197 -0
  164. data/test/dummy/tmp/cache/assets/D6B/DD0/sprockets%2F9a0abc735e27fc61dab019788518eba4 +164 -0
  165. data/test/dummy/tmp/cache/assets/D6E/CC0/sprockets%2F8b4fbcec2475e7203b8859baf8e310a3 +0 -0
  166. data/test/dummy/tmp/cache/assets/D72/470/sprockets%2Fbc0c6d850e7c769e83d58eb3e6061b2a +2556 -0
  167. data/test/dummy/tmp/cache/assets/D72/9D0/sprockets%2F9402daf6da6f7eed331a9d78216cb761 +0 -0
  168. data/test/dummy/tmp/cache/assets/D74/070/sprockets%2F91ae68f698a39bd7d0d11150fc46e4cd +418 -0
  169. data/test/dummy/tmp/cache/assets/D74/7F0/sprockets%2F22dad1069ea6a8f29ae757c44e18ec83 +0 -0
  170. data/test/dummy/tmp/cache/assets/D75/3C0/sprockets%2F44e2ae51b97853d8ecda7b264a267c7d +1630 -0
  171. data/test/dummy/tmp/cache/assets/D77/780/sprockets%2Ffa2abdfb0b62867c346f79187b8e42d5 +823 -0
  172. data/test/dummy/tmp/cache/assets/D79/850/sprockets%2F4d540586ed379fd9a70fa0b7ce4f5b27 +306 -0
  173. data/test/dummy/tmp/cache/assets/D7A/B60/sprockets%2F5925c92f48caff053d08853dc69e5bba +0 -0
  174. data/test/dummy/tmp/cache/assets/D81/C90/sprockets%2F19aca5c835efce74878c23e581e2a89e +2239 -0
  175. data/test/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +11228 -0
  176. data/test/dummy/tmp/cache/assets/D8B/B10/sprockets%2Fbb7a2305a8f2832631863bbababb67be +301 -0
  177. data/test/dummy/tmp/cache/assets/D92/3B0/sprockets%2F93dc71f411faf72ec8ef0b5d217b51a0 +505 -0
  178. data/test/dummy/tmp/cache/assets/D92/EE0/sprockets%2Ffd051ea0abf6be6970754aa732e40c8b +289 -0
  179. data/test/dummy/tmp/cache/assets/D93/810/sprockets%2F7dc1ac5e1b83ba5144e34cf156d48a8a +471 -0
  180. data/test/dummy/tmp/cache/assets/D94/020/sprockets%2F35cb4ce22488fb5bdd260508ca47a3fb +239 -0
  181. data/test/dummy/tmp/cache/assets/D94/EC0/sprockets%2F8b900fba18f8e046f5f12e6d1f0ac15b +74 -0
  182. data/test/dummy/tmp/cache/assets/D95/470/sprockets%2F5be5d361a52575c433831b5e8cccbace +9273 -0
  183. data/test/dummy/tmp/cache/assets/D97/9D0/sprockets%2F524a2a94a88c1d392dabcba654e365fc +103 -0
  184. data/test/dummy/tmp/cache/assets/D9D/800/sprockets%2Ff8387220eb4dda9b29a37b5deb9f2a40 +54 -0
  185. data/test/dummy/tmp/cache/assets/D9E/DD0/sprockets%2Fb6b4ffad6485eda046b327a196e8c44a +0 -0
  186. data/test/dummy/tmp/cache/assets/DA1/0A0/sprockets%2F359c94aee6ba2e15fc9666aa4de311c8 +166 -0
  187. data/test/dummy/tmp/cache/assets/DA1/0D0/sprockets%2F798de3c28452e164a7fc1a3a6e8cdb4b +652 -0
  188. data/test/dummy/tmp/cache/assets/DA3/CB0/sprockets%2Fdfad6bb1857a8af91f98ba137c18504e +815 -0
  189. data/test/dummy/tmp/cache/assets/DA4/E10/sprockets%2Fbda7705734ace95f12a7d79df9c14af2 +1354 -0
  190. data/test/dummy/tmp/cache/assets/DA5/E30/sprockets%2F2e6707a119e94a784efbadca18d7e8d1 +129 -0
  191. data/test/dummy/tmp/cache/assets/DA6/4B0/sprockets%2F4f7a708b6aa2d42eb577493dea7cef55 +115 -0
  192. data/test/dummy/tmp/cache/assets/DA8/A10/sprockets%2F0ae5bbb4ca200e74db3b64d72c2be120 +0 -0
  193. data/test/dummy/tmp/cache/assets/DA9/3F0/sprockets%2Fdd0af9cfd65fb7d02fe778c8f6015361 +499 -0
  194. data/test/dummy/tmp/cache/assets/DA9/780/sprockets%2Fe3559a635e8f92dec7727a3db2ae7b4c +813 -0
  195. data/test/dummy/tmp/cache/assets/DAC/0E0/sprockets%2F04cef8243a9ef7321846debc977ea8db +607 -0
  196. data/test/dummy/tmp/cache/assets/DB1/260/sprockets%2Fb879ff7530bf8cc175e0c7e70dc4e79b +0 -0
  197. data/test/dummy/tmp/cache/assets/DB4/4C0/sprockets%2F30a76cbd98dedb56742cd8ecaf858757 +0 -0
  198. data/test/dummy/tmp/cache/assets/DBD/7E0/sprockets%2F236fb1ac5ed9f2e3fe32203acc3a842d +0 -0
  199. data/test/dummy/tmp/cache/assets/DC2/DF0/sprockets%2Fe233bcaba8beff15626c35cb5e0e0936 +845 -0
  200. data/test/dummy/tmp/cache/assets/DC4/600/sprockets%2F59c96aa6c1cbebc61bff6c050a5351d7 +225 -0
  201. data/test/dummy/tmp/cache/assets/DC5/030/sprockets%2Fcb2fe864a0177eec19017c43ce9aa4ad +187 -0
  202. data/test/dummy/tmp/cache/assets/DC8/A60/sprockets%2F9fcb9f5c3f679ce749ee4c3f93869ba6 +74 -0
  203. data/test/dummy/tmp/cache/assets/DCB/D40/sprockets%2Ffd5542bfb7660a8d8cac3a2e46fb01f8 +828 -0
  204. data/test/dummy/tmp/cache/assets/DCC/020/sprockets%2F0c129c5f2784c96fa1dc3da6c19c1efc +128 -0
  205. data/test/dummy/tmp/cache/assets/DCF/520/sprockets%2F975162fb97a3ec7033db5f2fdba4fcd3 +70 -0
  206. data/test/dummy/tmp/cache/assets/DD0/000/sprockets%2F0d5d631cce6f0b078bb29cf98b3d78bb +276 -0
  207. data/test/dummy/tmp/cache/assets/DD0/C90/sprockets%2F84eeca4ef8f5eb29b13f7e1ea3c71324 +591 -0
  208. data/test/dummy/tmp/cache/assets/DD6/710/sprockets%2F9e83f2ebbe3e349efca2de390e15d635 +204 -0
  209. data/test/dummy/tmp/cache/assets/DE1/830/sprockets%2Fd23d3cafef2e2a9055bc103dffc1a023 +208 -0
  210. data/test/dummy/tmp/cache/assets/DEB/470/sprockets%2Fae2de0fcbc2214b71d3f2a875d2bc8c3 +2255 -0
  211. data/test/dummy/tmp/cache/assets/DEE/690/sprockets%2F5d824bcadef29060cc13eed71af4b4d0 +550 -0
  212. data/test/dummy/tmp/cache/assets/DF0/5D0/sprockets%2F25a875eb0a5d4c49bcc3fa39ea0adb26 +567 -0
  213. data/test/dummy/tmp/cache/assets/DF3/E20/sprockets%2Fada770c49a5d6b38d1cc43ed4d51c1fc +0 -0
  214. data/test/dummy/tmp/cache/assets/DF5/C80/sprockets%2F03ad7d7b3a8feba9ed9be82ae2083b20 +340 -0
  215. data/test/dummy/tmp/cache/assets/DF6/560/sprockets%2Fafceb2b55eb108efe4446dfb02b519b8 +0 -0
  216. data/test/dummy/tmp/cache/assets/DFC/030/sprockets%2Fcbdd3679eaba219b4e1ff20677af1c6f +1371 -0
  217. data/test/dummy/tmp/cache/assets/E00/970/sprockets%2F8bc6dde8d05c382dd07cbcec70f54e09 +378 -0
  218. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  219. data/test/dummy/tmp/cache/assets/E12/2F0/sprockets%2F5c45062ecfbe512dcba176ba6ddacc00 +523 -0
  220. data/test/dummy/tmp/cache/assets/E21/5D0/sprockets%2Fd4fe6d611bfb0e63c04de5dbfb128a8a +0 -0
  221. data/test/dummy/tmp/cache/assets/E22/770/sprockets%2F2ccebcabfbb9b59159e4b73b3b30a74d +208 -0
  222. data/test/dummy/tmp/cache/assets/E31/A90/sprockets%2F26b98bbbc15eee9b370c7dcde88d16aa +394 -0
  223. data/test/dummy/tmp/cache/assets/E31/E30/sprockets%2Ffbdafcc4e2f44bb9fc653bcf9625b750 +284 -0
  224. data/test/dummy/tmp/cache/assets/E37/1C0/sprockets%2Fa5eb45fc86dafe2bee4e4fa3f53c4785 +0 -0
  225. data/test/dummy/tmp/cache/assets/E4C/960/sprockets%2F13fd6e4bfdf031acb3dedca8d0f407b4 +1277 -0
  226. data/test/dummy/tmp/cache/assets/E88/330/sprockets%2Fe02d0adb5529ffafcea1b9e5ccf69a5b +669 -0
  227. data/test/dummy/tmp/pids/server.pid +1 -0
  228. data/test/dummy/tmp/simple.js.js +20 -0
  229. data/test/dummy/tmp/soy-1325274421.js +20 -0
  230. data/test/dummy/tmp/soy-1325286267.js +20 -0
  231. data/test/test_helper.rb +10 -0
  232. data/test/yellow-brick-road_test.rb +7 -0
  233. metadata +538 -0
@@ -0,0 +1,10 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1325040076.954355: @value{ I" length:EFiBI" digest;
2
+ F"%4f2ea434c1184f6094542c50ae5dbc2fI" source;
3
+ FI"B
4
+ root: ./my-closure
5
+
6
+ //= require_closure_root ./my-closure
7
+ ;
8
+ ;
9
+ FI"
10
+ F"%055b6301097847ea067f04e5d07d031b
@@ -0,0 +1,1355 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1325183043.2617128: @value{ I" length:EFi��I" digest;
2
+ F"%e1d40c42ffd632c09083fa0b68b3ed2bI" source;
3
+ FI"��// Copyright 2006 The Closure Library Authors. All Rights Reserved.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS-IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+
17
+ /**
18
+ * @fileoverview Utilities for manipulating arrays.
19
+ *
20
+ */
21
+
22
+
23
+
24
+
25
+ goog.provide('goog.array');
26
+ goog.provide('goog.array.ArrayLike');
27
+
28
+ goog.require('goog.asserts');
29
+
30
+
31
+ /**
32
+ * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should
33
+ * rely on Array.prototype functions, if available.
34
+ *
35
+ * The Array.prototype functions can be defined by external libraries like
36
+ * Prototype and setting this flag to false forces closure to use its own
37
+ * goog.array implementation.
38
+ *
39
+ * If your javascript can be loaded by a third party site and you are wary about
40
+ * relying on the prototype functions, specify
41
+ * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler.
42
+ */
43
+ goog.NATIVE_ARRAY_PROTOTYPES = true;
44
+
45
+
46
+ /**
47
+ * @typedef {Array|NodeList|Arguments|{length: number}}
48
+ */
49
+ goog.array.ArrayLike;
50
+
51
+
52
+ /**
53
+ * Returns the last element in an array without removing it.
54
+ * @param {goog.array.ArrayLike} array The array.
55
+ * @return {*} Last item in array.
56
+ */
57
+ goog.array.peek = function(array) {
58
+ return array[array.length - 1];
59
+ };
60
+
61
+
62
+ /**
63
+ * Reference to the original {@code Array.prototype}.
64
+ * @private
65
+ */
66
+ goog.array.ARRAY_PROTOTYPE_ = Array.prototype;
67
+
68
+
69
+ // NOTE(arv): Since most of the array functions are generic it allows you to
70
+ // pass an array-like object. Strings have a length and are considered array-
71
+ // like. However, the 'in' operator does not work on strings so we cannot just
72
+ // use the array path even if the browser supports indexing into strings. We
73
+ // therefore end up splitting the string.
74
+
75
+
76
+ /**
77
+ * Returns the index of the first element of an array with a specified
78
+ * value, or -1 if the element is not present in the array.
79
+ *
80
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}
81
+ *
82
+ * @param {goog.array.ArrayLike} arr The array to be searched.
83
+ * @param {*} obj The object for which we are searching.
84
+ * @param {number=} opt_fromIndex The index at which to start the search. If
85
+ * omitted the search starts at index 0.
86
+ * @return {number} The index of the first matching array element.
87
+ */
88
+ goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
89
+ goog.array.ARRAY_PROTOTYPE_.indexOf ?
90
+ function(arr, obj, opt_fromIndex) {
91
+ goog.asserts.assert(arr.length != null);
92
+
93
+ return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex);
94
+ } :
95
+ function(arr, obj, opt_fromIndex) {
96
+ var fromIndex = opt_fromIndex == null ?
97
+ 0 : (opt_fromIndex < 0 ?
98
+ Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex);
99
+
100
+ if (goog.isString(arr)) {
101
+ // Array.prototype.indexOf uses === so only strings should be found.
102
+ if (!goog.isString(obj) || obj.length != 1) {
103
+ return -1;
104
+ }
105
+ return arr.indexOf(obj, fromIndex);
106
+ }
107
+
108
+ for (var i = fromIndex; i < arr.length; i++) {
109
+ if (i in arr && arr[i] === obj)
110
+ return i;
111
+ }
112
+ return -1;
113
+ };
114
+
115
+
116
+ /**
117
+ * Returns the index of the last element of an array with a specified value, or
118
+ * -1 if the element is not present in the array.
119
+ *
120
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}
121
+ *
122
+ * @param {goog.array.ArrayLike} arr The array to be searched.
123
+ * @param {*} obj The object for which we are searching.
124
+ * @param {?number=} opt_fromIndex The index at which to start the search. If
125
+ * omitted the search starts at the end of the array.
126
+ * @return {number} The index of the last matching array element.
127
+ */
128
+ goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
129
+ goog.array.ARRAY_PROTOTYPE_.lastIndexOf ?
130
+ function(arr, obj, opt_fromIndex) {
131
+ goog.asserts.assert(arr.length != null);
132
+
133
+ // Firefox treats undefined and null as 0 in the fromIndex argument which
134
+ // leads it to always return -1
135
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
136
+ return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex);
137
+ } :
138
+ function(arr, obj, opt_fromIndex) {
139
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
140
+
141
+ if (fromIndex < 0) {
142
+ fromIndex = Math.max(0, arr.length + fromIndex);
143
+ }
144
+
145
+ if (goog.isString(arr)) {
146
+ // Array.prototype.lastIndexOf uses === so only strings should be found.
147
+ if (!goog.isString(obj) || obj.length != 1) {
148
+ return -1;
149
+ }
150
+ return arr.lastIndexOf(obj, fromIndex);
151
+ }
152
+
153
+ for (var i = fromIndex; i >= 0; i--) {
154
+ if (i in arr && arr[i] === obj)
155
+ return i;
156
+ }
157
+ return -1;
158
+ };
159
+
160
+
161
+ /**
162
+ * Calls a function for each element in an array.
163
+ *
164
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}
165
+ *
166
+ * @param {goog.array.ArrayLike} arr Array or array like object over
167
+ * which to iterate.
168
+ * @param {?function(this: T, ...)} f The function to call for every element.
169
+ * This function takes 3 arguments (the element, the index and the array).
170
+ * The return value is ignored. The function is called only for indexes of
171
+ * the array which have assigned values; it is not called for indexes which
172
+ * have been deleted or which have never been assigned values.
173
+ * @param {T=} opt_obj The object to be used as the value of 'this'
174
+ * within f.
175
+ * @template T
176
+ */
177
+ goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&
178
+ goog.array.ARRAY_PROTOTYPE_.forEach ?
179
+ function(arr, f, opt_obj) {
180
+ goog.asserts.assert(arr.length != null);
181
+
182
+ goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj);
183
+ } :
184
+ function(arr, f, opt_obj) {
185
+ var l = arr.length; // must be fixed during loop... see docs
186
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
187
+ for (var i = 0; i < l; i++) {
188
+ if (i in arr2) {
189
+ f.call(opt_obj, arr2[i], i, arr);
190
+ }
191
+ }
192
+ };
193
+
194
+
195
+ /**
196
+ * Calls a function for each element in an array, starting from the last
197
+ * element rather than the first.
198
+ *
199
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
200
+ * @param {Function} f The function to call for every element. This function
201
+ * takes 3 arguments (the element, the index and the array). The return
202
+ * value is ignored.
203
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
204
+ * within f.
205
+ */
206
+ goog.array.forEachRight = function(arr, f, opt_obj) {
207
+ var l = arr.length; // must be fixed during loop... see docs
208
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
209
+ for (var i = l - 1; i >= 0; --i) {
210
+ if (i in arr2) {
211
+ f.call(opt_obj, arr2[i], i, arr);
212
+ }
213
+ }
214
+ };
215
+
216
+
217
+ /**
218
+ * Calls a function for each element in an array, and if the function returns
219
+ * true adds the element to a new array.
220
+ *
221
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}
222
+ *
223
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
224
+ * @param {Function} f The function to call for every element. This function
225
+ * takes 3 arguments (the element, the index and the array) and must
226
+ * return a Boolean. If the return value is true the element is added to the
227
+ * result array. If it is false the element is not included.
228
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
229
+ * within f.
230
+ * @return {!Array} a new array in which only elements that passed the test are
231
+ * present.
232
+ */
233
+ goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&
234
+ goog.array.ARRAY_PROTOTYPE_.filter ?
235
+ function(arr, f, opt_obj) {
236
+ goog.asserts.assert(arr.length != null);
237
+
238
+ return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj);
239
+ } :
240
+ function(arr, f, opt_obj) {
241
+ var l = arr.length; // must be fixed during loop... see docs
242
+ var res = [];
243
+ var resLength = 0;
244
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
245
+ for (var i = 0; i < l; i++) {
246
+ if (i in arr2) {
247
+ var val = arr2[i]; // in case f mutates arr2
248
+ if (f.call(opt_obj, val, i, arr)) {
249
+ res[resLength++] = val;
250
+ }
251
+ }
252
+ }
253
+ return res;
254
+ };
255
+
256
+
257
+ /**
258
+ * Calls a function for each element in an array and inserts the result into a
259
+ * new array.
260
+ *
261
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-map}
262
+ *
263
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
264
+ * @param {Function} f The function to call for every element. This function
265
+ * takes 3 arguments (the element, the index and the array) and should
266
+ * return something. The result will be inserted into a new array.
267
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
268
+ * within f.
269
+ * @return {!Array} a new array with the results from f.
270
+ */
271
+ goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&
272
+ goog.array.ARRAY_PROTOTYPE_.map ?
273
+ function(arr, f, opt_obj) {
274
+ goog.asserts.assert(arr.length != null);
275
+
276
+ return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj);
277
+ } :
278
+ function(arr, f, opt_obj) {
279
+ var l = arr.length; // must be fixed during loop... see docs
280
+ var res = new Array(l);
281
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
282
+ for (var i = 0; i < l; i++) {
283
+ if (i in arr2) {
284
+ res[i] = f.call(opt_obj, arr2[i], i, arr);
285
+ }
286
+ }
287
+ return res;
288
+ };
289
+
290
+
291
+ /**
292
+ * Passes every element of an array into a function and accumulates the result.
293
+ *
294
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}
295
+ *
296
+ * For example:
297
+ * var a = [1, 2, 3, 4];
298
+ * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0);
299
+ * returns 10
300
+ *
301
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
302
+ * @param {Function} f The function to call for every element. This function
303
+ * takes 4 arguments (the function's previous result or the initial value,
304
+ * the value of the current array element, the current array index, and the
305
+ * array itself)
306
+ * function(previousValue, currentValue, index, array).
307
+ * @param {*} val The initial value to pass into the function on the first call.
308
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
309
+ * within f.
310
+ * @return {*} Result of evaluating f repeatedly across the values of the array.
311
+ */
312
+ goog.array.reduce = function(arr, f, val, opt_obj) {
313
+ if (arr.reduce) {
314
+ if (opt_obj) {
315
+ return arr.reduce(goog.bind(f, opt_obj), val);
316
+ } else {
317
+ return arr.reduce(f, val);
318
+ }
319
+ }
320
+ var rval = val;
321
+ goog.array.forEach(arr, function(val, index) {
322
+ rval = f.call(opt_obj, rval, val, index, arr);
323
+ });
324
+ return rval;
325
+ };
326
+
327
+
328
+ /**
329
+ * Passes every element of an array into a function and accumulates the result,
330
+ * starting from the last element and working towards the first.
331
+ *
332
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}
333
+ *
334
+ * For example:
335
+ * var a = ['a', 'b', 'c'];
336
+ * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, '');
337
+ * returns 'cba'
338
+ *
339
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
340
+ * @param {Function} f The function to call for every element. This function
341
+ * takes 4 arguments (the function's previous result or the initial value,
342
+ * the value of the current array element, the current array index, and the
343
+ * array itself)
344
+ * function(previousValue, currentValue, index, array).
345
+ * @param {*} val The initial value to pass into the function on the first call.
346
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
347
+ * within f.
348
+ * @return {*} Object returned as a result of evaluating f repeatedly across the
349
+ * values of the array.
350
+ */
351
+ goog.array.reduceRight = function(arr, f, val, opt_obj) {
352
+ if (arr.reduceRight) {
353
+ if (opt_obj) {
354
+ return arr.reduceRight(goog.bind(f, opt_obj), val);
355
+ } else {
356
+ return arr.reduceRight(f, val);
357
+ }
358
+ }
359
+ var rval = val;
360
+ goog.array.forEachRight(arr, function(val, index) {
361
+ rval = f.call(opt_obj, rval, val, index, arr);
362
+ });
363
+ return rval;
364
+ };
365
+
366
+
367
+ /**
368
+ * Calls f for each element of an array. If any call returns true, some()
369
+ * returns true (without checking the remaining elements). If all calls
370
+ * return false, some() returns false.
371
+ *
372
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-some}
373
+ *
374
+ * @param {goog.array.ArrayLike} arr The array to check.
375
+ * @param {Function} f The function to call for every element. This function
376
+ * takes 3 arguments (the element, the index and the array) and must
377
+ * return a Boolean.
378
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
379
+ * within f.
380
+ * @return {boolean} true if any element passes the test.
381
+ */
382
+ goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&
383
+ goog.array.ARRAY_PROTOTYPE_.some ?
384
+ function(arr, f, opt_obj) {
385
+ goog.asserts.assert(arr.length != null);
386
+
387
+ return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj);
388
+ } :
389
+ function(arr, f, opt_obj) {
390
+ var l = arr.length; // must be fixed during loop... see docs
391
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
392
+ for (var i = 0; i < l; i++) {
393
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
394
+ return true;
395
+ }
396
+ }
397
+ return false;
398
+ };
399
+
400
+
401
+ /**
402
+ * Call f for each element of an array. If all calls return true, every()
403
+ * returns true. If any call returns false, every() returns false and
404
+ * does not continue to check the remaining elements.
405
+ *
406
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-every}
407
+ *
408
+ * @param {goog.array.ArrayLike} arr The array to check.
409
+ * @param {Function} f The function to call for every element. This function
410
+ * takes 3 arguments (the element, the index and the array) and must
411
+ * return a Boolean.
412
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
413
+ * within f.
414
+ * @return {boolean} false if any element fails the test.
415
+ */
416
+ goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&
417
+ goog.array.ARRAY_PROTOTYPE_.every ?
418
+ function(arr, f, opt_obj) {
419
+ goog.asserts.assert(arr.length != null);
420
+
421
+ return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj);
422
+ } :
423
+ function(arr, f, opt_obj) {
424
+ var l = arr.length; // must be fixed during loop... see docs
425
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
426
+ for (var i = 0; i < l; i++) {
427
+ if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {
428
+ return false;
429
+ }
430
+ }
431
+ return true;
432
+ };
433
+
434
+
435
+ /**
436
+ * Search an array for the first element that satisfies a given condition and
437
+ * return that element.
438
+ * @param {goog.array.ArrayLike} arr The array to search.
439
+ * @param {Function} f The function to call for every element. This function
440
+ * takes 3 arguments (the element, the index and the array) and should
441
+ * return a boolean.
442
+ * @param {Object=} opt_obj An optional "this" context for the function.
443
+ * @return {*} The first array element that passes the test, or null if no
444
+ * element is found.
445
+ */
446
+ goog.array.find = function(arr, f, opt_obj) {
447
+ var i = goog.array.findIndex(arr, f, opt_obj);
448
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
449
+ };
450
+
451
+
452
+ /**
453
+ * Search an array for the first element that satisfies a given condition and
454
+ * return its index.
455
+ * @param {goog.array.ArrayLike} arr The array to search.
456
+ * @param {Function} f The function to call for every element. This function
457
+ * takes 3 arguments (the element, the index and the array) and should
458
+ * return a boolean.
459
+ * @param {Object=} opt_obj An optional "this" context for the function.
460
+ * @return {number} The index of the first array element that passes the test,
461
+ * or -1 if no element is found.
462
+ */
463
+ goog.array.findIndex = function(arr, f, opt_obj) {
464
+ var l = arr.length; // must be fixed during loop... see docs
465
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
466
+ for (var i = 0; i < l; i++) {
467
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
468
+ return i;
469
+ }
470
+ }
471
+ return -1;
472
+ };
473
+
474
+
475
+ /**
476
+ * Search an array (in reverse order) for the last element that satisfies a
477
+ * given condition and return that element.
478
+ * @param {goog.array.ArrayLike} arr The array to search.
479
+ * @param {Function} f The function to call for every element. This function
480
+ * takes 3 arguments (the element, the index and the array) and should
481
+ * return a boolean.
482
+ * @param {Object=} opt_obj An optional "this" context for the function.
483
+ * @return {*} The last array element that passes the test, or null if no
484
+ * element is found.
485
+ */
486
+ goog.array.findRight = function(arr, f, opt_obj) {
487
+ var i = goog.array.findIndexRight(arr, f, opt_obj);
488
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
489
+ };
490
+
491
+
492
+ /**
493
+ * Search an array (in reverse order) for the last element that satisfies a
494
+ * given condition and return its index.
495
+ * @param {goog.array.ArrayLike} arr The array to search.
496
+ * @param {Function} f The function to call for every element. This function
497
+ * takes 3 arguments (the element, the index and the array) and should
498
+ * return a boolean.
499
+ * @param {Object=} opt_obj An optional "this" context for the function.
500
+ * @return {number} The index of the last array element that passes the test,
501
+ * or -1 if no element is found.
502
+ */
503
+ goog.array.findIndexRight = function(arr, f, opt_obj) {
504
+ var l = arr.length; // must be fixed during loop... see docs
505
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
506
+ for (var i = l - 1; i >= 0; i--) {
507
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
508
+ return i;
509
+ }
510
+ }
511
+ return -1;
512
+ };
513
+
514
+
515
+ /**
516
+ * Whether the array contains the given object.
517
+ * @param {goog.array.ArrayLike} arr The array to test for the presence of the
518
+ * element.
519
+ * @param {*} obj The object for which to test.
520
+ * @return {boolean} true if obj is present.
521
+ */
522
+ goog.array.contains = function(arr, obj) {
523
+ return goog.array.indexOf(arr, obj) >= 0;
524
+ };
525
+
526
+
527
+ /**
528
+ * Whether the array is empty.
529
+ * @param {goog.array.ArrayLike} arr The array to test.
530
+ * @return {boolean} true if empty.
531
+ */
532
+ goog.array.isEmpty = function(arr) {
533
+ return arr.length == 0;
534
+ };
535
+
536
+
537
+ /**
538
+ * Clears the array.
539
+ * @param {goog.array.ArrayLike} arr Array or array like object to clear.
540
+ */
541
+ goog.array.clear = function(arr) {
542
+ // For non real arrays we don't have the magic length so we delete the
543
+ // indices.
544
+ if (!goog.isArray(arr)) {
545
+ for (var i = arr.length - 1; i >= 0; i--) {
546
+ delete arr[i];
547
+ }
548
+ }
549
+ arr.length = 0;
550
+ };
551
+
552
+
553
+ /**
554
+ * Pushes an item into an array, if it's not already in the array.
555
+ * @param {Array} arr Array into which to insert the item.
556
+ * @param {*} obj Value to add.
557
+ */
558
+ goog.array.insert = function(arr, obj) {
559
+ if (!goog.array.contains(arr, obj)) {
560
+ arr.push(obj);
561
+ }
562
+ };
563
+
564
+
565
+ /**
566
+ * Inserts an object at the given index of the array.
567
+ * @param {goog.array.ArrayLike} arr The array to modify.
568
+ * @param {*} obj The object to insert.
569
+ * @param {number=} opt_i The index at which to insert the object. If omitted,
570
+ * treated as 0. A negative index is counted from the end of the array.
571
+ */
572
+ goog.array.insertAt = function(arr, obj, opt_i) {
573
+ goog.array.splice(arr, opt_i, 0, obj);
574
+ };
575
+
576
+
577
+ /**
578
+ * Inserts at the given index of the array, all elements of another array.
579
+ * @param {goog.array.ArrayLike} arr The array to modify.
580
+ * @param {goog.array.ArrayLike} elementsToAdd The array of elements to add.
581
+ * @param {number=} opt_i The index at which to insert the object. If omitted,
582
+ * treated as 0. A negative index is counted from the end of the array.
583
+ */
584
+ goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {
585
+ goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);
586
+ };
587
+
588
+
589
+ /**
590
+ * Inserts an object into an array before a specified object.
591
+ * @param {Array} arr The array to modify.
592
+ * @param {*} obj The object to insert.
593
+ * @param {*=} opt_obj2 The object before which obj should be inserted. If obj2
594
+ * is omitted or not found, obj is inserted at the end of the array.
595
+ */
596
+ goog.array.insertBefore = function(arr, obj, opt_obj2) {
597
+ var i;
598
+ if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {
599
+ arr.push(obj);
600
+ } else {
601
+ goog.array.insertAt(arr, obj, i);
602
+ }
603
+ };
604
+
605
+
606
+ /**
607
+ * Removes the first occurrence of a particular value from an array.
608
+ * @param {goog.array.ArrayLike} arr Array from which to remove value.
609
+ * @param {*} obj Object to remove.
610
+ * @return {boolean} True if an element was removed.
611
+ */
612
+ goog.array.remove = function(arr, obj) {
613
+ var i = goog.array.indexOf(arr, obj);
614
+ var rv;
615
+ if ((rv = i >= 0)) {
616
+ goog.array.removeAt(arr, i);
617
+ }
618
+ return rv;
619
+ };
620
+
621
+
622
+ /**
623
+ * Removes from an array the element at index i
624
+ * @param {goog.array.ArrayLike} arr Array or array like object from which to
625
+ * remove value.
626
+ * @param {number} i The index to remove.
627
+ * @return {boolean} True if an element was removed.
628
+ */
629
+ goog.array.removeAt = function(arr, i) {
630
+ goog.asserts.assert(arr.length != null);
631
+
632
+ // use generic form of splice
633
+ // splice returns the removed items and if successful the length of that
634
+ // will be 1
635
+ return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1;
636
+ };
637
+
638
+
639
+ /**
640
+ * Removes the first value that satisfies the given condition.
641
+ * @param {goog.array.ArrayLike} arr Array from which to remove value.
642
+ * @param {Function} f The function to call for every element. This function
643
+ * takes 3 arguments (the element, the index and the array) and should
644
+ * return a boolean.
645
+ * @param {Object=} opt_obj An optional "this" context for the function.
646
+ * @return {boolean} True if an element was removed.
647
+ */
648
+ goog.array.removeIf = function(arr, f, opt_obj) {
649
+ var i = goog.array.findIndex(arr, f, opt_obj);
650
+ if (i >= 0) {
651
+ goog.array.removeAt(arr, i);
652
+ return true;
653
+ }
654
+ return false;
655
+ };
656
+
657
+
658
+ /**
659
+ * Returns a new array that is the result of joining the arguments. If arrays
660
+ * are passed then their items are added, however, if non-arrays are passed they
661
+ * will be added to the return array as is.
662
+ *
663
+ * Note that ArrayLike objects will be added as is, rather than having their
664
+ * items added.
665
+ *
666
+ * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]
667
+ * goog.array.concat(0, [1, 2]) -> [0, 1, 2]
668
+ * goog.array.concat([1, 2], null) -> [1, 2, null]
669
+ *
670
+ * There is bug in all current versions of IE (6, 7 and 8) where arrays created
671
+ * in an iframe become corrupted soon (not immediately) after the iframe is
672
+ * destroyed. This is common if loading data via goog.net.IframeIo, for example.
673
+ * This corruption only affects the concat method which will start throwing
674
+ * Catastrophic Errors (#-2147418113).
675
+ *
676
+ * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.
677
+ *
678
+ * Internally goog.array should use this, so that all methods will continue to
679
+ * work on these broken array objects.
680
+ *
681
+ * @param {...*} var_args Items to concatenate. Arrays will have each item
682
+ * added, while primitives and objects will be added as is.
683
+ * @return {!Array} The new resultant array.
684
+ */
685
+ goog.array.concat = function(var_args) {
686
+ return goog.array.ARRAY_PROTOTYPE_.concat.apply(
687
+ goog.array.ARRAY_PROTOTYPE_, arguments);
688
+ };
689
+
690
+
691
+ /**
692
+ * Does a shallow copy of an array.
693
+ * @param {goog.array.ArrayLike} arr Array or array-like object to clone.
694
+ * @return {!Array} Clone of the input array.
695
+ */
696
+ goog.array.clone = function(arr) {
697
+ if (goog.isArray(arr)) {
698
+ return goog.array.concat(/** @type {!Array} */ (arr));
699
+ } else { // array like
700
+ // Concat does not work with non arrays.
701
+ var rv = [];
702
+ for (var i = 0, len = arr.length; i < len; i++) {
703
+ rv[i] = arr[i];
704
+ }
705
+ return rv;
706
+ }
707
+ };
708
+
709
+
710
+ /**
711
+ * Converts an object to an array.
712
+ * @param {goog.array.ArrayLike} object The object to convert to an array.
713
+ * @return {!Array} The object converted into an array. If object has a
714
+ * length property, every property indexed with a non-negative number
715
+ * less than length will be included in the result. If object does not
716
+ * have a length property, an empty array will be returned.
717
+ */
718
+ goog.array.toArray = function(object) {
719
+ if (goog.isArray(object)) {
720
+ // This fixes the JS compiler warning and forces the Object to an Array type
721
+ return goog.array.concat(/** @type {!Array} */ (object));
722
+ }
723
+ // Clone what we hope to be an array-like object to an array.
724
+ // We could check isArrayLike() first, but no check we perform would be as
725
+ // reliable as simply making the call.
726
+ return goog.array.clone(/** @type {Array} */ (object));
727
+ };
728
+
729
+
730
+ /**
731
+ * Extends an array with another array, element, or "array like" object.
732
+ * This function operates 'in-place', it does not create a new Array.
733
+ *
734
+ * Example:
735
+ * var a = [];
736
+ * goog.array.extend(a, [0, 1]);
737
+ * a; // [0, 1]
738
+ * goog.array.extend(a, 2);
739
+ * a; // [0, 1, 2]
740
+ *
741
+ * @param {Array} arr1 The array to modify.
742
+ * @param {...*} var_args The elements or arrays of elements to add to arr1.
743
+ */
744
+ goog.array.extend = function(arr1, var_args) {
745
+ for (var i = 1; i < arguments.length; i++) {
746
+ var arr2 = arguments[i];
747
+ // If we have an Array or an Arguments object we can just call push
748
+ // directly.
749
+ var isArrayLike;
750
+ if (goog.isArray(arr2) ||
751
+ // Detect Arguments. ES5 says that the [[Class]] of an Arguments object
752
+ // is "Arguments" but only V8 and JSC/Safari gets this right. We instead
753
+ // detect Arguments by checking for array like and presence of "callee".
754
+ (isArrayLike = goog.isArrayLike(arr2)) &&
755
+ // The getter for callee throws an exception in strict mode
756
+ // according to section 10.6 in ES5 so check for presence instead.
757
+ arr2.hasOwnProperty('callee')) {
758
+ arr1.push.apply(arr1, arr2);
759
+
760
+ } else if (isArrayLike) {
761
+ // Otherwise loop over arr2 to prevent copying the object.
762
+ var len1 = arr1.length;
763
+ var len2 = arr2.length;
764
+ for (var j = 0; j < len2; j++) {
765
+ arr1[len1 + j] = arr2[j];
766
+ }
767
+ } else {
768
+ arr1.push(arr2);
769
+ }
770
+ }
771
+ };
772
+
773
+
774
+ /**
775
+ * Adds or removes elements from an array. This is a generic version of Array
776
+ * splice. This means that it might work on other objects similar to arrays,
777
+ * such as the arguments object.
778
+ *
779
+ * @param {goog.array.ArrayLike} arr The array to modify.
780
+ * @param {number|undefined} index The index at which to start changing the
781
+ * array. If not defined, treated as 0.
782
+ * @param {number} howMany How many elements to remove (0 means no removal. A
783
+ * value below 0 is treated as zero and so is any other non number. Numbers
784
+ * are floored).
785
+ * @param {...*} var_args Optional, additional elements to insert into the
786
+ * array.
787
+ * @return {!Array} the removed elements.
788
+ */
789
+ goog.array.splice = function(arr, index, howMany, var_args) {
790
+ goog.asserts.assert(arr.length != null);
791
+
792
+ return goog.array.ARRAY_PROTOTYPE_.splice.apply(
793
+ arr, goog.array.slice(arguments, 1));
794
+ };
795
+
796
+
797
+ /**
798
+ * Returns a new array from a segment of an array. This is a generic version of
799
+ * Array slice. This means that it might work on other objects similar to
800
+ * arrays, such as the arguments object.
801
+ *
802
+ * @param {goog.array.ArrayLike} arr The array from which to copy a segment.
803
+ * @param {number} start The index of the first element to copy.
804
+ * @param {number=} opt_end The index after the last element to copy.
805
+ * @return {!Array} A new array containing the specified segment of the original
806
+ * array.
807
+ */
808
+ goog.array.slice = function(arr, start, opt_end) {
809
+ goog.asserts.assert(arr.length != null);
810
+
811
+ // passing 1 arg to slice is not the same as passing 2 where the second is
812
+ // null or undefined (in that case the second argument is treated as 0).
813
+ // we could use slice on the arguments object and then use apply instead of
814
+ // testing the length
815
+ if (arguments.length <= 2) {
816
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start);
817
+ } else {
818
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end);
819
+ }
820
+ };
821
+
822
+
823
+ /**
824
+ * Removes all duplicates from an array (retaining only the first
825
+ * occurrence of each array element). This function modifies the
826
+ * array in place and doesn't change the order of the non-duplicate items.
827
+ *
828
+ * For objects, duplicates are identified as having the same unique ID as
829
+ * defined by {@link goog.getUid}.
830
+ *
831
+ * Runtime: N,
832
+ * Worstcase space: 2N (no dupes)
833
+ *
834
+ * @param {goog.array.ArrayLike} arr The array from which to remove duplicates.
835
+ * @param {Array=} opt_rv An optional array in which to return the results,
836
+ * instead of performing the removal inplace. If specified, the original
837
+ * array will remain unchanged.
838
+ */
839
+ goog.array.removeDuplicates = function(arr, opt_rv) {
840
+ var returnArray = opt_rv || arr;
841
+
842
+ var seen = {}, cursorInsert = 0, cursorRead = 0;
843
+ while (cursorRead < arr.length) {
844
+ var current = arr[cursorRead++];
845
+
846
+ // Prefix each type with a single character representing the type to
847
+ // prevent conflicting keys (e.g. true and 'true').
848
+ var key = goog.isObject(current) ?
849
+ 'o' + goog.getUid(current) :
850
+ (typeof current).charAt(0) + current;
851
+
852
+ if (!Object.prototype.hasOwnProperty.call(seen, key)) {
853
+ seen[key] = true;
854
+ returnArray[cursorInsert++] = current;
855
+ }
856
+ }
857
+ returnArray.length = cursorInsert;
858
+ };
859
+
860
+
861
+ /**
862
+ * Searches the specified array for the specified target using the binary
863
+ * search algorithm. If no opt_compareFn is specified, elements are compared
864
+ * using <code>goog.array.defaultCompare</code>, which compares the elements
865
+ * using the built in < and > operators. This will produce the expected
866
+ * behavior for homogeneous arrays of String(s) and Number(s). The array
867
+ * specified <b>must</b> be sorted in ascending order (as defined by the
868
+ * comparison function). If the array is not sorted, results are undefined.
869
+ * If the array contains multiple instances of the specified target value, any
870
+ * of these instances may be found.
871
+ *
872
+ * Runtime: O(log n)
873
+ *
874
+ * @param {goog.array.ArrayLike} arr The array to be searched.
875
+ * @param {*} target The sought value.
876
+ * @param {Function=} opt_compareFn Optional comparison function by which the
877
+ * array is ordered. Should take 2 arguments to compare, and return a
878
+ * negative number, zero, or a positive number depending on whether the
879
+ * first argument is less than, equal to, or greater than the second.
880
+ * @return {number} Lowest index of the target value if found, otherwise
881
+ * (-(insertion point) - 1). The insertion point is where the value should
882
+ * be inserted into arr to preserve the sorted property. Return value >= 0
883
+ * iff target is found.
884
+ */
885
+ goog.array.binarySearch = function(arr, target, opt_compareFn) {
886
+ return goog.array.binarySearch_(arr,
887
+ opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,
888
+ target);
889
+ };
890
+
891
+
892
+ /**
893
+ * Selects an index in the specified array using the binary search algorithm.
894
+ * The evaluator receives an element and determines whether the desired index
895
+ * is before, at, or after it. The evaluator must be consistent (formally,
896
+ * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)
897
+ * must be monotonically non-increasing).
898
+ *
899
+ * Runtime: O(log n)
900
+ *
901
+ * @param {goog.array.ArrayLike} arr The array to be searched.
902
+ * @param {Function} evaluator Evaluator function that receives 3 arguments
903
+ * (the element, the index and the array). Should return a negative number,
904
+ * zero, or a positive number depending on whether the desired index is
905
+ * before, at, or after the element passed to it.
906
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
907
+ * within evaluator.
908
+ * @return {number} Index of the leftmost element matched by the evaluator, if
909
+ * such exists; otherwise (-(insertion point) - 1). The insertion point is
910
+ * the index of the first element for which the evaluator returns negative,
911
+ * or arr.length if no such element exists. The return value is non-negative
912
+ * iff a match is found.
913
+ */
914
+ goog.array.binarySelect = function(arr, evaluator, opt_obj) {
915
+ return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */,
916
+ undefined /* opt_target */, opt_obj);
917
+ };
918
+
919
+
920
+ /**
921
+ * Implementation of a binary search algorithm which knows how to use both
922
+ * comparison functions and evaluators. If an evaluator is provided, will call
923
+ * the evaluator with the given optional data object, conforming to the
924
+ * interface defined in binarySelect. Otherwise, if a comparison function is
925
+ * provided, will call the comparison function against the given data object.
926
+ *
927
+ * This implementation purposefully does not use goog.bind or goog.partial for
928
+ * performance reasons.
929
+ *
930
+ * Runtime: O(log n)
931
+ *
932
+ * @param {goog.array.ArrayLike} arr The array to be searched.
933
+ * @param {Function} compareFn Either an evaluator or a comparison function,
934
+ * as defined by binarySearch and binarySelect above.
935
+ * @param {boolean} isEvaluator Whether the function is an evaluator or a
936
+ * comparison function.
937
+ * @param {*=} opt_target If the function is a comparison function, then this is
938
+ * the target to binary search for.
939
+ * @param {Object=} opt_selfObj If the function is an evaluator, this is an
940
+ * optional this object for the evaluator.
941
+ * @return {number} Lowest index of the target value if found, otherwise
942
+ * (-(insertion point) - 1). The insertion point is where the value should
943
+ * be inserted into arr to preserve the sorted property. Return value >= 0
944
+ * iff target is found.
945
+ * @private
946
+ */
947
+ goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target,
948
+ opt_selfObj) {
949
+ var left = 0; // inclusive
950
+ var right = arr.length; // exclusive
951
+ var found;
952
+ while (left < right) {
953
+ var middle = (left + right) >> 1;
954
+ var compareResult;
955
+ if (isEvaluator) {
956
+ compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
957
+ } else {
958
+ compareResult = compareFn(opt_target, arr[middle]);
959
+ }
960
+ if (compareResult > 0) {
961
+ left = middle + 1;
962
+ } else {
963
+ right = middle;
964
+ // We are looking for the lowest index so we can't return immediately.
965
+ found = !compareResult;
966
+ }
967
+ }
968
+ // left is the index if found, or the insertion point otherwise.
969
+ // ~left is a shorthand for -left - 1.
970
+ return found ? left : ~left;
971
+ };
972
+
973
+
974
+ /**
975
+ * Sorts the specified array into ascending order. If no opt_compareFn is
976
+ * specified, elements are compared using
977
+ * <code>goog.array.defaultCompare</code>, which compares the elements using
978
+ * the built in < and > operators. This will produce the expected behavior
979
+ * for homogeneous arrays of String(s) and Number(s), unlike the native sort,
980
+ * but will give unpredictable results for heterogenous lists of strings and
981
+ * numbers with different numbers of digits.
982
+ *
983
+ * This sort is not guaranteed to be stable.
984
+ *
985
+ * Runtime: Same as <code>Array.prototype.sort</code>
986
+ *
987
+ * @param {Array} arr The array to be sorted.
988
+ * @param {Function=} opt_compareFn Optional comparison function by which the
989
+ * array is to be ordered. Should take 2 arguments to compare, and return a
990
+ * negative number, zero, or a positive number depending on whether the
991
+ * first argument is less than, equal to, or greater than the second.
992
+ */
993
+ goog.array.sort = function(arr, opt_compareFn) {
994
+ // TODO(arv): Update type annotation since null is not accepted.
995
+ goog.asserts.assert(arr.length != null);
996
+
997
+ goog.array.ARRAY_PROTOTYPE_.sort.call(
998
+ arr, opt_compareFn || goog.array.defaultCompare);
999
+ };
1000
+
1001
+
1002
+ /**
1003
+ * Sorts the specified array into ascending order in a stable way. If no
1004
+ * opt_compareFn is specified, elements are compared using
1005
+ * <code>goog.array.defaultCompare</code>, which compares the elements using
1006
+ * the built in < and > operators. This will produce the expected behavior
1007
+ * for homogeneous arrays of String(s) and Number(s).
1008
+ *
1009
+ * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional
1010
+ * O(n) overhead of copying the array twice.
1011
+ *
1012
+ * @param {Array} arr The array to be sorted.
1013
+ * @param {function(*, *): number=} opt_compareFn Optional comparison function
1014
+ * by which the array is to be ordered. Should take 2 arguments to compare,
1015
+ * and return a negative number, zero, or a positive number depending on
1016
+ * whether the first argument is less than, equal to, or greater than the
1017
+ * second.
1018
+ */
1019
+ goog.array.stableSort = function(arr, opt_compareFn) {
1020
+ for (var i = 0; i < arr.length; i++) {
1021
+ arr[i] = {index: i, value: arr[i]};
1022
+ }
1023
+ var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
1024
+ function stableCompareFn(obj1, obj2) {
1025
+ return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
1026
+ };
1027
+ goog.array.sort(arr, stableCompareFn);
1028
+ for (var i = 0; i < arr.length; i++) {
1029
+ arr[i] = arr[i].value;
1030
+ }
1031
+ };
1032
+
1033
+
1034
+ /**
1035
+ * Sorts an array of objects by the specified object key and compare
1036
+ * function. If no compare function is provided, the key values are
1037
+ * compared in ascending order using <code>goog.array.defaultCompare</code>.
1038
+ * This won't work for keys that get renamed by the compiler. So use
1039
+ * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.
1040
+ * @param {Array.<Object>} arr An array of objects to sort.
1041
+ * @param {string} key The object key to sort by.
1042
+ * @param {Function=} opt_compareFn The function to use to compare key
1043
+ * values.
1044
+ */
1045
+ goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
1046
+ var compare = opt_compareFn || goog.array.defaultCompare;
1047
+ goog.array.sort(arr, function(a, b) {
1048
+ return compare(a[key], b[key]);
1049
+ });
1050
+ };
1051
+
1052
+
1053
+ /**
1054
+ * Tells if the array is sorted.
1055
+ * @param {!Array} arr The array.
1056
+ * @param {Function=} opt_compareFn Function to compare the array elements.
1057
+ * Should take 2 arguments to compare, and return a negative number, zero,
1058
+ * or a positive number depending on whether the first argument is less
1059
+ * than, equal to, or greater than the second.
1060
+ * @param {boolean=} opt_strict If true no equal elements are allowed.
1061
+ * @return {boolean} Whether the array is sorted.
1062
+ */
1063
+ goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
1064
+ var compare = opt_compareFn || goog.array.defaultCompare;
1065
+ for (var i = 1; i < arr.length; i++) {
1066
+ var compareResult = compare(arr[i - 1], arr[i]);
1067
+ if (compareResult > 0 || compareResult == 0 && opt_strict) {
1068
+ return false;
1069
+ }
1070
+ }
1071
+ return true;
1072
+ };
1073
+
1074
+
1075
+ /**
1076
+ * Compares two arrays for equality. Two arrays are considered equal if they
1077
+ * have the same length and their corresponding elements are equal according to
1078
+ * the comparison function.
1079
+ *
1080
+ * @param {goog.array.ArrayLike} arr1 The first array to compare.
1081
+ * @param {goog.array.ArrayLike} arr2 The second array to compare.
1082
+ * @param {Function=} opt_equalsFn Optional comparison function.
1083
+ * Should take 2 arguments to compare, and return true if the arguments
1084
+ * are equal. Defaults to {@link goog.array.defaultCompareEquality} which
1085
+ * compares the elements using the built-in '===' operator.
1086
+ * @return {boolean} Whether the two arrays are equal.
1087
+ */
1088
+ goog.array.equals = function(arr1, arr2, opt_equalsFn) {
1089
+ if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||
1090
+ arr1.length != arr2.length) {
1091
+ return false;
1092
+ }
1093
+ var l = arr1.length;
1094
+ var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
1095
+ for (var i = 0; i < l; i++) {
1096
+ if (!equalsFn(arr1[i], arr2[i])) {
1097
+ return false;
1098
+ }
1099
+ }
1100
+ return true;
1101
+ };
1102
+
1103
+
1104
+ /**
1105
+ * @deprecated Use {@link goog.array.equals}.
1106
+ * @param {goog.array.ArrayLike} arr1 See {@link goog.array.equals}.
1107
+ * @param {goog.array.ArrayLike} arr2 See {@link goog.array.equals}.
1108
+ * @param {Function=} opt_equalsFn See {@link goog.array.equals}.
1109
+ * @return {boolean} See {@link goog.array.equals}.
1110
+ */
1111
+ goog.array.compare = function(arr1, arr2, opt_equalsFn) {
1112
+ return goog.array.equals(arr1, arr2, opt_equalsFn);
1113
+ };
1114
+
1115
+
1116
+ /**
1117
+ * 3-way array compare function.
1118
+ * @param {!goog.array.ArrayLike} arr1 The first array to compare.
1119
+ * @param {!goog.array.ArrayLike} arr2 The second array to compare.
1120
+ * @param {(function(*, *): number)=} opt_compareFn Optional comparison function
1121
+ * by which the array is to be ordered. Should take 2 arguments to compare,
1122
+ * and return a negative number, zero, or a positive number depending on
1123
+ * whether the first argument is less than, equal to, or greater than the
1124
+ * second.
1125
+ * @return {number} Negative number, zero, or a positive number depending on
1126
+ * whether the first argument is less than, equal to, or greater than the
1127
+ * second.
1128
+ */
1129
+ goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
1130
+ var compare = opt_compareFn || goog.array.defaultCompare;
1131
+ var l = Math.min(arr1.length, arr2.length);
1132
+ for (var i = 0; i < l; i++) {
1133
+ var result = compare(arr1[i], arr2[i]);
1134
+ if (result != 0) {
1135
+ return result;
1136
+ }
1137
+ }
1138
+ return goog.array.defaultCompare(arr1.length, arr2.length);
1139
+ };
1140
+
1141
+
1142
+ /**
1143
+ * Compares its two arguments for order, using the built in < and >
1144
+ * operators.
1145
+ * @param {*} a The first object to be compared.
1146
+ * @param {*} b The second object to be compared.
1147
+ * @return {number} A negative number, zero, or a positive number as the first
1148
+ * argument is less than, equal to, or greater than the second.
1149
+ */
1150
+ goog.array.defaultCompare = function(a, b) {
1151
+ return a > b ? 1 : a < b ? -1 : 0;
1152
+ };
1153
+
1154
+
1155
+ /**
1156
+ * Compares its two arguments for equality, using the built in === operator.
1157
+ * @param {*} a The first object to compare.
1158
+ * @param {*} b The second object to compare.
1159
+ * @return {boolean} True if the two arguments are equal, false otherwise.
1160
+ */
1161
+ goog.array.defaultCompareEquality = function(a, b) {
1162
+ return a === b;
1163
+ };
1164
+
1165
+
1166
+ /**
1167
+ * Inserts a value into a sorted array. The array is not modified if the
1168
+ * value is already present.
1169
+ * @param {Array} array The array to modify.
1170
+ * @param {*} value The object to insert.
1171
+ * @param {Function=} opt_compareFn Optional comparison function by which the
1172
+ * array is ordered. Should take 2 arguments to compare, and return a
1173
+ * negative number, zero, or a positive number depending on whether the
1174
+ * first argument is less than, equal to, or greater than the second.
1175
+ * @return {boolean} True if an element was inserted.
1176
+ */
1177
+ goog.array.binaryInsert = function(array, value, opt_compareFn) {
1178
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
1179
+ if (index < 0) {
1180
+ goog.array.insertAt(array, value, -(index + 1));
1181
+ return true;
1182
+ }
1183
+ return false;
1184
+ };
1185
+
1186
+
1187
+ /**
1188
+ * Removes a value from a sorted array.
1189
+ * @param {Array} array The array to modify.
1190
+ * @param {*} value The object to remove.
1191
+ * @param {Function=} opt_compareFn Optional comparison function by which the
1192
+ * array is ordered. Should take 2 arguments to compare, and return a
1193
+ * negative number, zero, or a positive number depending on whether the
1194
+ * first argument is less than, equal to, or greater than the second.
1195
+ * @return {boolean} True if an element was removed.
1196
+ */
1197
+ goog.array.binaryRemove = function(array, value, opt_compareFn) {
1198
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
1199
+ return (index >= 0) ? goog.array.removeAt(array, index) : false;
1200
+ };
1201
+
1202
+
1203
+ /**
1204
+ * Splits an array into disjoint buckets according to a splitting function.
1205
+ * @param {Array} array The array.
1206
+ * @param {Function} sorter Function to call for every element. This
1207
+ * takes 3 arguments (the element, the index and the array) and must
1208
+ * return a valid object key (a string, number, etc), or undefined, if
1209
+ * that object should not be placed in a bucket.
1210
+ * @return {!Object} An object, with keys being all of the unique return values
1211
+ * of sorter, and values being arrays containing the items for
1212
+ * which the splitter returned that key.
1213
+ */
1214
+ goog.array.bucket = function(array, sorter) {
1215
+ var buckets = {};
1216
+
1217
+ for (var i = 0; i < array.length; i++) {
1218
+ var value = array[i];
1219
+ var key = sorter(value, i, array);
1220
+ if (goog.isDef(key)) {
1221
+ // Push the value to the right bucket, creating it if necessary.
1222
+ var bucket = buckets[key] || (buckets[key] = []);
1223
+ bucket.push(value);
1224
+ }
1225
+ }
1226
+
1227
+ return buckets;
1228
+ };
1229
+
1230
+
1231
+ /**
1232
+ * Returns an array consisting of the given value repeated N times.
1233
+ *
1234
+ * @param {*} value The value to repeat.
1235
+ * @param {number} n The repeat count.
1236
+ * @return {!Array.<*>} An array with the repeated value.
1237
+ */
1238
+ goog.array.repeat = function(value, n) {
1239
+ var array = [];
1240
+ for (var i = 0; i < n; i++) {
1241
+ array[i] = value;
1242
+ }
1243
+ return array;
1244
+ };
1245
+
1246
+
1247
+ /**
1248
+ * Returns an array consisting of every argument with all arrays
1249
+ * expanded in-place recursively.
1250
+ *
1251
+ * @param {...*} var_args The values to flatten.
1252
+ * @return {!Array.<*>} An array containing the flattened values.
1253
+ */
1254
+ goog.array.flatten = function(var_args) {
1255
+ var result = [];
1256
+ for (var i = 0; i < arguments.length; i++) {
1257
+ var element = arguments[i];
1258
+ if (goog.isArray(element)) {
1259
+ result.push.apply(result, goog.array.flatten.apply(null, element));
1260
+ } else {
1261
+ result.push(element);
1262
+ }
1263
+ }
1264
+ return result;
1265
+ };
1266
+
1267
+
1268
+ /**
1269
+ * Rotates an array in-place. After calling this method, the element at
1270
+ * index i will be the element previously at index (i - n) %
1271
+ * array.length, for all values of i between 0 and array.length - 1,
1272
+ * inclusive.
1273
+ *
1274
+ * For example, suppose list comprises [t, a, n, k, s]. After invoking
1275
+ * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].
1276
+ *
1277
+ * @param {!Array.<*>} array The array to rotate.
1278
+ * @param {number} n The amount to rotate.
1279
+ * @return {!Array.<*>} The array.
1280
+ */
1281
+ goog.array.rotate = function(array, n) {
1282
+ goog.asserts.assert(array.length != null);
1283
+
1284
+ if (array.length) {
1285
+ n %= array.length;
1286
+ if (n > 0) {
1287
+ goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n));
1288
+ } else if (n < 0) {
1289
+ goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n));
1290
+ }
1291
+ }
1292
+ return array;
1293
+ };
1294
+
1295
+
1296
+ /**
1297
+ * Creates a new array for which the element at position i is an array of the
1298
+ * ith element of the provided arrays. The returned array will only be as long
1299
+ * as the shortest array provided; additional values are ignored. For example,
1300
+ * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].
1301
+ *
1302
+ * This is similar to the zip() function in Python. See {@link
1303
+ * http://docs.python.org/library/functions.html#zip}
1304
+ *
1305
+ * @param {...!goog.array.ArrayLike} var_args Arrays to be combined.
1306
+ * @return {!Array.<!Array>} A new array of arrays created from provided arrays.
1307
+ */
1308
+ goog.array.zip = function(var_args) {
1309
+ if (!arguments.length) {
1310
+ return [];
1311
+ }
1312
+ var result = [];
1313
+ for (var i = 0; true; i++) {
1314
+ var value = [];
1315
+ for (var j = 0; j < arguments.length; j++) {
1316
+ var arr = arguments[j];
1317
+ // If i is larger than the array length, this is the shortest array.
1318
+ if (i >= arr.length) {
1319
+ return result;
1320
+ }
1321
+ value.push(arr[i]);
1322
+ }
1323
+ result.push(value);
1324
+ }
1325
+ };
1326
+
1327
+
1328
+ /**
1329
+ * Shuffles the values in the specified array using the Fisher-Yates in-place
1330
+ * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()
1331
+ * and so resets the state of that random number generator. Similarly, may reset
1332
+ * the state of the any other specified random number generator.
1333
+ *
1334
+ * Runtime: O(n)
1335
+ *
1336
+ * @param {!Array} arr The array to be shuffled.
1337
+ * @param {Function=} opt_randFn Optional random function to use for shuffling.
1338
+ * Takes no arguments, and returns a random number on the interval [0, 1).
1339
+ * Defaults to Math.random() using JavaScript's built-in Math library.
1340
+ */
1341
+ goog.array.shuffle = function(arr, opt_randFn) {
1342
+ var randFn = opt_randFn || Math.random;
1343
+
1344
+ for (var i = arr.length - 1; i > 0; i--) {
1345
+ // Choose a random array index in [0, i] (inclusive with i).
1346
+ var j = Math.floor(randFn() * (i + 1));
1347
+
1348
+ var tmp = arr[i];
1349
+ arr[i] = arr[j];
1350
+ arr[j] = tmp;
1351
+ }
1352
+ };
1353
+ ;
1354
+ FI"
1355
+ F"%bfbf319264927dfad4ad5eea35bb23e4