sw2at-ui 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (387) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/Gemfile +21 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +19 -0
  6. data/Rakefile +51 -0
  7. data/VERSION +1 -0
  8. data/app/assets/images/swat/loading-green.gif +0 -0
  9. data/app/assets/javascripts/swat/.bowerrc +3 -0
  10. data/app/assets/javascripts/swat/app/app.coffee +38 -0
  11. data/app/assets/javascripts/swat/app/controllers/revision.coffee +25 -0
  12. data/app/assets/javascripts/swat/app/controllers/revisions.coffee +10 -0
  13. data/app/assets/javascripts/swat/app/controllers/root.coffee +8 -0
  14. data/app/assets/javascripts/swat/app/factories/response.coffee +9 -0
  15. data/app/assets/javascripts/swat/app/factories/revision_model.coffee +20 -0
  16. data/app/assets/javascripts/swat/app/services/revision.coffee +16 -0
  17. data/app/assets/javascripts/swat/app/services/test_case.coffee +8 -0
  18. data/app/assets/javascripts/swat/application.coffee +5 -0
  19. data/app/assets/javascripts/swat/bower.json +16 -0
  20. data/app/assets/javascripts/swat/bower_components/angular/angular-csp.css +21 -0
  21. data/app/assets/javascripts/swat/bower_components/angular/angular.js +28133 -0
  22. data/app/assets/javascripts/swat/bower_components/angular/angular.min.js +289 -0
  23. data/app/assets/javascripts/swat/bower_components/angular/index.js +2 -0
  24. data/app/assets/javascripts/swat/bower_components/angular-animate/angular-animate.js +2137 -0
  25. data/app/assets/javascripts/swat/bower_components/angular-animate/angular-animate.min.js +33 -0
  26. data/app/assets/javascripts/swat/bower_components/angular-aria/angular-aria.js +339 -0
  27. data/app/assets/javascripts/swat/bower_components/angular-aria/angular-aria.min.js +12 -0
  28. data/app/assets/javascripts/swat/bower_components/angular-bootstrap/ui-bootstrap-csp.css +6 -0
  29. data/app/assets/javascripts/swat/bower_components/angular-bootstrap/ui-bootstrap-tpls.js +4840 -0
  30. data/app/assets/javascripts/swat/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js +10 -0
  31. data/app/assets/javascripts/swat/bower_components/angular-bootstrap/ui-bootstrap.js +4461 -0
  32. data/app/assets/javascripts/swat/bower_components/angular-bootstrap/ui-bootstrap.min.js +9 -0
  33. data/app/assets/javascripts/swat/bower_components/angular-material/LICENSE.txt +21 -0
  34. data/app/assets/javascripts/swat/bower_components/angular-material/angular-material.css +6228 -0
  35. data/app/assets/javascripts/swat/bower_components/angular-material/angular-material.js +8602 -0
  36. data/app/assets/javascripts/swat/bower_components/angular-material/angular-material.min.css +6 -0
  37. data/app/assets/javascripts/swat/bower_components/angular-material/angular-material.min.js +277 -0
  38. data/app/assets/javascripts/swat/bower_components/angular-material/default-theme.css +394 -0
  39. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/backdrop/backdrop-default-theme.css +8 -0
  40. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/backdrop/backdrop.css +54 -0
  41. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/backdrop/backdrop.js +40 -0
  42. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/bottomSheet/bottomSheet-default-theme.css +15 -0
  43. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/bottomSheet/bottomSheet.css +161 -0
  44. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/bottomSheet/bottomSheet.js +263 -0
  45. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/button/button-default-theme.css +49 -0
  46. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/button/button.css +134 -0
  47. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/button/button.js +101 -0
  48. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/card/card-default-theme.css +10 -0
  49. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/card/card.css +26 -0
  50. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/card/card.js +60 -0
  51. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/checkbox/checkbox-default-theme.css +38 -0
  52. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/checkbox/checkbox.css +78 -0
  53. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/checkbox/checkbox.js +135 -0
  54. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/content/content-default-theme.css +8 -0
  55. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/content/content.css +24 -0
  56. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/content/content.js +87 -0
  57. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/core/core.css +2736 -0
  58. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/core/core.js +3090 -0
  59. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/core/default-theme.js +1 -0
  60. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/dialog/dialog-default-theme.css +11 -0
  61. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/dialog/dialog.css +75 -0
  62. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/dialog/dialog.js +500 -0
  63. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/divider/divider-default-theme.css +8 -0
  64. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/divider/divider.css +12 -0
  65. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/divider/divider.js +50 -0
  66. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/icon/icon.css +24 -0
  67. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/icon/icon.js +52 -0
  68. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/input/input-default-theme.css +39 -0
  69. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/input/input.css +113 -0
  70. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/input/input.js +355 -0
  71. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/list/list.css +56 -0
  72. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/list/list.js +96 -0
  73. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/menu/menu.css +6 -0
  74. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/menu/menu.js +29 -0
  75. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/progressCircular/progressCircular-default-theme.css +35 -0
  76. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/progressCircular/progressCircular.css +1395 -0
  77. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/progressCircular/progressCircular.js +129 -0
  78. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/progressLinear/progressLinear-default-theme.css +26 -0
  79. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/progressLinear/progressLinear.css +366 -0
  80. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/progressLinear/progressLinear.js +130 -0
  81. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/radioButton/radioButton-default-theme.css +39 -0
  82. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/radioButton/radioButton.css +66 -0
  83. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/radioButton/radioButton.js +302 -0
  84. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/sidenav/sidenav-default-theme.css +8 -0
  85. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/sidenav/sidenav.css +86 -0
  86. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/sidenav/sidenav.js +320 -0
  87. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/slider/slider-default-theme.css +55 -0
  88. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/slider/slider.css +210 -0
  89. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/slider/slider.js +391 -0
  90. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/sticky/sticky.css +20 -0
  91. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/sticky/sticky.js +314 -0
  92. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/subheader/subheader-default-theme.css +15 -0
  93. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/subheader/subheader.css +62 -0
  94. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/subheader/subheader.js +89 -0
  95. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/swipe/swipe.js +79 -0
  96. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/switch/switch-default-theme.css +29 -0
  97. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/switch/switch.css +81 -0
  98. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/switch/switch.js +171 -0
  99. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/tabs/tabs-default-theme.css +34 -0
  100. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/tabs/tabs.css +171 -0
  101. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/tabs/tabs.js +1009 -0
  102. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/textField/textField-default-theme.css +29 -0
  103. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/textField/textField.css +72 -0
  104. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/textField/textField.js +145 -0
  105. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/toast/toast-default-theme.css +17 -0
  106. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/toast/toast.css +110 -0
  107. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/toast/toast.js +236 -0
  108. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/toolbar/toolbar-default-theme.css +17 -0
  109. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/toolbar/toolbar.css +69 -0
  110. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/toolbar/toolbar.js +161 -0
  111. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/tooltip/tooltip-default-theme.css +10 -0
  112. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/tooltip/tooltip.css +133 -0
  113. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/tooltip/tooltip.js +199 -0
  114. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/whiteframe/whiteframe.css +20 -0
  115. data/app/assets/javascripts/swat/bower_components/angular-material/modules/closure/whiteframe/whiteframe.js +17 -0
  116. data/app/assets/javascripts/swat/bower_components/angular-material/modules/css/angular-material-layout.css +2582 -0
  117. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/backdrop-default-theme.css +8 -0
  118. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/backdrop-default-theme.min.css +6 -0
  119. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/backdrop.css +54 -0
  120. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/backdrop.js +38 -0
  121. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/backdrop.min.css +6 -0
  122. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/backdrop.min.js +7 -0
  123. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/backdrop/bower.json +7 -0
  124. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bottomSheet-default-theme.css +15 -0
  125. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bottomSheet-default-theme.min.css +6 -0
  126. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.css +188 -0
  127. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.js +293 -0
  128. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.min.css +6 -0
  129. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bottomSheet.min.js +7 -0
  130. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/bottomSheet/bower.json +8 -0
  131. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/bower.json +7 -0
  132. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/button-default-theme.css +42 -0
  133. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/button-default-theme.min.css +6 -0
  134. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/button.css +132 -0
  135. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/button.js +94 -0
  136. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/button.min.css +6 -0
  137. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/button/button.min.js +7 -0
  138. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/bower.json +7 -0
  139. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/card-default-theme.css +10 -0
  140. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/card-default-theme.min.css +6 -0
  141. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/card.css +31 -0
  142. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/card.js +58 -0
  143. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/card.min.css +6 -0
  144. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/card/card.min.js +7 -0
  145. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/bower.json +7 -0
  146. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/checkbox-default-theme.css +38 -0
  147. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/checkbox-default-theme.min.css +6 -0
  148. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/checkbox.css +79 -0
  149. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/checkbox.js +133 -0
  150. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/checkbox.min.css +6 -0
  151. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/checkbox/checkbox.min.js +7 -0
  152. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/bower.json +7 -0
  153. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/content-default-theme.css +8 -0
  154. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/content-default-theme.min.css +6 -0
  155. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/content.css +24 -0
  156. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/content.js +60 -0
  157. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/content.min.css +6 -0
  158. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/content/content.min.js +7 -0
  159. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/core/bower.json +7 -0
  160. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/core/core.css +3067 -0
  161. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/core/core.js +2780 -0
  162. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/core/core.min.css +6 -0
  163. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/core/core.min.js +7 -0
  164. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/core/default-theme.js +1 -0
  165. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/bower.json +8 -0
  166. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/dialog-default-theme.css +11 -0
  167. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/dialog-default-theme.min.css +6 -0
  168. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/dialog.css +88 -0
  169. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/dialog.js +495 -0
  170. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/dialog.min.css +6 -0
  171. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/dialog/dialog.min.js +7 -0
  172. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/bower.json +7 -0
  173. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/divider-default-theme.css +8 -0
  174. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/divider-default-theme.min.css +6 -0
  175. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/divider.css +12 -0
  176. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/divider.js +48 -0
  177. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/divider.min.css +6 -0
  178. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/divider/divider.min.js +7 -0
  179. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/icon/bower.json +7 -0
  180. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/icon/icon.css +24 -0
  181. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/icon/icon.js +50 -0
  182. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/icon/icon.min.css +6 -0
  183. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/icon/icon.min.js +7 -0
  184. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/bower.json +7 -0
  185. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/input-default-theme.css +40 -0
  186. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/input-default-theme.min.css +6 -0
  187. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/input.css +102 -0
  188. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/input.js +333 -0
  189. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/input.min.css +6 -0
  190. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/input/input.min.js +7 -0
  191. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/list/bower.json +7 -0
  192. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/list/list.css +61 -0
  193. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/list/list.js +94 -0
  194. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/list/list.min.css +6 -0
  195. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/list/list.min.js +7 -0
  196. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/menu/bower.json +5 -0
  197. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/menu/menu.css +6 -0
  198. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/menu/menu.js +27 -0
  199. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/menu/menu.min.css +6 -0
  200. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/menu/menu.min.js +7 -0
  201. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/bower.json +7 -0
  202. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/progressCircular-default-theme.css +35 -0
  203. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/progressCircular-default-theme.min.css +6 -0
  204. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/progressCircular.css +1445 -0
  205. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/progressCircular.js +127 -0
  206. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/progressCircular.min.css +6 -0
  207. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressCircular/progressCircular.min.js +7 -0
  208. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/bower.json +7 -0
  209. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/progressLinear-default-theme.css +28 -0
  210. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/progressLinear-default-theme.min.css +6 -0
  211. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/progressLinear.css +368 -0
  212. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/progressLinear.js +128 -0
  213. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/progressLinear.min.css +6 -0
  214. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/progressLinear/progressLinear.min.js +7 -0
  215. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/bower.json +7 -0
  216. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/radioButton-default-theme.css +39 -0
  217. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/radioButton-default-theme.min.css +6 -0
  218. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/radioButton.css +67 -0
  219. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/radioButton.js +296 -0
  220. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/radioButton.min.css +6 -0
  221. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/radioButton/radioButton.min.js +7 -0
  222. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/bower.json +8 -0
  223. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/sidenav-default-theme.css +8 -0
  224. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/sidenav-default-theme.min.css +6 -0
  225. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/sidenav.css +90 -0
  226. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/sidenav.js +302 -0
  227. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/sidenav.min.css +6 -0
  228. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sidenav/sidenav.min.js +7 -0
  229. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/bower.json +7 -0
  230. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/slider-default-theme.css +55 -0
  231. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/slider-default-theme.min.css +6 -0
  232. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/slider.css +218 -0
  233. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/slider.js +411 -0
  234. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/slider.min.css +6 -0
  235. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/slider/slider.min.js +7 -0
  236. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sticky/bower.json +8 -0
  237. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sticky/sticky.css +20 -0
  238. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sticky/sticky.js +309 -0
  239. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sticky/sticky.min.css +6 -0
  240. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/sticky/sticky.min.js +7 -0
  241. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/bower.json +8 -0
  242. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/subheader-default-theme.css +15 -0
  243. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/subheader-default-theme.min.css +6 -0
  244. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/subheader.css +61 -0
  245. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/subheader.js +86 -0
  246. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/subheader.min.css +6 -0
  247. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/subheader/subheader.min.js +7 -0
  248. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/swipe/bower.json +5 -0
  249. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/swipe/swipe.js +213 -0
  250. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/swipe/swipe.min.js +7 -0
  251. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/bower.json +8 -0
  252. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/switch-default-theme.css +29 -0
  253. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/switch-default-theme.min.css +6 -0
  254. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/switch.css +77 -0
  255. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/switch.js +144 -0
  256. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/switch.min.css +6 -0
  257. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/switch/switch.min.js +7 -0
  258. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/bower.json +7 -0
  259. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/tabs-default-theme.css +34 -0
  260. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/tabs-default-theme.min.css +6 -0
  261. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/tabs.css +181 -0
  262. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/tabs.js +992 -0
  263. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/tabs.min.css +6 -0
  264. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tabs/tabs.min.js +7 -0
  265. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/bower.json +7 -0
  266. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/textField-default-theme.css +29 -0
  267. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/textField-default-theme.min.css +6 -0
  268. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/textField.css +76 -0
  269. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/textField.js +143 -0
  270. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/textField.min.css +6 -0
  271. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/textField/textField.min.js +7 -0
  272. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/bower.json +9 -0
  273. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/toast-default-theme.css +17 -0
  274. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/toast-default-theme.min.css +6 -0
  275. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/toast.css +115 -0
  276. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/toast.js +235 -0
  277. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/toast.min.css +6 -0
  278. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toast/toast.min.js +7 -0
  279. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/bower.json +8 -0
  280. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/toolbar-default-theme.css +17 -0
  281. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/toolbar-default-theme.min.css +6 -0
  282. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/toolbar.css +78 -0
  283. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/toolbar.js +158 -0
  284. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/toolbar.min.css +6 -0
  285. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/toolbar/toolbar.min.js +7 -0
  286. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/bower.json +7 -0
  287. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/tooltip-default-theme.css +10 -0
  288. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/tooltip-default-theme.min.css +6 -0
  289. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/tooltip.css +136 -0
  290. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/tooltip.js +197 -0
  291. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/tooltip.min.css +6 -0
  292. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/tooltip/tooltip.min.js +7 -0
  293. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/whiteframe/bower.json +5 -0
  294. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/whiteframe/whiteframe.css +20 -0
  295. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/whiteframe/whiteframe.js +15 -0
  296. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/whiteframe/whiteframe.min.css +6 -0
  297. data/app/assets/javascripts/swat/bower_components/angular-material/modules/js/whiteframe/whiteframe.min.js +7 -0
  298. data/app/assets/javascripts/swat/bower_components/angular-resource/angular-resource.js +668 -0
  299. data/app/assets/javascripts/swat/bower_components/angular-resource/angular-resource.min.js +13 -0
  300. data/app/assets/javascripts/swat/bower_components/angular-resource/index.js +2 -0
  301. data/app/assets/javascripts/swat/bower_components/angular-route/angular-route.js +991 -0
  302. data/app/assets/javascripts/swat/bower_components/angular-route/angular-route.min.js +15 -0
  303. data/app/assets/javascripts/swat/bower_components/angular-route/index.js +2 -0
  304. data/app/assets/javascripts/swat/bower_components/angular-ui-router/LICENSE.txt +21 -0
  305. data/app/assets/javascripts/swat/bower_components/angular-ui-router/api/angular-ui-router.d.ts +126 -0
  306. data/app/assets/javascripts/swat/bower_components/angular-ui-router/release/angular-ui-router.js +4370 -0
  307. data/app/assets/javascripts/swat/bower_components/angular-ui-router/release/angular-ui-router.min.js +7 -0
  308. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/common.js +292 -0
  309. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/resolve.js +252 -0
  310. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/state.js +1465 -0
  311. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/stateDirectives.js +285 -0
  312. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/stateFilters.js +39 -0
  313. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/templateFactory.js +110 -0
  314. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/urlMatcherFactory.js +1050 -0
  315. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/urlRouter.js +427 -0
  316. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/view.js +71 -0
  317. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/viewDirective.js +303 -0
  318. data/app/assets/javascripts/swat/bower_components/angular-ui-router/src/viewScroll.js +52 -0
  319. data/app/assets/javascripts/swat/bower_components/lodash/lodash.js +12235 -0
  320. data/app/assets/javascripts/swat/bower_components/lodash/lodash.min.js +98 -0
  321. data/app/assets/javascripts/swat/bower_components/ng-clip/.editorconfig +10 -0
  322. data/app/assets/javascripts/swat/bower_components/ng-clip/.gitignore +3 -0
  323. data/app/assets/javascripts/swat/bower_components/ng-clip/Gruntfile.js +96 -0
  324. data/app/assets/javascripts/swat/bower_components/ng-clip/dest/ng-clip.min.js +2 -0
  325. data/app/assets/javascripts/swat/bower_components/ng-clip/example/bootstrap-tooltip.html +49 -0
  326. data/app/assets/javascripts/swat/bower_components/ng-clip/example/index.html +68 -0
  327. data/app/assets/javascripts/swat/bower_components/ng-clip/example/ng-repeat.html +44 -0
  328. data/app/assets/javascripts/swat/bower_components/ng-clip/npm-debug.log +145 -0
  329. data/app/assets/javascripts/swat/bower_components/ng-clip/src/ngClip.js +84 -0
  330. data/app/assets/javascripts/swat/bower_components/zeroclipboard/dist/.jshintrc +70 -0
  331. data/app/assets/javascripts/swat/bower_components/zeroclipboard/dist/ZeroClipboard.Core.js +2017 -0
  332. data/app/assets/javascripts/swat/bower_components/zeroclipboard/dist/ZeroClipboard.Core.min.js +10 -0
  333. data/app/assets/javascripts/swat/bower_components/zeroclipboard/dist/ZeroClipboard.js +2581 -0
  334. data/app/assets/javascripts/swat/bower_components/zeroclipboard/dist/ZeroClipboard.min.js +10 -0
  335. data/app/assets/javascripts/swat/bower_components/zeroclipboard/dist/ZeroClipboard.swf +0 -0
  336. data/app/assets/javascripts/swat/bower_components.coffee +12 -0
  337. data/app/assets/stylesheets/swat/application.sass +59 -0
  338. data/app/assets/stylesheets/swat/default-theme.css +394 -0
  339. data/app/assets/stylesheets/swat/font-awesome.css +1801 -0
  340. data/app/assets/stylesheets/swat/fonts/FontAwesome.otf +0 -0
  341. data/app/assets/stylesheets/swat/fonts/fontawesome-webfont.eot +0 -0
  342. data/app/assets/stylesheets/swat/fonts/fontawesome-webfont.svg +565 -0
  343. data/app/assets/stylesheets/swat/fonts/fontawesome-webfont.ttf +0 -0
  344. data/app/assets/stylesheets/swat/fonts/fontawesome-webfont.woff +0 -0
  345. data/app/assets/stylesheets/swat/fonts/fontawesome-webfont.woff2 +0 -0
  346. data/app/assets/stylesheets/swat/swat_theme.sass +177 -0
  347. data/app/controllers/swat/api/revisions_controller.rb +27 -0
  348. data/app/controllers/swat/api/test_cases_controller.rb +20 -0
  349. data/app/controllers/swat/application_controller.rb +4 -0
  350. data/app/controllers/swat/info/states_controller.rb +12 -0
  351. data/app/controllers/swat/pages/base_pages_controller.rb +7 -0
  352. data/app/controllers/swat/pages/revisions_controller.rb +8 -0
  353. data/app/controllers/swat/revisions_controller.rb +4 -0
  354. data/app/helpers/swat/application_helper.rb +4 -0
  355. data/app/models/concerns/root_revision_ext.rb +14 -0
  356. data/app/models/full_revision.rb +88 -0
  357. data/app/models/revision.rb +84 -0
  358. data/app/models/revision_status_calculator.rb +98 -0
  359. data/app/models/test_case.rb +25 -0
  360. data/app/views/layouts/swat/application.slim +36 -0
  361. data/app/views/layouts/swat/page.slim +2 -0
  362. data/app/views/swat/application/index.slim +0 -0
  363. data/app/views/swat/pages/revisions/index.slim +25 -0
  364. data/app/views/swat/pages/revisions/show.slim +43 -0
  365. data/app/views/swat/shared/_footer.slim +5 -0
  366. data/app/views/swat/shared/_header.slim +9 -0
  367. data/bin/rails +12 -0
  368. data/config/routes.rb +38 -0
  369. data/fixtures/firebase_collection.rb +97 -0
  370. data/lib/sw2at-ui.rb +19 -0
  371. data/lib/swat/engine.rb +5 -0
  372. data/lib/swat/ui/config.rb +28 -0
  373. data/lib/swat/ui/rspec_commands.rb +191 -0
  374. data/lib/swat/ui/rspec_setup.rb +42 -0
  375. data/lib/swat/ui/stats_collector.rb +90 -0
  376. data/lib/swat/ui/version.rb +5 -0
  377. data/lib/tasks/swat_tasks.rake +36 -0
  378. data/spec/lib/commands_spec.rb +88 -0
  379. data/spec/models/calculator_spec.rb +130 -0
  380. data/spec/models/full_revision_spec.rb +263 -0
  381. data/spec/models/revision_spec.rb +59 -0
  382. data/spec/models/testcase_spec.rb +94 -0
  383. data/spec/spec_helper.rb +45 -0
  384. data/sw2at-ui.gemspec +465 -0
  385. data/test/helper.rb +34 -0
  386. data/test/test_sw2at-ui.rb +7 -0
  387. metadata +628 -0
@@ -0,0 +1,2780 @@
1
+ /*!
2
+ * Angular Material Design
3
+ * https://github.com/angular/material
4
+ * @license MIT
5
+ * v0.7.0-rc3
6
+ */
7
+ (function() {
8
+ 'use strict';
9
+
10
+ /**
11
+ * Initialization function that validates environment
12
+ * requirements.
13
+ */
14
+ angular.module('material.core', ['material.core.theming'])
15
+ .run(MdCoreInitialize)
16
+ .config(MdCoreConfigure);
17
+
18
+ function MdCoreInitialize() {
19
+ if (typeof Hammer === 'undefined') {
20
+ throw new Error(
21
+ 'ngMaterial requires HammerJS to be preloaded.'
22
+ );
23
+ }
24
+ // By default, Hammer disables user selection on desktop if swipe is enabled.
25
+ // We don't want this, so we make sure Hammer doesn't set a user-select: none.
26
+ Hammer.defaults.cssProps.userSelect = '';
27
+ }
28
+
29
+ function MdCoreConfigure($provide, $mdThemingProvider) {
30
+ $provide.decorator('$$rAF', ['$delegate', '$rootScope', rAFDecorator]);
31
+
32
+ $mdThemingProvider.theme('default')
33
+ .primaryColor('blue')
34
+ .accentColor('green')
35
+ .warnColor('red')
36
+ .backgroundColor('grey');
37
+
38
+ function rAFDecorator($$rAF, $rootScope) {
39
+ /**
40
+ * Use this to debounce events that come in often.
41
+ * The debounced function will always use the *last* invocation before the
42
+ * coming frame.
43
+ *
44
+ * For example, window resize events that fire many times a second:
45
+ * If we set to use an raf-debounced callback on window resize, then
46
+ * our callback will only be fired once per frame, with the last resize
47
+ * event that happened before that frame.
48
+ *
49
+ * @param {function} callback function to debounce
50
+ */
51
+ $$rAF.debounce = function(cb) {
52
+ var queueArgs, alreadyQueued, queueCb, context;
53
+ return function debounced() {
54
+ queueArgs = arguments;
55
+ context = this;
56
+ queueCb = cb;
57
+ if (!alreadyQueued) {
58
+ alreadyQueued = true;
59
+ $$rAF(function() {
60
+ queueCb.apply(context, queueArgs);
61
+ alreadyQueued = false;
62
+ });
63
+ }
64
+ };
65
+ };
66
+ return $$rAF;
67
+
68
+ }
69
+
70
+ }
71
+ MdCoreConfigure.$inject = ["$provide", "$mdThemingProvider"];
72
+
73
+ })();
74
+
75
+ (function() {
76
+ 'use strict';
77
+
78
+ angular.module('material.core')
79
+ .factory('$mdConstant', MdConstantFactory);
80
+
81
+ function MdConstantFactory($$rAF, $sniffer) {
82
+
83
+ var webkit = /webkit/i.test($sniffer.vendorPrefix);
84
+ function vendorProperty(name) {
85
+ return webkit ? ('webkit' + name.charAt(0).toUpperCase() + name.substring(1)) : name;
86
+ }
87
+
88
+ return {
89
+ KEY_CODE: {
90
+ ENTER: 13,
91
+ ESCAPE: 27,
92
+ SPACE: 32,
93
+ LEFT_ARROW : 37,
94
+ UP_ARROW : 38,
95
+ RIGHT_ARROW : 39,
96
+ DOWN_ARROW : 40
97
+ },
98
+ CSS: {
99
+ /* Constants */
100
+ TRANSITIONEND: 'transitionend' + (webkit ? ' webkitTransitionEnd' : ''),
101
+ ANIMATIONEND: 'animationend' + (webkit ? ' webkitAnimationEnd' : ''),
102
+
103
+ TRANSFORM: vendorProperty('transform'),
104
+ TRANSITION: vendorProperty('transition'),
105
+ TRANSITION_DURATION: vendorProperty('transitionDuration'),
106
+ ANIMATION_PLAY_STATE: vendorProperty('animationPlayState'),
107
+ ANIMATION_DURATION: vendorProperty('animationDuration'),
108
+ ANIMATION_NAME: vendorProperty('animationName'),
109
+ ANIMATION_TIMING: vendorProperty('animationTimingFunction'),
110
+ ANIMATION_DIRECTION: vendorProperty('animationDirection')
111
+ },
112
+ MEDIA: {
113
+ 'sm': '(max-width: 600px)',
114
+ 'gt-sm': '(min-width: 600px)',
115
+ 'md': '(min-width: 600px) and (max-width: 960px)',
116
+ 'gt-md': '(min-width: 960px)',
117
+ 'lg': '(min-width: 960px) and (max-width: 1200px)',
118
+ 'gt-lg': '(min-width: 1200px)'
119
+ }
120
+ };
121
+ }
122
+ MdConstantFactory.$inject = ["$$rAF", "$sniffer"];
123
+
124
+ })();
125
+
126
+ (function(){
127
+
128
+ angular
129
+ .module('material.core')
130
+ .config( ["$provide", function($provide){
131
+ $provide.decorator('$mdUtil', ['$delegate', function ($delegate){
132
+ /**
133
+ * Inject the iterator facade to easily support iteration and accessors
134
+ * @see iterator below
135
+ */
136
+ $delegate.iterator = Iterator;
137
+
138
+ return $delegate;
139
+ }
140
+ ]);
141
+ }]);
142
+
143
+ /**
144
+ * iterator is a list facade to easily support iteration and accessors
145
+ *
146
+ * @param items Array list which this iterator will enumerate
147
+ * @param reloop Boolean enables iterator to consider the list as an endless reloop
148
+ */
149
+ function Iterator(items, reloop) {
150
+ var trueFn = function() { return true; };
151
+
152
+ reloop = !!reloop;
153
+ var _items = items || [ ];
154
+
155
+ // Published API
156
+ return {
157
+ items: getItems,
158
+ count: count,
159
+
160
+ inRange: inRange,
161
+ contains: contains,
162
+ indexOf: indexOf,
163
+ itemAt: itemAt,
164
+
165
+ findBy: findBy,
166
+
167
+ add: add,
168
+ remove: remove,
169
+
170
+ first: first,
171
+ last: last,
172
+ next: angular.bind(null, findSubsequentItem, false),
173
+ previous: angular.bind(null, findSubsequentItem, true),
174
+
175
+ hasPrevious: hasPrevious,
176
+ hasNext: hasNext
177
+
178
+ };
179
+
180
+ /**
181
+ * Publish copy of the enumerable set
182
+ * @returns {Array|*}
183
+ */
184
+ function getItems() {
185
+ return [].concat(_items);
186
+ }
187
+
188
+ /**
189
+ * Determine length of the list
190
+ * @returns {Array.length|*|number}
191
+ */
192
+ function count() {
193
+ return _items.length;
194
+ }
195
+
196
+ /**
197
+ * Is the index specified valid
198
+ * @param index
199
+ * @returns {Array.length|*|number|boolean}
200
+ */
201
+ function inRange(index) {
202
+ return _items.length && ( index > -1 ) && (index < _items.length );
203
+ }
204
+
205
+ /**
206
+ * Can the iterator proceed to the next item in the list; relative to
207
+ * the specified item.
208
+ *
209
+ * @param item
210
+ * @returns {Array.length|*|number|boolean}
211
+ */
212
+ function hasNext(item) {
213
+ return item ? inRange(indexOf(item) + 1) : false;
214
+ }
215
+
216
+ /**
217
+ * Can the iterator proceed to the previous item in the list; relative to
218
+ * the specified item.
219
+ *
220
+ * @param item
221
+ * @returns {Array.length|*|number|boolean}
222
+ */
223
+ function hasPrevious(item) {
224
+ return item ? inRange(indexOf(item) - 1) : false;
225
+ }
226
+
227
+ /**
228
+ * Get item at specified index/position
229
+ * @param index
230
+ * @returns {*}
231
+ */
232
+ function itemAt(index) {
233
+ return inRange(index) ? _items[index] : null;
234
+ }
235
+
236
+ /**
237
+ * Find all elements matching the key/value pair
238
+ * otherwise return null
239
+ *
240
+ * @param val
241
+ * @param key
242
+ *
243
+ * @return array
244
+ */
245
+ function findBy(key, val) {
246
+ return _items.filter(function(item) {
247
+ return item[key] === val;
248
+ });
249
+ }
250
+
251
+ /**
252
+ * Add item to list
253
+ * @param item
254
+ * @param index
255
+ * @returns {*}
256
+ */
257
+ function add(item, index) {
258
+ if ( !item ) return -1;
259
+
260
+ if (!angular.isNumber(index)) {
261
+ index = _items.length;
262
+ }
263
+
264
+ _items.splice(index, 0, item);
265
+
266
+ return indexOf(item);
267
+ }
268
+
269
+ /**
270
+ * Remove item from list...
271
+ * @param item
272
+ */
273
+ function remove(item) {
274
+ if ( contains(item) ){
275
+ _items.splice(indexOf(item), 1);
276
+ }
277
+ }
278
+
279
+ /**
280
+ * Get the zero-based index of the target item
281
+ * @param item
282
+ * @returns {*}
283
+ */
284
+ function indexOf(item) {
285
+ return _items.indexOf(item);
286
+ }
287
+
288
+ /**
289
+ * Boolean existence check
290
+ * @param item
291
+ * @returns {boolean}
292
+ */
293
+ function contains(item) {
294
+ return item && (indexOf(item) > -1);
295
+ }
296
+
297
+ /**
298
+ * Return first item in the list
299
+ * @returns {*}
300
+ */
301
+ function first() {
302
+ return _items.length ? _items[0] : null;
303
+ }
304
+
305
+ /**
306
+ * Return last item in the list...
307
+ * @returns {*}
308
+ */
309
+ function last() {
310
+ return _items.length ? _items[_items.length - 1] : null;
311
+ }
312
+
313
+ /**
314
+ * Find the next item. If reloop is true and at the end of the list, it will
315
+ * go back to the first item. If given ,the `validate` callback will be used
316
+ * determine whether the next item is valid. If not valid, it will try to find the
317
+ * next item again.
318
+ * @param item
319
+ * @param {optional} validate function
320
+ * @param {optional} recursion limit
321
+ * @returns {*}
322
+ */
323
+ function findSubsequentItem(backwards, item, validate, limit) {
324
+ validate = validate || trueFn;
325
+
326
+ var curIndex = indexOf(item);
327
+ if (!inRange(curIndex)) {
328
+ return null;
329
+ }
330
+
331
+ var nextIndex = curIndex + (backwards ? -1 : 1);
332
+ var foundItem = null;
333
+ if (inRange(nextIndex)) {
334
+ foundItem = _items[nextIndex];
335
+ } else if (reloop) {
336
+ foundItem = backwards ? last() : first();
337
+ nextIndex = indexOf(foundItem);
338
+ }
339
+
340
+ if ((foundItem === null) || (nextIndex === limit)) {
341
+ return null;
342
+ }
343
+
344
+ if (angular.isUndefined(limit)) {
345
+ limit = nextIndex;
346
+ }
347
+
348
+ return validate(foundItem) ? foundItem : findSubsequentItem(backwards, foundItem, validate, limit);
349
+ }
350
+ }
351
+
352
+ })();
353
+
354
+ angular.module('material.core')
355
+ .factory('$mdMedia', mdMediaFactory);
356
+
357
+ /**
358
+ * Exposes a function on the '$mdMedia' service which will return true or false,
359
+ * whether the given media query matches. Re-evaluates on resize. Allows presets
360
+ * for 'sm', 'md', 'lg'.
361
+ *
362
+ * @example $mdMedia('sm') == true if device-width <= sm
363
+ * @example $mdMedia('(min-width: 1200px)') == true if device-width >= 1200px
364
+ * @example $mdMedia('max-width: 300px') == true if device-width <= 300px (sanitizes input, adding parens)
365
+ */
366
+ function mdMediaFactory($mdConstant, $mdUtil, $rootScope, $window) {
367
+ var queriesCache = $mdUtil.cacheFactory('$mdMedia:queries', {capacity: 15});
368
+ var resultsCache = $mdUtil.cacheFactory('$mdMedia:results', {capacity: 15});
369
+
370
+ angular.element($window).on('resize', updateAll);
371
+
372
+ return $mdMedia;
373
+
374
+ function $mdMedia(query) {
375
+ var validated = queriesCache.get(query);
376
+ if (angular.isUndefined(validated)) {
377
+ validated = queriesCache.put(query, validate(query));
378
+ }
379
+
380
+ var result = resultsCache.get(validated);
381
+ if (angular.isUndefined(result)) {
382
+ result = add(validated);
383
+ }
384
+
385
+ return result;
386
+ }
387
+
388
+ function validate(query) {
389
+ return $mdConstant.MEDIA[query] ||
390
+ ((query.charAt(0) !== '(') ? ('(' + query + ')') : query);
391
+ }
392
+
393
+ function add(query) {
394
+ return resultsCache.put(query, !!$window.matchMedia(query).matches);
395
+ }
396
+
397
+ function updateAll() {
398
+ var keys = resultsCache.keys();
399
+ var len = keys.length;
400
+
401
+ if (len) {
402
+ for (var i = 0; i < len; i++) {
403
+ add(keys[i]);
404
+ }
405
+
406
+ // Trigger a $digest() if not already in progress
407
+ $rootScope.$evalAsync();
408
+ }
409
+ }
410
+ }
411
+ mdMediaFactory.$inject = ["$mdConstant", "$mdUtil", "$rootScope", "$window"];
412
+
413
+ (function() {
414
+ 'use strict';
415
+
416
+ /*
417
+ * This var has to be outside the angular factory, otherwise when
418
+ * there are multiple material apps on the same page, each app
419
+ * will create its own instance of this array and the app's IDs
420
+ * will not be unique.
421
+ */
422
+ var nextUniqueId = ['0','0','0'];
423
+
424
+ angular.module('material.core')
425
+ .factory('$mdUtil', ["$cacheFactory", "$document", "$timeout", function($cacheFactory, $document, $timeout) {
426
+ var Util;
427
+ return Util = {
428
+ now: window.performance ? angular.bind(window.performance, window.performance.now) : Date.now,
429
+
430
+ attachDragBehavior: attachDragBehavior,
431
+
432
+ elementRect: function(element, offsetParent) {
433
+ var node = element[0];
434
+ offsetParent = offsetParent || node.offsetParent || document.body;
435
+ offsetParent = offsetParent[0] || offsetParent;
436
+ var nodeRect = node.getBoundingClientRect();
437
+ var parentRect = offsetParent.getBoundingClientRect();
438
+ return {
439
+ left: nodeRect.left - parentRect.left + offsetParent.scrollLeft,
440
+ top: nodeRect.top - parentRect.top + offsetParent.scrollTop,
441
+ width: nodeRect.width,
442
+ height: nodeRect.height
443
+ };
444
+ },
445
+
446
+ fakeNgModel: function() {
447
+ return {
448
+ $setViewValue: function(value) {
449
+ this.$viewValue = value;
450
+ this.$render(value);
451
+ this.$viewChangeListeners.forEach(function(cb) { cb(); });
452
+ },
453
+ $parsers: [],
454
+ $formatters: [],
455
+ $viewChangeListeners: [],
456
+ $render: angular.noop
457
+ };
458
+ },
459
+
460
+ /**
461
+ * @see cacheFactory below
462
+ */
463
+ cacheFactory: cacheFactory,
464
+
465
+ // Returns a function, that, as long as it continues to be invoked, will not
466
+ // be triggered. The function will be called after it stops being called for
467
+ // N milliseconds.
468
+ // @param wait Integer value of msecs to delay (since last debounce reset); default value 10 msecs
469
+ // @param invokeApply should the $timeout trigger $digest() dirty checking
470
+ debounce: function (func, wait, scope, invokeApply) {
471
+ var timer;
472
+
473
+ return function debounced() {
474
+ var context = scope,
475
+ args = Array.prototype.slice.call(arguments);
476
+
477
+ $timeout.cancel(timer);
478
+ timer = $timeout(function() {
479
+
480
+ timer = undefined;
481
+ func.apply(context, args);
482
+
483
+ }, wait || 10, invokeApply );
484
+ };
485
+ },
486
+
487
+ // Returns a function that can only be triggered every `delay` milliseconds.
488
+ // In other words, the function will not be called unless it has been more
489
+ // than `delay` milliseconds since the last call.
490
+ throttle: function throttle(func, delay) {
491
+ var recent;
492
+ return function throttled() {
493
+ var context = this;
494
+ var args = arguments;
495
+ var now = Util.now();
496
+
497
+ if (!recent || (now - recent > delay)) {
498
+ func.apply(context, args);
499
+ recent = now;
500
+ }
501
+ };
502
+ },
503
+
504
+ /**
505
+ * nextUid, from angular.js.
506
+ * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
507
+ * characters such as '012ABC'. The reason why we are not using simply a number counter is that
508
+ * the number string gets longer over time, and it can also overflow, where as the nextId
509
+ * will grow much slower, it is a string, and it will never overflow.
510
+ *
511
+ * @returns an unique alpha-numeric string
512
+ */
513
+ nextUid: function() {
514
+ var index = nextUniqueId.length;
515
+ var digit;
516
+
517
+ while(index) {
518
+ index--;
519
+ digit = nextUniqueId[index].charCodeAt(0);
520
+ if (digit == 57 /*'9'*/) {
521
+ nextUniqueId[index] = 'A';
522
+ return nextUniqueId.join('');
523
+ }
524
+ if (digit == 90 /*'Z'*/) {
525
+ nextUniqueId[index] = '0';
526
+ } else {
527
+ nextUniqueId[index] = String.fromCharCode(digit + 1);
528
+ return nextUniqueId.join('');
529
+ }
530
+ }
531
+ nextUniqueId.unshift('0');
532
+ return nextUniqueId.join('');
533
+ },
534
+
535
+ // Stop watchers and events from firing on a scope without destroying it,
536
+ // by disconnecting it from its parent and its siblings' linked lists.
537
+ disconnectScope: function disconnectScope(scope) {
538
+ if (!scope) return;
539
+
540
+ // we can't destroy the root scope or a scope that has been already destroyed
541
+ if (scope.$root === scope) return;
542
+ if (scope.$$destroyed ) return;
543
+
544
+ var parent = scope.$parent;
545
+ scope.$$disconnected = true;
546
+
547
+ // See Scope.$destroy
548
+ if (parent.$$childHead === scope) parent.$$childHead = scope.$$nextSibling;
549
+ if (parent.$$childTail === scope) parent.$$childTail = scope.$$prevSibling;
550
+ if (scope.$$prevSibling) scope.$$prevSibling.$$nextSibling = scope.$$nextSibling;
551
+ if (scope.$$nextSibling) scope.$$nextSibling.$$prevSibling = scope.$$prevSibling;
552
+
553
+ scope.$$nextSibling = scope.$$prevSibling = null;
554
+
555
+ },
556
+
557
+ // Undo the effects of disconnectScope above.
558
+ reconnectScope: function reconnectScope(scope) {
559
+ if (!scope) return;
560
+
561
+ // we can't disconnect the root node or scope already disconnected
562
+ if (scope.$root === scope) return;
563
+ if (!scope.$$disconnected) return;
564
+
565
+ var child = scope;
566
+
567
+ var parent = child.$parent;
568
+ child.$$disconnected = false;
569
+ // See Scope.$new for this logic...
570
+ child.$$prevSibling = parent.$$childTail;
571
+ if (parent.$$childHead) {
572
+ parent.$$childTail.$$nextSibling = child;
573
+ parent.$$childTail = child;
574
+ } else {
575
+ parent.$$childHead = parent.$$childTail = child;
576
+ }
577
+ },
578
+ /*
579
+ * getClosest replicates jQuery.closest() to walk up the DOM tree until it finds a matching nodeName
580
+ *
581
+ * @param el Element to start walking the DOM from
582
+ * @param tagName Tag name to find closest to el, such as 'form'
583
+ */
584
+ getClosest: function getClosest(el, tagName) {
585
+ tagName = tagName.toUpperCase();
586
+ do {
587
+ if (el.nodeName === tagName) {
588
+ return el;
589
+ }
590
+ } while (el = el.parentNode);
591
+ return null;
592
+ }
593
+ };
594
+
595
+
596
+ function attachDragBehavior(scope, element, options) {
597
+ // The state of the current drag & previous drag
598
+ var drag;
599
+ var previousDrag;
600
+ // Whether the pointer is currently down on this element.
601
+ var pointerIsDown;
602
+ var START_EVENTS = 'mousedown touchstart pointerdown';
603
+ var MOVE_EVENTS = 'mousemove touchmove pointermove';
604
+ var END_EVENTS = 'mouseup mouseleave touchend touchcancel pointerup pointercancel';
605
+
606
+ // Listen to move and end events on document. End events especially could have bubbled up
607
+ // from the child.
608
+ element.on(START_EVENTS, startDrag);
609
+ $document.on(MOVE_EVENTS, doDrag)
610
+ .on(END_EVENTS, endDrag);
611
+
612
+ scope.$on('$destroy', cleanup);
613
+
614
+ return cleanup;
615
+
616
+ function cleanup() {
617
+ if (cleanup.called) return;
618
+ cleanup.called = true;
619
+
620
+ element.off(START_EVENTS, startDrag);
621
+ $document.off(MOVE_EVENTS, doDrag)
622
+ .off(END_EVENTS, endDrag);
623
+ drag = pointerIsDown = false;
624
+ }
625
+
626
+ function startDrag(ev) {
627
+ var eventType = ev.type.charAt(0);
628
+ var now = Util.now();
629
+ // iOS & old android bug: after a touch event, iOS sends a click event 350 ms later.
630
+ // Don't allow a drag of a different pointerType than the previous drag if it has been
631
+ // less than 400ms.
632
+ if (previousDrag && previousDrag.pointerType !== eventType &&
633
+ (now - previousDrag.endTime < 400)) {
634
+ return;
635
+ }
636
+ if (pointerIsDown) return;
637
+ pointerIsDown = true;
638
+
639
+ drag = {
640
+ // Restrict this drag to whatever started it: if a mousedown started the drag,
641
+ // don't let anything but mouse events continue it.
642
+ pointerType: eventType,
643
+ startX: getPosition(ev),
644
+ startTime: now
645
+ };
646
+
647
+ element.one('$md.dragstart', function(ev) {
648
+ // Allow user to cancel by preventing default
649
+ if (ev.defaultPrevented) drag = null;
650
+ });
651
+ element.triggerHandler('$md.dragstart', drag);
652
+ }
653
+ function doDrag(ev) {
654
+ if (!drag || !isProperEventType(ev, drag)) return;
655
+
656
+ if (drag.pointerType === 't' || drag.pointerType === 'p') {
657
+ // No scrolling for touch/pointer events
658
+ ev.preventDefault();
659
+ }
660
+ updateDragState(ev);
661
+ element.triggerHandler('$md.drag', drag);
662
+ }
663
+ function endDrag(ev) {
664
+ pointerIsDown = false;
665
+ if (!drag || !isProperEventType(ev, drag)) return;
666
+
667
+ drag.endTime = Util.now();
668
+ updateDragState(ev);
669
+
670
+ element.triggerHandler('$md.dragend', drag);
671
+
672
+ previousDrag = drag;
673
+ drag = null;
674
+ }
675
+
676
+ function updateDragState(ev) {
677
+ var x = getPosition(ev);
678
+ drag.distance = drag.startX - x;
679
+ drag.direction = drag.distance > 0 ? 'left' : (drag.distance < 0 ? 'right' : '');
680
+ drag.duration = drag.startTime - Util.now();
681
+ drag.velocity = Math.abs(drag.duration) / drag.time;
682
+ }
683
+ function getPosition(ev) {
684
+ ev = ev.originalEvent || ev; //support jQuery events
685
+ var point = (ev.touches && ev.touches[0]) ||
686
+ (ev.changedTouches && ev.changedTouches[0]) ||
687
+ ev;
688
+ return point.pageX;
689
+ }
690
+ function isProperEventType(ev, drag) {
691
+ return drag && ev && (ev.type || '').charAt(0) === drag.pointerType;
692
+ }
693
+ }
694
+
695
+ /*
696
+ * Inject a 'keys()' method into Angular's $cacheFactory. Then
697
+ * head-hook all other methods
698
+ *
699
+ */
700
+ function cacheFactory(id, options) {
701
+ var cache = $cacheFactory(id, options);
702
+ var keys = {};
703
+
704
+ cache._put = cache.put;
705
+ cache.put = function(k,v) {
706
+ keys[k] = true;
707
+ return cache._put(k, v);
708
+ };
709
+
710
+ cache._remove = cache.remove;
711
+ cache.remove = function(k) {
712
+ delete keys[k];
713
+ return cache._remove(k);
714
+ };
715
+
716
+ cache._removeAll = cache.removeAll;
717
+ cache.removeAll = function() {
718
+ keys = {};
719
+ return cache._removeAll();
720
+ };
721
+
722
+ cache._destroy = cache.destroy;
723
+ cache.destroy = function() {
724
+ keys = {};
725
+ return cache._destroy();
726
+ };
727
+
728
+ cache.keys = function() {
729
+ return Object.keys(keys);
730
+ };
731
+
732
+ return cache;
733
+ }
734
+ }]);
735
+
736
+ /*
737
+ * Since removing jQuery from the demos, some code that uses `element.focus()` is broken.
738
+ *
739
+ * We need to add `element.focus()`, because it's testable unlike `element[0].focus`.
740
+ *
741
+ * TODO(ajoslin): This should be added in a better place later.
742
+ */
743
+
744
+ angular.element.prototype.focus = angular.element.prototype.focus || function() {
745
+ if (this.length) {
746
+ this[0].focus();
747
+ }
748
+ return this;
749
+ };
750
+ angular.element.prototype.blur = angular.element.prototype.blur || function() {
751
+ if (this.length) {
752
+ this[0].blur();
753
+ }
754
+ return this;
755
+ };
756
+
757
+ })();
758
+
759
+ (function() {
760
+ 'use strict';
761
+
762
+ angular.module('material.core')
763
+ .service('$mdAria', AriaService);
764
+
765
+ function AriaService($$rAF, $log, $window) {
766
+
767
+ return {
768
+ expect: expect,
769
+ expectAsync: expectAsync,
770
+ expectWithText: expectWithText
771
+ };
772
+
773
+ /**
774
+ * Check if expected attribute has been specified on the target element or child
775
+ * @param element
776
+ * @param attrName
777
+ * @param {optional} defaultValue What to set the attr to if no value is found
778
+ */
779
+ function expect(element, attrName, defaultValue) {
780
+ var node = element[0];
781
+
782
+ if (!node.hasAttribute(attrName) && !childHasAttribute(node, attrName)) {
783
+
784
+ defaultValue = angular.isString(defaultValue) && defaultValue.trim() || '';
785
+ if (defaultValue.length) {
786
+ element.attr(attrName, defaultValue);
787
+ } else {
788
+ $log.warn('ARIA: Attribute "', attrName, '", required for accessibility, is missing on node:', node);
789
+ }
790
+
791
+ }
792
+ }
793
+
794
+ function expectAsync(element, attrName, defaultValueGetter) {
795
+ // Problem: when retrieving the element's contents synchronously to find the label,
796
+ // the text may not be defined yet in the case of a binding.
797
+ // There is a higher chance that a binding will be defined if we wait one frame.
798
+ $$rAF(function() {
799
+ expect(element, attrName, defaultValueGetter());
800
+ });
801
+ }
802
+
803
+ function expectWithText(element, attrName) {
804
+ expectAsync(element, attrName, function() {
805
+ return element.text().trim();
806
+ });
807
+ }
808
+
809
+ function childHasAttribute(node, attrName) {
810
+ var hasChildren = node.hasChildNodes(),
811
+ hasAttr = false;
812
+
813
+ function isHidden(el) {
814
+ var style = el.currentStyle ? el.currentStyle : $window.getComputedStyle(el);
815
+ return (style.display === 'none');
816
+ }
817
+
818
+ if(hasChildren) {
819
+ var children = node.childNodes;
820
+ for(var i=0; i<children.length; i++){
821
+ var child = children[i];
822
+ if(child.nodeType === 1 && child.hasAttribute(attrName)) {
823
+ if(!isHidden(child)){
824
+ hasAttr = true;
825
+ }
826
+ }
827
+ }
828
+ }
829
+ return hasAttr;
830
+ }
831
+ }
832
+ AriaService.$inject = ["$$rAF", "$log", "$window"];
833
+ })();
834
+
835
+ (function() {
836
+ 'use strict';
837
+
838
+ angular.module('material.core')
839
+ .service('$mdCompiler', mdCompilerService);
840
+
841
+ function mdCompilerService($q, $http, $injector, $compile, $controller, $templateCache) {
842
+ /* jshint validthis: true */
843
+
844
+ /*
845
+ * @ngdoc service
846
+ * @name $mdCompiler
847
+ * @module material.core
848
+ * @description
849
+ * The $mdCompiler service is an abstraction of angular's compiler, that allows the developer
850
+ * to easily compile an element with a templateUrl, controller, and locals.
851
+ *
852
+ * @usage
853
+ * <hljs lang="js">
854
+ * $mdCompiler.compile({
855
+ * templateUrl: 'modal.html',
856
+ * controller: 'ModalCtrl',
857
+ * locals: {
858
+ * modal: myModalInstance;
859
+ * }
860
+ * }).then(function(compileData) {
861
+ * compileData.element; // modal.html's template in an element
862
+ * compileData.link(myScope); //attach controller & scope to element
863
+ * });
864
+ * </hljs>
865
+ */
866
+
867
+ /*
868
+ * @ngdoc method
869
+ * @name $mdCompiler#compile
870
+ * @description A helper to compile an HTML template/templateUrl with a given controller,
871
+ * locals, and scope.
872
+ * @param {object} options An options object, with the following properties:
873
+ *
874
+ * - `controller` - `{(string=|function()=}` Controller fn that should be associated with
875
+ * newly created scope or the name of a registered controller if passed as a string.
876
+ * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be
877
+ * published to scope under the `controllerAs` name.
878
+ * - `template` - `{string=}` An html template as a string.
879
+ * - `templateUrl` - `{string=}` A path to an html template.
880
+ * - `transformTemplate` - `{function(template)=}` A function which transforms the template after
881
+ * it is loaded. It will be given the template string as a parameter, and should
882
+ * return a a new string representing the transformed template.
883
+ * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
884
+ * be injected into the controller. If any of these dependencies are promises, the compiler
885
+ * will wait for them all to be resolved, or if one is rejected before the controller is
886
+ * instantiated `compile()` will fail..
887
+ * * `key` - `{string}`: a name of a dependency to be injected into the controller.
888
+ * * `factory` - `{string|function}`: If `string` then it is an alias for a service.
889
+ * Otherwise if function, then it is injected and the return value is treated as the
890
+ * dependency. If the result is a promise, it is resolved before its value is
891
+ * injected into the controller.
892
+ *
893
+ * @returns {object=} promise A promise, which will be resolved with a `compileData` object.
894
+ * `compileData` has the following properties:
895
+ *
896
+ * - `element` - `{element}`: an uncompiled element matching the provided template.
897
+ * - `link` - `{function(scope)}`: A link function, which, when called, will compile
898
+ * the element and instantiate the provided controller (if given).
899
+ * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is
900
+ * called. If `bindToController` is true, they will be coppied to the ctrl instead
901
+ * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in
902
+ */
903
+ this.compile = function(options) {
904
+ var templateUrl = options.templateUrl;
905
+ var template = options.template || '';
906
+ var controller = options.controller;
907
+ var controllerAs = options.controllerAs;
908
+ var resolve = options.resolve || {};
909
+ var locals = options.locals || {};
910
+ var transformTemplate = options.transformTemplate || angular.identity;
911
+ var bindToController = options.bindToController;
912
+
913
+ // Take resolve values and invoke them.
914
+ // Resolves can either be a string (value: 'MyRegisteredAngularConst'),
915
+ // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})
916
+ angular.forEach(resolve, function(value, key) {
917
+ if (angular.isString(value)) {
918
+ resolve[key] = $injector.get(value);
919
+ } else {
920
+ resolve[key] = $injector.invoke(value);
921
+ }
922
+ });
923
+ //Add the locals, which are just straight values to inject
924
+ //eg locals: { three: 3 }, will inject three into the controller
925
+ angular.extend(resolve, locals);
926
+
927
+ if (templateUrl) {
928
+ resolve.$template = $http.get(templateUrl, {cache: $templateCache})
929
+ .then(function(response) {
930
+ return response.data;
931
+ });
932
+ } else {
933
+ resolve.$template = $q.when(template);
934
+ }
935
+
936
+ // Wait for all the resolves to finish if they are promises
937
+ return $q.all(resolve).then(function(locals) {
938
+
939
+ var template = transformTemplate(locals.$template);
940
+ var element = angular.element('<div>').html(template.trim()).contents();
941
+ var linkFn = $compile(element);
942
+
943
+ //Return a linking function that can be used later when the element is ready
944
+ return {
945
+ locals: locals,
946
+ element: element,
947
+ link: function link(scope) {
948
+ locals.$scope = scope;
949
+
950
+ //Instantiate controller if it exists, because we have scope
951
+ if (controller) {
952
+ var ctrl = $controller(controller, locals);
953
+ if (bindToController) {
954
+ angular.extend(ctrl, locals);
955
+ }
956
+ //See angular-route source for this logic
957
+ element.data('$ngControllerController', ctrl);
958
+ element.children().data('$ngControllerController', ctrl);
959
+
960
+ if (controllerAs) {
961
+ scope[controllerAs] = ctrl;
962
+ }
963
+ }
964
+
965
+ return linkFn(scope);
966
+ }
967
+ };
968
+ });
969
+
970
+ };
971
+ }
972
+ mdCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controller", "$templateCache"];
973
+ })();
974
+
975
+ (function() {
976
+ 'use strict';
977
+
978
+ angular.module('material.core')
979
+ .provider('$$interimElement', InterimElementProvider);
980
+
981
+ /*
982
+ * @ngdoc service
983
+ * @name $$interimElement
984
+ * @module material.core
985
+ *
986
+ * @description
987
+ *
988
+ * Factory that contructs `$$interimElement.$service` services.
989
+ * Used internally in material design for elements that appear on screen temporarily.
990
+ * The service provides a promise-like API for interacting with the temporary
991
+ * elements.
992
+ *
993
+ * ```js
994
+ * app.service('$mdToast', function($$interimElement) {
995
+ * var $mdToast = $$interimElement(toastDefaultOptions);
996
+ * return $mdToast;
997
+ * });
998
+ * ```
999
+ * @param {object=} defaultOptions Options used by default for the `show` method on the service.
1000
+ *
1001
+ * @returns {$$interimElement.$service}
1002
+ *
1003
+ */
1004
+
1005
+ function InterimElementProvider() {
1006
+ createInterimElementProvider.$get = InterimElementFactory;
1007
+ InterimElementFactory.$inject = ["$document", "$q", "$rootScope", "$timeout", "$rootElement", "$animate", "$interpolate", "$mdCompiler", "$mdTheming"];
1008
+ return createInterimElementProvider;
1009
+
1010
+ /**
1011
+ * Returns a new provider which allows configuration of a new interimElement
1012
+ * service. Allows configuration of default options & methods for options,
1013
+ * as well as configuration of 'preset' methods (eg dialog.basic(): basic is a preset method)
1014
+ */
1015
+ function createInterimElementProvider(interimFactoryName) {
1016
+ var EXPOSED_METHODS = ['onHide', 'onShow', 'onRemove'];
1017
+ var providerConfig = {
1018
+ presets: {}
1019
+ };
1020
+ var provider = {
1021
+ setDefaults: setDefaults,
1022
+ addPreset: addPreset,
1023
+ $get: factory
1024
+ };
1025
+
1026
+ /**
1027
+ * all interim elements will come with the 'build' preset
1028
+ */
1029
+ provider.addPreset('build', {
1030
+ methods: ['controller', 'controllerAs', 'resolve',
1031
+ 'template', 'templateUrl', 'themable', 'transformTemplate', 'parent']
1032
+ });
1033
+
1034
+ factory.$inject = ["$$interimElement", "$animate", "$injector"];
1035
+ return provider;
1036
+
1037
+ /**
1038
+ * Save the configured defaults to be used when the factory is instantiated
1039
+ */
1040
+ function setDefaults(definition) {
1041
+ providerConfig.optionsFactory = definition.options;
1042
+ providerConfig.methods = (definition.methods || []).concat(EXPOSED_METHODS);
1043
+ return provider;
1044
+ }
1045
+
1046
+ /**
1047
+ * Save the configured preset to be used when the factory is instantiated
1048
+ */
1049
+ function addPreset(name, definition) {
1050
+ definition = definition || {};
1051
+ definition.methods = definition.methods || [];
1052
+ definition.options = definition.options || function() { return {}; };
1053
+
1054
+ if (/^cancel|hide|show$/.test(name)) {
1055
+ throw new Error("Preset '" + name + "' in " + interimFactoryName + " is reserved!");
1056
+ }
1057
+ if (definition.methods.indexOf('_options') > -1) {
1058
+ throw new Error("Method '_options' in " + interimFactoryName + " is reserved!");
1059
+ }
1060
+ providerConfig.presets[name] = {
1061
+ methods: definition.methods.concat(EXPOSED_METHODS),
1062
+ optionsFactory: definition.options,
1063
+ argOption: definition.argOption
1064
+ };
1065
+ return provider;
1066
+ }
1067
+
1068
+ /**
1069
+ * Create a factory that has the given methods & defaults implementing interimElement
1070
+ */
1071
+ /* @ngInject */
1072
+ function factory($$interimElement, $animate, $injector) {
1073
+ var defaultMethods;
1074
+ var defaultOptions;
1075
+ var interimElementService = $$interimElement();
1076
+
1077
+ /*
1078
+ * publicService is what the developer will be using.
1079
+ * It has methods hide(), cancel(), show(), build(), and any other
1080
+ * presets which were set during the config phase.
1081
+ */
1082
+ var publicService = {
1083
+ hide: interimElementService.hide,
1084
+ cancel: interimElementService.cancel,
1085
+ show: showInterimElement
1086
+ };
1087
+
1088
+ defaultMethods = providerConfig.methods || [];
1089
+ // This must be invoked after the publicService is initialized
1090
+ defaultOptions = invokeFactory(providerConfig.optionsFactory, {});
1091
+
1092
+ angular.forEach(providerConfig.presets, function(definition, name) {
1093
+ var presetDefaults = invokeFactory(definition.optionsFactory, {});
1094
+ var presetMethods = (definition.methods || []).concat(defaultMethods);
1095
+
1096
+ // Every interimElement built with a preset has a field called `$type`,
1097
+ // which matches the name of the preset.
1098
+ // Eg in preset 'confirm', options.$type === 'confirm'
1099
+ angular.extend(presetDefaults, { $type: name });
1100
+
1101
+ // This creates a preset class which has setter methods for every
1102
+ // method given in the `.addPreset()` function, as well as every
1103
+ // method given in the `.setDefaults()` function.
1104
+ //
1105
+ // @example
1106
+ // .setDefaults({
1107
+ // methods: ['hasBackdrop', 'clickOutsideToClose', 'escapeToClose', 'targetEvent'],
1108
+ // options: dialogDefaultOptions
1109
+ // })
1110
+ // .addPreset('alert', {
1111
+ // methods: ['title', 'ok'],
1112
+ // options: alertDialogOptions
1113
+ // })
1114
+ //
1115
+ // Set values will be passed to the options when interimElemnt.show() is called.
1116
+ function Preset(opts) {
1117
+ this._options = angular.extend({}, presetDefaults, opts);
1118
+ }
1119
+ angular.forEach(presetMethods, function(name) {
1120
+ Preset.prototype[name] = function(value) {
1121
+ this._options[name] = value;
1122
+ return this;
1123
+ };
1124
+ });
1125
+
1126
+ // Create shortcut method for one-linear methods
1127
+ if (definition.argOption) {
1128
+ var methodName = 'show' + name.charAt(0).toUpperCase() + name.slice(1);
1129
+ publicService[methodName] = function(arg) {
1130
+ var config = publicService[name](arg);
1131
+ return publicService.show(config);
1132
+ };
1133
+ }
1134
+
1135
+ // eg $mdDialog.alert() will return a new alert preset
1136
+ publicService[name] = function(arg) {
1137
+ // If argOption is supplied, eg `argOption: 'content'`, then we assume
1138
+ // if the argument is not an options object then it is the `argOption` option.
1139
+ //
1140
+ // @example `$mdToast.simple('hello')` // sets options.content to hello
1141
+ // // because argOption === 'content'
1142
+ if (arguments.length && definition.argOption && !angular.isObject(arg) &&
1143
+ !angular.isArray(arg)) {
1144
+ return (new Preset())[definition.argOption](arg);
1145
+ } else {
1146
+ return new Preset(arg);
1147
+ }
1148
+
1149
+ };
1150
+ });
1151
+
1152
+ return publicService;
1153
+
1154
+ function showInterimElement(opts) {
1155
+ // opts is either a preset which stores its options on an _options field,
1156
+ // or just an object made up of options
1157
+ if (opts && opts._options) opts = opts._options;
1158
+ return interimElementService.show(
1159
+ angular.extend({}, defaultOptions, opts)
1160
+ );
1161
+ }
1162
+
1163
+ /**
1164
+ * Helper to call $injector.invoke with a local of the factory name for
1165
+ * this provider.
1166
+ * If an $mdDialog is providing options for a dialog and tries to inject
1167
+ * $mdDialog, a circular dependency error will happen.
1168
+ * We get around that by manually injecting $mdDialog as a local.
1169
+ */
1170
+ function invokeFactory(factory, defaultVal) {
1171
+ var locals = {};
1172
+ locals[interimFactoryName] = publicService;
1173
+ return $injector.invoke(factory || function() { return defaultVal; }, {}, locals);
1174
+ }
1175
+
1176
+ }
1177
+
1178
+ }
1179
+
1180
+ /* @ngInject */
1181
+ function InterimElementFactory($document, $q, $rootScope, $timeout, $rootElement, $animate,
1182
+ $interpolate, $mdCompiler, $mdTheming ) {
1183
+ var startSymbol = $interpolate.startSymbol(),
1184
+ endSymbol = $interpolate.endSymbol(),
1185
+ usesStandardSymbols = ((startSymbol === '{{') && (endSymbol === '}}')),
1186
+ processTemplate = usesStandardSymbols ? angular.identity : replaceInterpolationSymbols;
1187
+
1188
+ return function createInterimElementService() {
1189
+ /*
1190
+ * @ngdoc service
1191
+ * @name $$interimElement.$service
1192
+ *
1193
+ * @description
1194
+ * A service used to control inserting and removing an element into the DOM.
1195
+ *
1196
+ */
1197
+ var stack = [];
1198
+ var service;
1199
+ return service = {
1200
+ show: show,
1201
+ hide: hide,
1202
+ cancel: cancel
1203
+ };
1204
+
1205
+ /*
1206
+ * @ngdoc method
1207
+ * @name $$interimElement.$service#show
1208
+ * @kind function
1209
+ *
1210
+ * @description
1211
+ * Adds the `$interimElement` to the DOM and returns a promise that will be resolved or rejected
1212
+ * with hide or cancel, respectively.
1213
+ *
1214
+ * @param {*} options is hashMap of settings
1215
+ * @returns a Promise
1216
+ *
1217
+ */
1218
+ function show(options) {
1219
+ if (stack.length) {
1220
+ service.cancel();
1221
+ }
1222
+
1223
+ var interimElement = new InterimElement(options);
1224
+
1225
+ stack.push(interimElement);
1226
+ return interimElement.show().then(function() {
1227
+ return interimElement.deferred.promise;
1228
+ });
1229
+ }
1230
+
1231
+ /*
1232
+ * @ngdoc method
1233
+ * @name $$interimElement.$service#hide
1234
+ * @kind function
1235
+ *
1236
+ * @description
1237
+ * Removes the `$interimElement` from the DOM and resolves the promise returned from `show`
1238
+ *
1239
+ * @param {*} resolveParam Data to resolve the promise with
1240
+ * @returns a Promise that will be resolved after the element has been removed.
1241
+ *
1242
+ */
1243
+ function hide(response) {
1244
+ var interimElement = stack.shift();
1245
+ interimElement && interimElement.remove().then(function() {
1246
+ interimElement.deferred.resolve(response);
1247
+ });
1248
+
1249
+ return interimElement ? interimElement.deferred.promise : $q.when(response);
1250
+ }
1251
+
1252
+ /*
1253
+ * @ngdoc method
1254
+ * @name $$interimElement.$service#cancel
1255
+ * @kind function
1256
+ *
1257
+ * @description
1258
+ * Removes the `$interimElement` from the DOM and rejects the promise returned from `show`
1259
+ *
1260
+ * @param {*} reason Data to reject the promise with
1261
+ * @returns Promise that will be rejected after the element has been removed.
1262
+ *
1263
+ */
1264
+ function cancel(reason) {
1265
+ var interimElement = stack.shift();
1266
+ interimElement && interimElement.remove().then(function() {
1267
+ interimElement.deferred.reject(reason);
1268
+ });
1269
+
1270
+ return interimElement ? interimElement.deferred.promise : $q.reject(reason);
1271
+ }
1272
+
1273
+
1274
+ /*
1275
+ * Internal Interim Element Object
1276
+ * Used internally to manage the DOM element and related data
1277
+ */
1278
+ function InterimElement(options) {
1279
+ var self;
1280
+ var hideTimeout, element;
1281
+
1282
+ options = options || {};
1283
+ options = angular.extend({
1284
+ scope: options.scope || $rootScope.$new(options.isolateScope),
1285
+ onShow: function(scope, element, options) {
1286
+ return $animate.enter(element, options.parent);
1287
+ },
1288
+ onRemove: function(scope, element, options) {
1289
+ // Element could be undefined if a new element is shown before
1290
+ // the old one finishes compiling.
1291
+ return element && $animate.leave(element) || $q.when();
1292
+ }
1293
+ }, options);
1294
+
1295
+ if (options.template) {
1296
+ options.template = processTemplate(options.template);
1297
+ }
1298
+
1299
+ return self = {
1300
+ options: options,
1301
+ deferred: $q.defer(),
1302
+ show: function() {
1303
+ return $mdCompiler.compile(options).then(function(compileData) {
1304
+ angular.extend(compileData.locals, self.options);
1305
+
1306
+ // Search for parent at insertion time, if not specified
1307
+ if (angular.isString(options.parent)) {
1308
+ options.parent = angular.element($document[0].querySelector(options.parent));
1309
+ } else if (!options.parent) {
1310
+ options.parent = $rootElement.find('body');
1311
+ if (!options.parent.length) options.parent = $rootElement;
1312
+ }
1313
+
1314
+ element = compileData.link(options.scope);
1315
+ if (options.themable) $mdTheming(element);
1316
+ var ret = options.onShow(options.scope, element, options);
1317
+ return $q.when(ret)
1318
+ .then(function(){
1319
+ // Issue onComplete callback when the `show()` finishes
1320
+ (options.onComplete || angular.noop)(options.scope, element, options);
1321
+ startHideTimeout();
1322
+ });
1323
+
1324
+ function startHideTimeout() {
1325
+ if (options.hideDelay) {
1326
+ hideTimeout = $timeout(service.cancel, options.hideDelay) ;
1327
+ }
1328
+ }
1329
+ });
1330
+ },
1331
+ cancelTimeout: function() {
1332
+ if (hideTimeout) {
1333
+ $timeout.cancel(hideTimeout);
1334
+ hideTimeout = undefined;
1335
+ }
1336
+ },
1337
+ remove: function() {
1338
+ self.cancelTimeout();
1339
+ var ret = options.onRemove(options.scope, element, options);
1340
+ return $q.when(ret).then(function() {
1341
+ options.scope.$destroy();
1342
+ });
1343
+ }
1344
+ };
1345
+ }
1346
+ };
1347
+
1348
+ /*
1349
+ * Replace `{{` and `}}` in a string (usually a template) with the actual start-/endSymbols used
1350
+ * for interpolation. This allows pre-defined templates (for components such as dialog, toast etc)
1351
+ * to continue to work in apps that use custom interpolation start-/endSymbols.
1352
+ *
1353
+ * @param {string} text The text in which to replace `{{` / `}}`
1354
+ * @returns {string} The modified string using the actual interpolation start-/endSymbols
1355
+ */
1356
+ function replaceInterpolationSymbols(text) {
1357
+ if (!text || !angular.isString(text)) return text;
1358
+ return text.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
1359
+ }
1360
+ }
1361
+
1362
+ }
1363
+
1364
+ })();
1365
+
1366
+ (function() {
1367
+ 'use strict';
1368
+
1369
+ /**
1370
+ * @ngdoc module
1371
+ * @name material.core.componentRegistry
1372
+ *
1373
+ * @description
1374
+ * A component instance registration service.
1375
+ * Note: currently this as a private service in the SideNav component.
1376
+ */
1377
+ angular.module('material.core')
1378
+ .factory('$mdComponentRegistry', ComponentRegistry);
1379
+
1380
+ /*
1381
+ * @private
1382
+ * @ngdoc factory
1383
+ * @name ComponentRegistry
1384
+ * @module material.core.componentRegistry
1385
+ *
1386
+ */
1387
+ function ComponentRegistry($log, $q) {
1388
+
1389
+ var self;
1390
+ var instances = [ ];
1391
+ var pendings = { };
1392
+
1393
+ return self = {
1394
+ /**
1395
+ * Used to print an error when an instance for a handle isn't found.
1396
+ */
1397
+ notFoundError: function(handle) {
1398
+ $log.error('No instance found for handle', handle);
1399
+ },
1400
+ /**
1401
+ * Return all registered instances as an array.
1402
+ */
1403
+ getInstances: function() {
1404
+ return instances;
1405
+ },
1406
+
1407
+ /**
1408
+ * Get a registered instance.
1409
+ * @param handle the String handle to look up for a registered instance.
1410
+ */
1411
+ get: function(handle) {
1412
+ if ( !isValidID(handle) ) return null;
1413
+
1414
+ var i, j, instance;
1415
+ for(i = 0, j = instances.length; i < j; i++) {
1416
+ instance = instances[i];
1417
+ if(instance.$$mdHandle === handle) {
1418
+ return instance;
1419
+ }
1420
+ }
1421
+ return null;
1422
+ },
1423
+
1424
+ /**
1425
+ * Register an instance.
1426
+ * @param instance the instance to register
1427
+ * @param handle the handle to identify the instance under.
1428
+ */
1429
+ register: function(instance, handle) {
1430
+ if ( !handle ) return angular.noop;
1431
+
1432
+ instance.$$mdHandle = handle;
1433
+ instances.push(instance);
1434
+ resolveWhen();
1435
+
1436
+ return deregister;
1437
+
1438
+ /**
1439
+ * Remove registration for an instance
1440
+ */
1441
+ function deregister() {
1442
+ var index = instances.indexOf(instance);
1443
+ if (index !== -1) {
1444
+ instances.splice(index, 1);
1445
+ }
1446
+ }
1447
+
1448
+ /**
1449
+ * Resolve any pending promises for this instance
1450
+ */
1451
+ function resolveWhen() {
1452
+ var dfd = pendings[handle];
1453
+ if ( dfd ) {
1454
+ dfd.resolve( instance );
1455
+ delete pendings[handle];
1456
+ }
1457
+ }
1458
+ },
1459
+
1460
+ /**
1461
+ * Async accessor to registered component instance
1462
+ * If not available then a promise is created to notify
1463
+ * all listeners when the instance is registered.
1464
+ */
1465
+ when : function(handle) {
1466
+ if ( isValidID(handle) ) {
1467
+ var deferred = $q.defer();
1468
+ var instance = self.get(handle);
1469
+
1470
+ if ( instance ) {
1471
+ deferred.resolve( instance );
1472
+ } else {
1473
+ pendings[handle] = deferred;
1474
+ }
1475
+
1476
+ return deferred.promise;
1477
+ }
1478
+ return $q.reject("Invalid `md-component-id` value.");
1479
+ }
1480
+
1481
+ };
1482
+
1483
+ function isValidID(handle){
1484
+ return handle && (handle !== "");
1485
+ }
1486
+
1487
+ }
1488
+ ComponentRegistry.$inject = ["$log", "$q"];
1489
+
1490
+
1491
+ })();
1492
+
1493
+ (function() {
1494
+ 'use strict';
1495
+
1496
+ angular.module('material.core')
1497
+ .factory('$mdInkRipple', InkRippleService)
1498
+ .directive('mdInkRipple', InkRippleDirective)
1499
+ .directive('mdNoInk', attrNoDirective())
1500
+ .directive('mdNoBar', attrNoDirective())
1501
+ .directive('mdNoStretch', attrNoDirective());
1502
+
1503
+ function InkRippleDirective($mdInkRipple) {
1504
+ return {
1505
+ controller: angular.noop,
1506
+ link: function (scope, element, attr) {
1507
+ if (attr.hasOwnProperty('mdInkRippleCheckbox')) {
1508
+ $mdInkRipple.attachCheckboxBehavior(scope, element);
1509
+ } else {
1510
+ $mdInkRipple.attachButtonBehavior(scope, element);
1511
+ }
1512
+ }
1513
+ };
1514
+ }
1515
+ InkRippleDirective.$inject = ["$mdInkRipple"];
1516
+
1517
+ function InkRippleService($window, $timeout) {
1518
+
1519
+ return {
1520
+ attachButtonBehavior: attachButtonBehavior,
1521
+ attachCheckboxBehavior: attachCheckboxBehavior,
1522
+ attachTabBehavior: attachTabBehavior,
1523
+ attach: attach
1524
+ };
1525
+
1526
+ function attachButtonBehavior(scope, element, options) {
1527
+ return attach(scope, element, angular.extend({
1528
+ isFAB: element.hasClass('md-fab'),
1529
+ isMenuItem: element.hasClass('md-menu-item'),
1530
+ center: false,
1531
+ dimBackground: true
1532
+ }, options));
1533
+ }
1534
+
1535
+ function attachCheckboxBehavior(scope, element, options) {
1536
+ return attach(scope, element, angular.extend({
1537
+ center: true,
1538
+ dimBackground: false
1539
+ }, options));
1540
+ }
1541
+
1542
+ function attachTabBehavior(scope, element, options) {
1543
+ return attach(scope, element, angular.extend({
1544
+ center: false,
1545
+ dimBackground: true,
1546
+ outline: true
1547
+ }, options));
1548
+ }
1549
+
1550
+ function attach(scope, element, options) {
1551
+ if (element.controller('mdNoInk')) return angular.noop;
1552
+
1553
+ options = angular.extend({
1554
+ colorElement: element,
1555
+ mousedown: true,
1556
+ hover: true,
1557
+ focus: true,
1558
+ center: false,
1559
+ mousedownPauseTime: 150,
1560
+ dimBackground: false,
1561
+ outline: false,
1562
+ isFAB: false,
1563
+ isMenuItem: false
1564
+ }, options);
1565
+
1566
+ var rippleContainer, rippleSize,
1567
+ controller = element.controller('mdInkRipple') || {},
1568
+ counter = 0,
1569
+ ripples = [],
1570
+ states = [],
1571
+ isActiveExpr = element.attr('md-highlight'),
1572
+ isActive = false,
1573
+ isHeld = false,
1574
+ node = element[0],
1575
+ hammertime = new Hammer(node),
1576
+ color = parseColor(element.attr('md-ink-ripple')) || parseColor($window.getComputedStyle(options.colorElement[0]).color || 'rgb(0, 0, 0)');
1577
+
1578
+ // expose onInput for ripple testing
1579
+ scope._onInput = onInput;
1580
+
1581
+ options.mousedown && hammertime.on('hammer.input', onInput);
1582
+
1583
+ controller.createRipple = createRipple;
1584
+
1585
+ if (isActiveExpr) {
1586
+ scope.$watch(isActiveExpr, function watchActive(newValue) {
1587
+ isActive = newValue;
1588
+ if (isActive && !ripples.length) {
1589
+ $timeout(function () { createRipple(0, 0); }, 0, false);
1590
+ }
1591
+ angular.forEach(ripples, updateElement);
1592
+ });
1593
+ }
1594
+
1595
+ // Publish self-detach method if desired...
1596
+ return function detach() {
1597
+ hammertime.destroy();
1598
+ rippleContainer && rippleContainer.remove();
1599
+ };
1600
+
1601
+ function parseColor(color) {
1602
+ if (!color) return;
1603
+ if (color.indexOf('rgba') === 0) return color.replace(/\d?\.?\d*\s*\)\s*$/, '0.1)');
1604
+ if (color.indexOf('rgb') === 0) return rgbToRGBA(color);
1605
+ if (color.indexOf('#') === 0) return hexToRGBA(color);
1606
+
1607
+ /**
1608
+ * Converts a hex value to an rgba string
1609
+ *
1610
+ * @param {string} hex value (3 or 6 digits) to be converted
1611
+ *
1612
+ * @returns {string} rgba color with 0.1 alpha
1613
+ */
1614
+ function hexToRGBA(color) {
1615
+ var hex = color.charAt(0) === '#' ? color.substr(1) : color,
1616
+ dig = hex.length / 3,
1617
+ red = hex.substr(0, dig),
1618
+ grn = hex.substr(dig, dig),
1619
+ blu = hex.substr(dig * 2);
1620
+ if (dig === 1) {
1621
+ red += red;
1622
+ grn += grn;
1623
+ blu += blu;
1624
+ }
1625
+ return 'rgba(' + parseInt(red, 16) + ',' + parseInt(grn, 16) + ',' + parseInt(blu, 16) + ',0.1)';
1626
+ }
1627
+
1628
+ /**
1629
+ * Converts rgb value to rgba string
1630
+ *
1631
+ * @param {string} rgb color string
1632
+ *
1633
+ * @returns {string} rgba color with 0.1 alpha
1634
+ */
1635
+ function rgbToRGBA(color) {
1636
+ return color.replace(')', ', 0.1)').replace('(', 'a(');
1637
+ }
1638
+
1639
+ }
1640
+
1641
+ function removeElement(elem, wait) {
1642
+ ripples.splice(ripples.indexOf(elem), 1);
1643
+ if (ripples.length === 0) {
1644
+ rippleContainer && rippleContainer.css({ backgroundColor: '' });
1645
+ }
1646
+ $timeout(function () { elem.remove(); }, wait, false);
1647
+ }
1648
+
1649
+ function updateElement(elem) {
1650
+ var index = ripples.indexOf(elem),
1651
+ state = states[index] || {},
1652
+ elemIsActive = ripples.length > 1 ? false : isActive,
1653
+ elemIsHeld = ripples.length > 1 ? false : isHeld;
1654
+ if (elemIsActive || state.animating || elemIsHeld) {
1655
+ elem.addClass('md-ripple-visible');
1656
+ } else if (elem) {
1657
+ elem.removeClass('md-ripple-visible');
1658
+ if (options.outline) {
1659
+ elem.css({
1660
+ width: rippleSize + 'px',
1661
+ height: rippleSize + 'px',
1662
+ marginLeft: (rippleSize * -1) + 'px',
1663
+ marginTop: (rippleSize * -1) + 'px'
1664
+ });
1665
+ }
1666
+ removeElement(elem, options.outline ? 450 : 650);
1667
+ }
1668
+ }
1669
+
1670
+ /**
1671
+ * Creates a ripple at the provided coordinates
1672
+ *
1673
+ * @param {number} left cursor position
1674
+ * @param {number} top cursor position
1675
+ *
1676
+ * @returns {angular.element} the generated ripple element
1677
+ */
1678
+ function createRipple(left, top) {
1679
+
1680
+ color = parseColor(element.attr('md-ink-ripple')) || parseColor($window.getComputedStyle(options.colorElement[0]).color || 'rgb(0, 0, 0)');
1681
+
1682
+ var container = getRippleContainer(),
1683
+ size = getRippleSize(left, top),
1684
+ css = getRippleCss(size, left, top),
1685
+ elem = getRippleElement(css),
1686
+ index = ripples.indexOf(elem),
1687
+ state = states[index] || {};
1688
+
1689
+ rippleSize = size;
1690
+
1691
+ state.animating = true;
1692
+
1693
+ $timeout(function () {
1694
+ if (options.dimBackground) {
1695
+ container.css({ backgroundColor: color });
1696
+ }
1697
+ elem.addClass('md-ripple-placed md-ripple-scaled');
1698
+ if (options.outline) {
1699
+ elem.css({
1700
+ borderWidth: (size * 0.5) + 'px',
1701
+ marginLeft: (size * -0.5) + 'px',
1702
+ marginTop: (size * -0.5) + 'px'
1703
+ });
1704
+ } else {
1705
+ elem.css({ left: '50%', top: '50%' });
1706
+ }
1707
+ updateElement(elem);
1708
+ $timeout(function () {
1709
+ state.animating = false;
1710
+ updateElement(elem);
1711
+ }, (options.outline ? 450 : 225), false);
1712
+ }, 0, false);
1713
+
1714
+ return elem;
1715
+
1716
+ /**
1717
+ * Creates the ripple element with the provided css
1718
+ *
1719
+ * @param {object} css properties to be applied
1720
+ *
1721
+ * @returns {angular.element} the generated ripple element
1722
+ */
1723
+ function getRippleElement(css) {
1724
+ var elem = angular.element('<div class="md-ripple" data-counter="' + counter++ + '">');
1725
+ ripples.unshift(elem);
1726
+ states.unshift({ animating: true });
1727
+ container.append(elem);
1728
+ css && elem.css(css);
1729
+ return elem;
1730
+ }
1731
+
1732
+ /**
1733
+ * Calculate the ripple size
1734
+ *
1735
+ * @returns {number} calculated ripple diameter
1736
+ */
1737
+ function getRippleSize(left, top) {
1738
+ var width = container.prop('offsetWidth'),
1739
+ height = container.prop('offsetHeight'),
1740
+ multiplier, size, rect;
1741
+ if (options.isMenuItem) {
1742
+ size = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
1743
+ } else if (options.outline) {
1744
+ rect = node.getBoundingClientRect();
1745
+ left -= rect.left;
1746
+ top -= rect.top;
1747
+ width = Math.max(left, width - left);
1748
+ height = Math.max(top, height - top);
1749
+ size = 2 * Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
1750
+ } else {
1751
+ multiplier = options.isFAB ? 1.1 : 0.8;
1752
+ size = Math.max(width, height) * multiplier;
1753
+ }
1754
+ return size;
1755
+ }
1756
+
1757
+ /**
1758
+ * Generates the ripple css
1759
+ *
1760
+ * @param {number} the diameter of the ripple
1761
+ * @param {number} the left cursor offset
1762
+ * @param {number} the top cursor offset
1763
+ *
1764
+ * @returns {{backgroundColor: *, width: string, height: string, marginLeft: string, marginTop: string}}
1765
+ */
1766
+ function getRippleCss(size, left, top) {
1767
+ var rect,
1768
+ css = {
1769
+ backgroundColor: rgbaToRGB(color),
1770
+ borderColor: rgbaToRGB(color),
1771
+ width: size + 'px',
1772
+ height: size + 'px'
1773
+ };
1774
+
1775
+ if (options.outline) {
1776
+ css.width = 0;
1777
+ css.height = 0;
1778
+ } else {
1779
+ css.marginLeft = css.marginTop = (size * -0.5) + 'px';
1780
+ }
1781
+
1782
+ if (options.center) {
1783
+ css.left = css.top = '50%';
1784
+ } else {
1785
+ rect = node.getBoundingClientRect();
1786
+ css.left = Math.round((left - rect.left) / container.prop('offsetWidth') * 100) + '%';
1787
+ css.top = Math.round((top - rect.top) / container.prop('offsetHeight') * 100) + '%';
1788
+ }
1789
+
1790
+ return css;
1791
+
1792
+ /**
1793
+ * Converts rgba string to rgb, removing the alpha value
1794
+ *
1795
+ * @param {string} rgba color
1796
+ *
1797
+ * @returns {string} rgb color
1798
+ */
1799
+ function rgbaToRGB(color) {
1800
+ return color.replace('rgba', 'rgb').replace(/,[^\)\,]+\)/, ')');
1801
+ }
1802
+ }
1803
+
1804
+ /**
1805
+ * Gets the current ripple container
1806
+ * If there is no ripple container, it creates one and returns it
1807
+ *
1808
+ * @returns {angular.element} ripple container element
1809
+ */
1810
+ function getRippleContainer() {
1811
+ if (rippleContainer) return rippleContainer;
1812
+ var container = angular.element('<div class="md-ripple-container"></div>');
1813
+ rippleContainer = container;
1814
+ element.append(container);
1815
+ return container;
1816
+ }
1817
+ }
1818
+
1819
+ /**
1820
+ * Handles user input start and stop events
1821
+ *
1822
+ * @param {event} event fired by hammer.js
1823
+ */
1824
+ function onInput(ev) {
1825
+ var ripple, index;
1826
+ if (ev.eventType === Hammer.INPUT_START && ev.isFirst && isRippleAllowed()) {
1827
+ ripple = createRipple(ev.center.x, ev.center.y);
1828
+ isHeld = true;
1829
+ } else if (ev.eventType === Hammer.INPUT_END && ev.isFinal) {
1830
+ isHeld = false;
1831
+ index = ripples.length - 1;
1832
+ ripple = ripples[index];
1833
+ $timeout(function () { updateElement(ripple); }, 0, false);
1834
+ }
1835
+
1836
+ /**
1837
+ * Determines if the ripple is allowed
1838
+ *
1839
+ * @returns {boolean} true if the ripple is allowed, false if not
1840
+ */
1841
+ function isRippleAllowed() {
1842
+ var parent = node.parentNode;
1843
+ var grandparent = parent && parent.parentNode;
1844
+ var ancestor = grandparent && grandparent.parentNode;
1845
+ return !isDisabled(node) && !isDisabled(parent) && !isDisabled(grandparent) && !isDisabled(ancestor);
1846
+ function isDisabled (elem) {
1847
+ return elem && elem.hasAttribute && elem.hasAttribute('disabled');
1848
+ }
1849
+ }
1850
+ }
1851
+ }
1852
+ }
1853
+ InkRippleService.$inject = ["$window", "$timeout"];
1854
+
1855
+ /**
1856
+ * noink/nobar/nostretch directive: make any element that has one of
1857
+ * these attributes be given a controller, so that other directives can
1858
+ * `require:` these and see if there is a `no<xxx>` parent attribute.
1859
+ *
1860
+ * @usage
1861
+ * <hljs lang="html">
1862
+ * <parent md-no-ink>
1863
+ * <child detect-no>
1864
+ * </child>
1865
+ * </parent>
1866
+ * </hljs>
1867
+ *
1868
+ * <hljs lang="js">
1869
+ * myApp.directive('detectNo', function() {
1870
+ * return {
1871
+ * require: ['^?mdNoInk', ^?mdNoBar'],
1872
+ * link: function(scope, element, attr, ctrls) {
1873
+ * var noinkCtrl = ctrls[0];
1874
+ * var nobarCtrl = ctrls[1];
1875
+ * if (noInkCtrl) {
1876
+ * alert("the md-no-ink flag has been specified on an ancestor!");
1877
+ * }
1878
+ * if (nobarCtrl) {
1879
+ * alert("the md-no-bar flag has been specified on an ancestor!");
1880
+ * }
1881
+ * }
1882
+ * };
1883
+ * });
1884
+ * </hljs>
1885
+ */
1886
+ function attrNoDirective() {
1887
+ return function() {
1888
+ return {
1889
+ controller: angular.noop
1890
+ };
1891
+ };
1892
+ }
1893
+ })();
1894
+
1895
+ (function() {
1896
+ 'use strict';
1897
+
1898
+ angular.module('material.core.theming.palette', [])
1899
+ .constant('$mdColorPalette', {
1900
+ 'red': {
1901
+ '50': '#ffebee',
1902
+ '100': '#ffcdd2',
1903
+ '200': '#ef9a9a',
1904
+ '300': '#e57373',
1905
+ '400': '#ef5350',
1906
+ '500': '#f44336',
1907
+ '600': '#e53935',
1908
+ '700': '#d32f2f',
1909
+ '800': '#c62828',
1910
+ '900': '#b71c1c',
1911
+ 'A100': '#ff8a80',
1912
+ 'A200': '#ff5252',
1913
+ 'A400': '#ff1744',
1914
+ 'A700': '#d50000',
1915
+ 'contrastDefaultColor': 'light',
1916
+ 'contrastDarkColors': '50 100 200 300 400 A100'
1917
+ },
1918
+ 'pink': {
1919
+ '50': '#fce4ec',
1920
+ '100': '#f8bbd0',
1921
+ '200': '#f48fb1',
1922
+ '300': '#f06292',
1923
+ '400': '#ec407a',
1924
+ '500': '#e91e63',
1925
+ '600': '#d81b60',
1926
+ '700': '#c2185b',
1927
+ '800': '#ad1457',
1928
+ '900': '#880e4f',
1929
+ 'A100': '#ff80ab',
1930
+ 'A200': '#ff4081',
1931
+ 'A400': '#f50057',
1932
+ 'A700': '#c51162',
1933
+ 'contrastDefaultColor': 'light',
1934
+ 'contrastDarkColors': '50 100 200 300 400 A100'
1935
+ },
1936
+ 'purple': {
1937
+ '50': '#f3e5f5',
1938
+ '100': '#e1bee7',
1939
+ '200': '#ce93d8',
1940
+ '300': '#ba68c8',
1941
+ '400': '#ab47bc',
1942
+ '500': '#9c27b0',
1943
+ '600': '#8e24aa',
1944
+ '700': '#7b1fa2',
1945
+ '800': '#6a1b9a',
1946
+ '900': '#4a148c',
1947
+ 'A100': '#ea80fc',
1948
+ 'A200': '#e040fb',
1949
+ 'A400': '#d500f9',
1950
+ 'A700': '#aa00ff',
1951
+ 'contrastDefaultColor': 'light',
1952
+ 'contrastDarkColors': '50 100 200 A100'
1953
+ },
1954
+ 'deep-purple': {
1955
+ '50': '#ede7f6',
1956
+ '100': '#d1c4e9',
1957
+ '200': '#b39ddb',
1958
+ '300': '#9575cd',
1959
+ '400': '#7e57c2',
1960
+ '500': '#673ab7',
1961
+ '600': '#5e35b1',
1962
+ '700': '#512da8',
1963
+ '800': '#4527a0',
1964
+ '900': '#311b92',
1965
+ 'A100': '#b388ff',
1966
+ 'A200': '#7c4dff',
1967
+ 'A400': '#651fff',
1968
+ 'A700': '#6200ea',
1969
+ 'contrastDefaultColor': 'light',
1970
+ 'contrastDarkColors': '50 100 200 A100'
1971
+ },
1972
+ 'indigo': {
1973
+ '50': '#e8eaf6',
1974
+ '100': '#c5cae9',
1975
+ '200': '#9fa8da',
1976
+ '300': '#7986cb',
1977
+ '400': '#5c6bc0',
1978
+ '500': '#3f51b5',
1979
+ '600': '#3949ab',
1980
+ '700': '#303f9f',
1981
+ '800': '#283593',
1982
+ '900': '#1a237e',
1983
+ 'A100': '#8c9eff',
1984
+ 'A200': '#536dfe',
1985
+ 'A400': '#3d5afe',
1986
+ 'A700': '#304ffe',
1987
+ 'contrastDefaultColor': 'light',
1988
+ 'contrastDarkColors': '50 100 200 A100'
1989
+ },
1990
+ 'blue': {
1991
+ '50': '#e3f2fd',
1992
+ '100': '#bbdefb',
1993
+ '200': '#90caf9',
1994
+ '300': '#64b5f6',
1995
+ '400': '#42a5f5',
1996
+ '500': '#2196f3',
1997
+ '600': '#1e88e5',
1998
+ '700': '#1976d2',
1999
+ '800': '#1565c0',
2000
+ '900': '#0d47a1',
2001
+ 'A100': '#82b1ff',
2002
+ 'A200': '#448aff',
2003
+ 'A400': '#2979ff',
2004
+ 'A700': '#2962ff',
2005
+ 'contrastDefaultColor': 'light',
2006
+ 'contrastDarkColors': '100 200 300 400 A100'
2007
+ },
2008
+ 'light-blue': {
2009
+ '50': '#e1f5fe',
2010
+ '100': '#b3e5fc',
2011
+ '200': '#81d4fa',
2012
+ '300': '#4fc3f7',
2013
+ '400': '#29b6f6',
2014
+ '500': '#03a9f4',
2015
+ '600': '#039be5',
2016
+ '700': '#0288d1',
2017
+ '800': '#0277bd',
2018
+ '900': '#01579b',
2019
+ 'A100': '#80d8ff',
2020
+ 'A200': '#40c4ff',
2021
+ 'A400': '#00b0ff',
2022
+ 'A700': '#0091ea',
2023
+ 'contrastDefaultColor': 'dark',
2024
+ 'contrastLightColors': '500 600 700 800 900 A700'
2025
+ },
2026
+ 'cyan': {
2027
+ '50': '#e0f7fa',
2028
+ '100': '#b2ebf2',
2029
+ '200': '#80deea',
2030
+ '300': '#4dd0e1',
2031
+ '400': '#26c6da',
2032
+ '500': '#00bcd4',
2033
+ '600': '#00acc1',
2034
+ '700': '#0097a7',
2035
+ '800': '#00838f',
2036
+ '900': '#006064',
2037
+ 'A100': '#84ffff',
2038
+ 'A200': '#18ffff',
2039
+ 'A400': '#00e5ff',
2040
+ 'A700': '#00b8d4',
2041
+ 'contrastDefaultColor': 'dark',
2042
+ 'contrastLightColors': '500 600 700 800 900'
2043
+ },
2044
+ 'teal': {
2045
+ '50': '#e0f2f1',
2046
+ '100': '#b2dfdb',
2047
+ '200': '#80cbc4',
2048
+ '300': '#4db6ac',
2049
+ '400': '#26a69a',
2050
+ '500': '#009688',
2051
+ '600': '#00897b',
2052
+ '700': '#00796b',
2053
+ '800': '#00695c',
2054
+ '900': '#004d40',
2055
+ 'A100': '#a7ffeb',
2056
+ 'A200': '#64ffda',
2057
+ 'A400': '#1de9b6',
2058
+ 'A700': '#00bfa5',
2059
+ 'contrastDefaultColor': 'dark',
2060
+ 'contrastLightColors': '500 600 700 800 900'
2061
+ },
2062
+ 'green': {
2063
+ '50': '#e8f5e9',
2064
+ '100': '#c8e6c9',
2065
+ '200': '#a5d6a7',
2066
+ '300': '#81c784',
2067
+ '400': '#66bb6a',
2068
+ '500': '#4caf50',
2069
+ '600': '#43a047',
2070
+ '700': '#388e3c',
2071
+ '800': '#2e7d32',
2072
+ '900': '#1b5e20',
2073
+ 'A100': '#b9f6ca',
2074
+ 'A200': '#69f0ae',
2075
+ 'A400': '#00e676',
2076
+ 'A700': '#00c853',
2077
+ 'contrastDefaultColor': 'dark',
2078
+ 'contrastLightColors': '500 600 700 800 900'
2079
+ },
2080
+ 'light-green': {
2081
+ '50': '#f1f8e9',
2082
+ '100': '#dcedc8',
2083
+ '200': '#c5e1a5',
2084
+ '300': '#aed581',
2085
+ '400': '#9ccc65',
2086
+ '500': '#8bc34a',
2087
+ '600': '#7cb342',
2088
+ '700': '#689f38',
2089
+ '800': '#558b2f',
2090
+ '900': '#33691e',
2091
+ 'A100': '#ccff90',
2092
+ 'A200': '#b2ff59',
2093
+ 'A400': '#76ff03',
2094
+ 'A700': '#64dd17',
2095
+ 'contrastDefaultColor': 'dark',
2096
+ 'contrastLightColors': '800 900'
2097
+ },
2098
+ 'lime': {
2099
+ '50': '#f9fbe7',
2100
+ '100': '#f0f4c3',
2101
+ '200': '#e6ee9c',
2102
+ '300': '#dce775',
2103
+ '400': '#d4e157',
2104
+ '500': '#cddc39',
2105
+ '600': '#c0ca33',
2106
+ '700': '#afb42b',
2107
+ '800': '#9e9d24',
2108
+ '900': '#827717',
2109
+ 'A100': '#f4ff81',
2110
+ 'A200': '#eeff41',
2111
+ 'A400': '#c6ff00',
2112
+ 'A700': '#aeea00',
2113
+ 'contrastDefaultColor': 'dark',
2114
+ 'contrastLightColors': '900'
2115
+ },
2116
+ 'yellow': {
2117
+ '50': '#fffde7',
2118
+ '100': '#fff9c4',
2119
+ '200': '#fff59d',
2120
+ '300': '#fff176',
2121
+ '400': '#ffee58',
2122
+ '500': '#ffeb3b',
2123
+ '600': '#fdd835',
2124
+ '700': '#fbc02d',
2125
+ '800': '#f9a825',
2126
+ '900': '#f57f17',
2127
+ 'A100': '#ffff8d',
2128
+ 'A200': '#ffff00',
2129
+ 'A400': '#ffea00',
2130
+ 'A700': '#ffd600',
2131
+ 'contrastDefaultColor': 'dark'
2132
+ },
2133
+ 'amber': {
2134
+ '50': '#fff8e1',
2135
+ '100': '#ffecb3',
2136
+ '200': '#ffe082',
2137
+ '300': '#ffd54f',
2138
+ '400': '#ffca28',
2139
+ '500': '#ffc107',
2140
+ '600': '#ffb300',
2141
+ '700': '#ffa000',
2142
+ '800': '#ff8f00',
2143
+ '900': '#ff6f00',
2144
+ 'A100': '#ffe57f',
2145
+ 'A200': '#ffd740',
2146
+ 'A400': '#ffc400',
2147
+ 'A700': '#ffab00',
2148
+ 'contrastDefaultColor': 'dark'
2149
+ },
2150
+ 'orange': {
2151
+ '50': '#fff3e0',
2152
+ '100': '#ffe0b2',
2153
+ '200': '#ffcc80',
2154
+ '300': '#ffb74d',
2155
+ '400': '#ffa726',
2156
+ '500': '#ff9800',
2157
+ '600': '#fb8c00',
2158
+ '700': '#f57c00',
2159
+ '800': '#ef6c00',
2160
+ '900': '#e65100',
2161
+ 'A100': '#ffd180',
2162
+ 'A200': '#ffab40',
2163
+ 'A400': '#ff9100',
2164
+ 'A700': '#ff6d00',
2165
+ 'contrastDefaultColor': 'dark',
2166
+ 'contrastLightColors': '800 900'
2167
+ },
2168
+ 'deep-orange': {
2169
+ '50': '#fbe9e7',
2170
+ '100': '#ffccbc',
2171
+ '200': '#ffab91',
2172
+ '300': '#ff8a65',
2173
+ '400': '#ff7043',
2174
+ '500': '#ff5722',
2175
+ '600': '#f4511e',
2176
+ '700': '#e64a19',
2177
+ '800': '#d84315',
2178
+ '900': '#bf360c',
2179
+ 'A100': '#ff9e80',
2180
+ 'A200': '#ff6e40',
2181
+ 'A400': '#ff3d00',
2182
+ 'A700': '#dd2c00',
2183
+ 'contrastDefaultColor': 'light',
2184
+ 'contrastDarkColors': '50 100 200 300 400 A100 A200'
2185
+ },
2186
+ 'brown': {
2187
+ '50': '#efebe9',
2188
+ '100': '#d7ccc8',
2189
+ '200': '#bcaaa4',
2190
+ '300': '#a1887f',
2191
+ '400': '#8d6e63',
2192
+ '500': '#795548',
2193
+ '600': '#6d4c41',
2194
+ '700': '#5d4037',
2195
+ '800': '#4e342e',
2196
+ '900': '#3e2723',
2197
+ 'A100': '#d7ccc8',
2198
+ 'A200': '#bcaaa4',
2199
+ 'A400': '#8d6e63',
2200
+ 'A700': '#5d4037',
2201
+ 'contrastDefaultColor': 'light',
2202
+ 'contrastDarkColors': '50 100 200'
2203
+ },
2204
+ 'grey': {
2205
+ '0': '#ffffff',
2206
+ '50': '#fafafa',
2207
+ '100': '#f5f5f5',
2208
+ '200': '#eeeeee',
2209
+ '300': '#e0e0e0',
2210
+ '400': '#bdbdbd',
2211
+ '500': '#9e9e9e',
2212
+ '600': '#757575',
2213
+ '700': '#616161',
2214
+ '800': '#424242',
2215
+ '900': '#212121',
2216
+ '1000': '#000000',
2217
+ 'A100': '#ffffff',
2218
+ 'A200': '#eeeeee',
2219
+ 'A400': '#bdbdbd',
2220
+ 'A700': '#616161',
2221
+ 'contrastDefaultColor': 'dark',
2222
+ 'contrastLightColors': '600 700 800 900'
2223
+ },
2224
+ 'blue-grey': {
2225
+ '50': '#eceff1',
2226
+ '100': '#cfd8dc',
2227
+ '200': '#b0bec5',
2228
+ '300': '#90a4ae',
2229
+ '400': '#78909c',
2230
+ '500': '#607d8b',
2231
+ '600': '#546e7a',
2232
+ '700': '#455a64',
2233
+ '800': '#37474f',
2234
+ '900': '#263238',
2235
+ 'A100': '#cfd8dc',
2236
+ 'A200': '#b0bec5',
2237
+ 'A400': '#78909c',
2238
+ 'A700': '#455a64',
2239
+ 'contrastDefaultColor': 'light',
2240
+ 'contrastDarkColors': '50 100 200 300'
2241
+ }
2242
+ });
2243
+ })();
2244
+
2245
+ (function() {
2246
+ 'use strict';
2247
+
2248
+ angular.module('material.core.theming', ['material.core.theming.palette'])
2249
+ .directive('mdTheme', ThemingDirective)
2250
+ .directive('mdThemable', ThemableDirective)
2251
+ .provider('$mdTheming', ThemingProvider)
2252
+ .run(generateThemes);
2253
+
2254
+ /**
2255
+ * @ngdoc provider
2256
+ * @name $mdThemingProvider
2257
+ * @module material.core
2258
+ *
2259
+ * @description Provider to configure the `$mdTheming` service.
2260
+ */
2261
+
2262
+ /**
2263
+ * @ngdoc method
2264
+ * @name $mdThemingProvider#setDefaultTheme
2265
+ * @param {string} themeName Default theme name to be applied to elements. Default value is `default`.
2266
+ */
2267
+
2268
+ /**
2269
+ * @ngdoc method
2270
+ * @name $mdThemingProvider#alwaysWatchTheme
2271
+ * @param {boolean} watch Whether or not to always watch themes for changes and re-apply
2272
+ * classes when they change. Default is `false`. Enabling can reduce performance.
2273
+ */
2274
+
2275
+ // In memory storage of defined themes and color palettes (both loaded by CSS, and user specified)
2276
+ var PALETTES;
2277
+ var THEMES;
2278
+ var themingProvider;
2279
+ var generationIsDone;
2280
+
2281
+ var DARK_FOREGROUND = {
2282
+ name: 'dark',
2283
+ '1': 'rgba(0,0,0,0.87)',
2284
+ '2': 'rgba(0,0,0,0.54)',
2285
+ '3': 'rgba(0,0,0,0.26)',
2286
+ '4': 'rgba(0,0,0,0.12)'
2287
+ };
2288
+ var LIGHT_FOREGROUND = {
2289
+ name: 'light',
2290
+ '1': 'rgba(255,255,255,1.0)',
2291
+ '2': 'rgba(255,255,255,0.7)',
2292
+ '3': 'rgba(255,255,255,0.3)',
2293
+ '4': 'rgba(255,255,255,0.12)'
2294
+ };
2295
+
2296
+ var DARK_SHADOW = '1px 1px 0px rgba(0,0,0,0.4), -1px -1px 0px rgba(0,0,0,0.4)';
2297
+ var LIGHT_SHADOW = '';
2298
+
2299
+ var DARK_CONTRAST_COLOR = colorToRgbaArray('rgba(0,0,0,0.87)');
2300
+ var LIGHT_CONTRAST_COLOR = colorToRgbaArray('rgb(255,255,255)');
2301
+
2302
+ var THEME_COLOR_TYPES = ['primary', 'accent', 'warn', 'background'];
2303
+ var DEFAULT_COLOR_TYPE = 'primary';
2304
+
2305
+ // A color in a theme will use these hues by default, if not specified by user.
2306
+ var LIGHT_DEFAULT_HUES = {
2307
+ 'accent': {
2308
+ 'default': 'A700',
2309
+ 'hue-1': 'A200',
2310
+ 'hue-2': 'A400',
2311
+ 'hue-3': 'A100'
2312
+ }
2313
+ };
2314
+ var DARK_DEFAULT_HUES = {
2315
+ 'background': {
2316
+ 'default': '500',
2317
+ 'hue-1': '300',
2318
+ 'hue-2': '600',
2319
+ 'hue-3': '800'
2320
+ }
2321
+ };
2322
+ THEME_COLOR_TYPES.forEach(function(colorType) {
2323
+ // Color types with unspecified default hues will use these default hue values
2324
+ var defaultDefaultHues = {
2325
+ 'default': '500',
2326
+ 'hue-1': '300',
2327
+ 'hue-2': '800',
2328
+ 'hue-3': 'A100'
2329
+ };
2330
+ if (!LIGHT_DEFAULT_HUES[colorType]) LIGHT_DEFAULT_HUES[colorType] = defaultDefaultHues;
2331
+ if (!DARK_DEFAULT_HUES[colorType]) DARK_DEFAULT_HUES[colorType] = defaultDefaultHues;
2332
+ });
2333
+
2334
+ var VALID_HUE_VALUES = [
2335
+ '50', '100', '200', '300', '400', '500', '600',
2336
+ '700', '800', '900', 'A100', 'A200', 'A400', 'A700'
2337
+ ];
2338
+
2339
+ function ThemingProvider($mdColorPalette) {
2340
+ PALETTES = {};
2341
+ THEMES = {};
2342
+ var defaultTheme = 'default';
2343
+ var alwaysWatchTheme = false;
2344
+
2345
+ // Load JS Defined Palettes
2346
+ angular.extend(PALETTES, $mdColorPalette);
2347
+
2348
+ // Default theme defined in core.js
2349
+
2350
+ ThemingService.$inject = ["$rootScope"];
2351
+ return themingProvider = {
2352
+ definePalette: definePalette,
2353
+ extendPalette: extendPalette,
2354
+ theme: registerTheme,
2355
+
2356
+ setDefaultTheme: function(theme) {
2357
+ defaultTheme = theme;
2358
+ },
2359
+ alwaysWatchTheme: function(alwaysWatch) {
2360
+ alwaysWatchTheme = alwaysWatch;
2361
+ },
2362
+ $get: ThemingService,
2363
+ _LIGHT_DEFAULT_HUES: LIGHT_DEFAULT_HUES,
2364
+ _DARK_DEFAULT_HUES: DARK_DEFAULT_HUES,
2365
+ _PALETTES: PALETTES,
2366
+ _THEMES: THEMES,
2367
+ _parseRules: parseRules,
2368
+ _rgba: rgba
2369
+ };
2370
+
2371
+ // Example: $mdThemingProvider.definePalette('neonRed', { 50: '#f5fafa', ... });
2372
+ function definePalette(name, map) {
2373
+ map = map || {};
2374
+ PALETTES[name] = checkPaletteValid(name, map);
2375
+ return themingProvider;
2376
+ }
2377
+
2378
+ // Returns an new object which is a copy of a given palette `name` with variables from
2379
+ // `map` overwritten
2380
+ // Example: var neonRedMap = $mdThemingProvider.extendPalette('red', { 50: '#f5fafafa' });
2381
+ function extendPalette(name, map) {
2382
+ return checkPaletteValid(name, angular.extend({}, PALETTES[name] || {}, map) );
2383
+ }
2384
+
2385
+ // Make sure that palette has all required hues
2386
+ function checkPaletteValid(name, map) {
2387
+ var missingColors = VALID_HUE_VALUES.filter(function(field) {
2388
+ return !map[field];
2389
+ });
2390
+ if (missingColors.length) {
2391
+ throw new Error("Missing colors %1 in palette %2!"
2392
+ .replace('%1', missingColors.join(', '))
2393
+ .replace('%2', name));
2394
+ }
2395
+
2396
+ return map;
2397
+ }
2398
+
2399
+ // Register a theme (which is a collection of color palettes to use with various states
2400
+ // ie. warn, accent, primary )
2401
+ // Optionally inherit from an existing theme
2402
+ // $mdThemingProvider.theme('custom-theme').primaryColor('red');
2403
+ function registerTheme(name, inheritFrom) {
2404
+ inheritFrom = inheritFrom || 'default';
2405
+ if (THEMES[name]) return THEMES[name];
2406
+
2407
+ var parentTheme = typeof inheritFrom === 'string' ? THEMES[inheritFrom] : inheritFrom;
2408
+ var theme = new Theme(name);
2409
+
2410
+ if (parentTheme) {
2411
+ angular.forEach(parentTheme.colors, function(color, colorType) {
2412
+ theme.colors[colorType] = {
2413
+ name: color.name,
2414
+ // Make sure a COPY of the hues is given to the child color,
2415
+ // not the same reference.
2416
+ hues: angular.extend({}, color.hues)
2417
+ };
2418
+ });
2419
+ }
2420
+ THEMES[name] = theme;
2421
+
2422
+ return theme;
2423
+ }
2424
+
2425
+ function Theme(name) {
2426
+ var self = this;
2427
+ self.name = name;
2428
+ self.colors = {};
2429
+
2430
+ self.dark = setDark;
2431
+ setDark(false);
2432
+
2433
+ function setDark(isDark) {
2434
+ isDark = arguments.length === 0 ? true : !!isDark;
2435
+
2436
+ // If no change, abort
2437
+ if (isDark === self.isDark) return;
2438
+
2439
+ self.isDark = isDark;
2440
+
2441
+ self.foregroundPalette = self.isDark ? LIGHT_FOREGROUND : DARK_FOREGROUND;
2442
+ self.foregroundShadow = self.isDark ? DARK_SHADOW : LIGHT_SHADOW;
2443
+
2444
+ // Light and dark themes have different default hues.
2445
+ // Go through each existing color type for this theme, and for every
2446
+ // hue value that is still the default hue value from the previous light/dark setting,
2447
+ // set it to the default hue value from the new light/dark setting.
2448
+ var newDefaultHues = self.isDark ? DARK_DEFAULT_HUES : LIGHT_DEFAULT_HUES;
2449
+ var oldDefaultHues = self.isDark ? LIGHT_DEFAULT_HUES : DARK_DEFAULT_HUES;
2450
+ angular.forEach(newDefaultHues, function(newDefaults, colorType) {
2451
+ var color = self.colors[colorType];
2452
+ var oldDefaults = oldDefaultHues[colorType];
2453
+ if (color) {
2454
+ for (var hueName in color.hues) {
2455
+ if (color.hues[hueName] === oldDefaults[hueName]) {
2456
+ color.hues[hueName] = newDefaults[hueName];
2457
+ }
2458
+ }
2459
+ }
2460
+ });
2461
+
2462
+ return self;
2463
+ }
2464
+
2465
+ THEME_COLOR_TYPES.forEach(function(colorType) {
2466
+ var defaultHues = (self.isDark ? DARK_DEFAULT_HUES : LIGHT_DEFAULT_HUES)[colorType];
2467
+ self[colorType + 'Color'] = function setColorType(paletteName, hues) {
2468
+ var color = self.colors[colorType] = {
2469
+ name: paletteName,
2470
+ hues: angular.extend({}, defaultHues, hues)
2471
+ };
2472
+
2473
+ Object.keys(color.hues).forEach(function(name) {
2474
+ if (!defaultHues[name]) {
2475
+ throw new Error("Invalid hue name '%1' in theme %2's %3 color %4. Available hue names: %4"
2476
+ .replace('%1', name)
2477
+ .replace('%2', self.name)
2478
+ .replace('%3', paletteName)
2479
+ .replace('%4', Object.keys(defaultHues).join(', '))
2480
+ );
2481
+ }
2482
+ });
2483
+ Object.keys(color.hues).map(function(key) {
2484
+ return color.hues[key];
2485
+ }).forEach(function(hueValue) {
2486
+ if (VALID_HUE_VALUES.indexOf(hueValue) == -1) {
2487
+ throw new Error("Invalid hue value '%1' in theme %2's %3 color %4. Available hue values: %5"
2488
+ .replace('%1', hueValue)
2489
+ .replace('%2', self.name)
2490
+ .replace('%3', colorType)
2491
+ .replace('%4', paletteName)
2492
+ .replace('%5', VALID_HUE_VALUES.join(', '))
2493
+ );
2494
+ }
2495
+ });
2496
+
2497
+ return self;
2498
+ };
2499
+ });
2500
+ }
2501
+
2502
+ /**
2503
+ * @ngdoc service
2504
+ * @name $mdTheming
2505
+ *
2506
+ * @description
2507
+ *
2508
+ * Service that makes an element apply theming related classes to itself.
2509
+ *
2510
+ * ```js
2511
+ * app.directive('myFancyDirective', function($mdTheming) {
2512
+ * return {
2513
+ * restrict: 'e',
2514
+ * link: function(scope, el, attrs) {
2515
+ * $mdTheming(el);
2516
+ * }
2517
+ * };
2518
+ * });
2519
+ * ```
2520
+ * @param {el=} element to apply theming to
2521
+ */
2522
+ /* @ngInject */
2523
+ function ThemingService($rootScope) {
2524
+ applyTheme.inherit = function(el, parent) {
2525
+ var ctrl = parent.controller('mdTheme');
2526
+
2527
+ var attrThemeValue = el.attr('md-theme-watch');
2528
+ if ( (alwaysWatchTheme || angular.isDefined(attrThemeValue)) && attrThemeValue != 'false') {
2529
+ var deregisterWatch = $rootScope.$watch(function() {
2530
+ return ctrl && ctrl.$mdTheme || defaultTheme;
2531
+ }, changeTheme);
2532
+ el.on('$destroy', deregisterWatch);
2533
+ } else {
2534
+ var theme = ctrl && ctrl.$mdTheme || defaultTheme;
2535
+ changeTheme(theme);
2536
+ }
2537
+
2538
+ function changeTheme(theme) {
2539
+ var oldTheme = el.data('$mdThemeName');
2540
+ if (oldTheme) el.removeClass('md-' + oldTheme +'-theme');
2541
+ el.addClass('md-' + theme + '-theme');
2542
+ el.data('$mdThemeName', theme);
2543
+ }
2544
+ };
2545
+
2546
+ return applyTheme;
2547
+
2548
+ function applyTheme(scope, el) {
2549
+ // Allow us to be invoked via a linking function signature.
2550
+ if (el === undefined) {
2551
+ el = scope;
2552
+ scope = undefined;
2553
+ }
2554
+ if (scope === undefined) {
2555
+ scope = $rootScope;
2556
+ }
2557
+ applyTheme.inherit(el, el);
2558
+ }
2559
+ }
2560
+ }
2561
+ ThemingProvider.$inject = ["$mdColorPalette"];
2562
+
2563
+ function ThemingDirective($interpolate) {
2564
+ return {
2565
+ priority: 100,
2566
+ link: {
2567
+ pre: function(scope, el, attrs) {
2568
+ var ctrl = {
2569
+ $setTheme: function(theme) {
2570
+ ctrl.$mdTheme = theme;
2571
+ }
2572
+ };
2573
+ el.data('$mdThemeController', ctrl);
2574
+ ctrl.$setTheme($interpolate(attrs.mdTheme)(scope));
2575
+ attrs.$observe('mdTheme', ctrl.$setTheme);
2576
+ }
2577
+ }
2578
+ };
2579
+ }
2580
+ ThemingDirective.$inject = ["$interpolate"];
2581
+
2582
+ function ThemableDirective($mdTheming) {
2583
+ return $mdTheming;
2584
+ }
2585
+ ThemableDirective.$inject = ["$mdTheming"];
2586
+
2587
+ function parseRules(theme, colorType, rules) {
2588
+ checkValidPalette(theme, colorType);
2589
+
2590
+ rules = rules.replace(/THEME_NAME/g, theme.name);
2591
+ var generatedRules = [];
2592
+ var color = theme.colors[colorType];
2593
+
2594
+ var themeNameRegex = new RegExp('.md-' + theme.name + '-theme', 'g');
2595
+ // Matches '{{ primary-color }}', etc
2596
+ var hueRegex = new RegExp('(\'|")?{{\\s*(' + colorType + ')-(color|contrast)-?(\\d\\.?\\d*)?\\s*}}(\"|\')?','g');
2597
+ var simpleVariableRegex = /'?"?\{\{\s*([a-zA-Z]+)-(A?\d+|hue\-[0-3]|shadow)-?(\d\.?\d*)?\s*\}\}'?"?/g;
2598
+ var palette = PALETTES[color.name];
2599
+
2600
+ // find and replace simple variables where we use a specific hue, not angentire palette
2601
+ // eg. "{{primary-100}}"
2602
+ //\(' + THEME_COLOR_TYPES.join('\|') + '\)'
2603
+ rules = rules.replace(simpleVariableRegex, function(match, colorType, hue, opacity) {
2604
+ if (colorType === 'foreground') {
2605
+ if (hue == 'shadow') {
2606
+ return theme.foregroundShadow;
2607
+ } else {
2608
+ return theme.foregroundPalette[hue] || theme.foregroundPalette['1'];
2609
+ }
2610
+ }
2611
+ if (hue.indexOf('hue') === 0) {
2612
+ hue = theme.colors[colorType].hues[hue];
2613
+ }
2614
+ return rgba( (PALETTES[ theme.colors[colorType].name ][hue] || '').value, opacity );
2615
+ });
2616
+
2617
+ // For each type, generate rules for each hue (ie. default, md-hue-1, md-hue-2, md-hue-3)
2618
+ angular.forEach(color.hues, function(hueValue, hueName) {
2619
+ var newRule = rules
2620
+ .replace(hueRegex, function(match, _, colorType, hueType, opacity) {
2621
+ return rgba(palette[hueValue][hueType === 'color' ? 'value' : 'contrast'], opacity);
2622
+ });
2623
+ if (hueName !== 'default') {
2624
+ newRule = newRule.replace(themeNameRegex, '.md-' + theme.name + '-theme.md-' + hueName);
2625
+ }
2626
+ generatedRules.push(newRule);
2627
+ });
2628
+
2629
+ return generatedRules.join('');
2630
+ }
2631
+
2632
+ // Generate our themes at run time given the state of THEMES and PALETTES
2633
+ function generateThemes($injector) {
2634
+ var themeCss = $injector.has('$MD_THEME_CSS') ? $injector.get('$MD_THEME_CSS') : '';
2635
+
2636
+ // MD_THEME_CSS is a string generated by the build process that includes all the themable
2637
+ // components as templates
2638
+
2639
+ // Expose contrast colors for palettes to ensure that text is always readable
2640
+ angular.forEach(PALETTES, sanitizePalette);
2641
+
2642
+ // Break the CSS into individual rules
2643
+ var rules = themeCss.split(/\}(?!(\}|'|"|;))/)
2644
+ .filter(function(rule) { return rule && rule.length; })
2645
+ .map(function(rule) { return rule.trim() + '}'; });
2646
+
2647
+ var rulesByType = {};
2648
+ THEME_COLOR_TYPES.forEach(function(type) {
2649
+ rulesByType[type] = '';
2650
+ });
2651
+ var ruleMatchRegex = new RegExp('md-(' + THEME_COLOR_TYPES.join('|') + ')', 'g');
2652
+
2653
+ // Sort the rules based on type, allowing us to do color substitution on a per-type basis
2654
+ rules.forEach(function(rule) {
2655
+ var match = rule.match(ruleMatchRegex);
2656
+ // First: test that if the rule has '.md-accent', it goes into the accent set of rules
2657
+ for (var i = 0, type; type = THEME_COLOR_TYPES[i]; i++) {
2658
+ if (rule.indexOf('.md-' + type) > -1) {
2659
+ return rulesByType[type] += rule;
2660
+ }
2661
+ }
2662
+
2663
+ // If no eg 'md-accent' class is found, try to just find 'accent' in the rule and guess from
2664
+ // there
2665
+ for (i = 0; type = THEME_COLOR_TYPES[i]; i++) {
2666
+ if (rule.indexOf(type) > -1) {
2667
+ return rulesByType[type] += rule;
2668
+ }
2669
+ }
2670
+
2671
+ // Default to the primary array
2672
+ return rulesByType[DEFAULT_COLOR_TYPE] += rule;
2673
+ });
2674
+
2675
+ var styleString = '';
2676
+
2677
+ // For each theme, use the color palettes specified for `primary`, `warn` and `accent`
2678
+ // to generate CSS rules.
2679
+ angular.forEach(THEMES, function(theme) {
2680
+ THEME_COLOR_TYPES.forEach(function(colorType) {
2681
+ styleString += parseRules(theme, colorType, rulesByType[colorType] + '');
2682
+ });
2683
+ });
2684
+
2685
+ // Insert our newly minted styles into the DOM
2686
+ if (!generationIsDone) {
2687
+ var style = document.createElement('style');
2688
+ style.innerHTML = styleString;
2689
+ var head = document.getElementsByTagName('head')[0];
2690
+ head.insertBefore(style, head.firstElementChild);
2691
+ generationIsDone = true;
2692
+ }
2693
+
2694
+ // The user specifies a 'default' contrast color as either light or dark,
2695
+ // then explicitly lists which hues are the opposite contrast (eg. A100 has dark, A200 has light)
2696
+ function sanitizePalette(palette) {
2697
+ var defaultContrast = palette.contrastDefaultColor;
2698
+ var lightColors = palette.contrastLightColors || [];
2699
+ var darkColors = palette.contrastDarkColors || [];
2700
+
2701
+ // Sass provides these colors as space-separated lists
2702
+ if (typeof lightColors === 'string') lightColors = lightColors.split(' ');
2703
+ if (typeof darkColors === 'string') darkColors = darkColors.split(' ');
2704
+
2705
+ // Cleanup after ourselves
2706
+ delete palette.contrastDefaultColor;
2707
+ delete palette.contrastLightColors;
2708
+ delete palette.contrastDarkColors;
2709
+
2710
+ // Change { 'A100': '#fffeee' } to { 'A100': { value: '#fffeee', contrast:DARK_CONTRAST_COLOR }
2711
+ angular.forEach(palette, function(hueValue, hueName) {
2712
+ if (angular.isObject(hueValue)) return; // Already converted
2713
+ // Map everything to rgb colors
2714
+ var rgbValue = colorToRgbaArray(hueValue);
2715
+ if (!rgbValue) {
2716
+ throw new Error("Color %1, in palette %2's hue %3, is invalid. Hex or rgb(a) color expected."
2717
+ .replace('%1', hueValue)
2718
+ .replace('%2', palette.name)
2719
+ .replace('%3', hueName));
2720
+ }
2721
+
2722
+ palette[hueName] = {
2723
+ value: rgbValue,
2724
+ contrast: getContrastColor()
2725
+ };
2726
+ function getContrastColor() {
2727
+ if (defaultContrast === 'light') {
2728
+ return darkColors.indexOf(hueName) > -1 ? DARK_CONTRAST_COLOR : LIGHT_CONTRAST_COLOR;
2729
+ } else {
2730
+ return lightColors.indexOf(hueName) > -1 ? LIGHT_CONTRAST_COLOR : DARK_CONTRAST_COLOR;
2731
+ }
2732
+ }
2733
+ });
2734
+ }
2735
+
2736
+ }
2737
+ generateThemes.$inject = ["$injector"];
2738
+
2739
+ function checkValidPalette(theme, colorType) {
2740
+ // If theme attempts to use a palette that doesnt exist, throw error
2741
+ if (!PALETTES[ (theme.colors[colorType] || {}).name ]) {
2742
+ throw new Error(
2743
+ "You supplied an invalid color palette for theme %1's %2 palette. Available palettes: %3"
2744
+ .replace('%1', theme.name)
2745
+ .replace('%2', colorType)
2746
+ .replace('%3', Object.keys(PALETTES).join(', '))
2747
+ );
2748
+ }
2749
+ }
2750
+
2751
+ function colorToRgbaArray(clr) {
2752
+ if (angular.isArray(clr) && clr.length == 3) return clr;
2753
+ if (/^rgb/.test(clr)) {
2754
+ return clr.replace(/(^\s*rgba?\(|\)\s*$)/g, '').split(',').map(function(value) {
2755
+ return parseInt(value, 10);
2756
+ });
2757
+ }
2758
+ if (clr.charAt(0) == '#') clr = clr.substring(1);
2759
+ if (!/^([a-fA-F0-9]{3}){1,2}$/g.test(clr)) return;
2760
+
2761
+ var dig = clr.length / 3;
2762
+ var red = clr.substr(0, dig);
2763
+ var grn = clr.substr(dig, dig);
2764
+ var blu = clr.substr(dig * 2);
2765
+ if (dig === 1) {
2766
+ red += red;
2767
+ grn += grn;
2768
+ blu += blu;
2769
+ }
2770
+ return [parseInt(red, 16), parseInt(grn, 16), parseInt(blu, 16)];
2771
+ }
2772
+
2773
+ function rgba(rgbArray, opacity) {
2774
+ if (rgbArray.length == 4) opacity = rgbArray.pop();
2775
+ return opacity && opacity.length ?
2776
+ 'rgba(' + rgbArray.join(',') + ',' + opacity + ')' :
2777
+ 'rgb(' + rgbArray.join(',') + ')';
2778
+ }
2779
+
2780
+ })();