j1-template 2020.0.7 → 2020.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (341) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/blocks/ads/ad.html +64 -0
  3. data/_includes/themes/j1/blocks/footer/boxes/links_box.proc +1 -1
  4. data/_includes/themes/j1/layouts/content_generator_blog_archive.html +3 -2
  5. data/_includes/themes/j1/layouts/content_generator_collection.html +3 -1
  6. data/_includes/themes/j1/layouts/content_generator_page.html +3 -1
  7. data/_includes/themes/j1/layouts/content_generator_post.html +12 -11
  8. data/_includes/themes/j1/layouts/layout_metadata_generator.html +141 -4
  9. data/_includes/themes/j1/modules/connectors/ad/custom-provider.html +6 -9
  10. data/_includes/themes/j1/modules/connectors/ad/google-adsense.html +9 -6
  11. data/_includes/themes/j1/modules/connectors/ads +3 -6
  12. data/_includes/themes/j1/modules/navigator/generator.html +6 -6
  13. data/_includes/themes/j1/modules/navigator/procedures/topsearch.proc +10 -5
  14. data/_includes/themes/j1/procedures/layouts/module_writer.proc +1 -1
  15. data/_includes/themes/j1/procedures/posts/collate_timeline.proc +7 -7
  16. data/_layouts/default.html +18 -8
  17. data/assets/data/authclient.html +19 -8
  18. data/assets/data/banner.html +24 -23
  19. data/assets/data/carousel.json +31 -21
  20. data/assets/data/cookie_consent.html +81 -52
  21. data/assets/data/footer.html +15 -5
  22. data/assets/data/galleries.json +91 -81
  23. data/assets/data/gallery_customizer.html +20 -10
  24. data/assets/data/mdi_icons.json +56 -1
  25. data/assets/data/menu.html +14 -6
  26. data/assets/data/mmenu.html +47 -93
  27. data/assets/data/mmenu_sidebar.html +41 -44
  28. data/assets/data/mmenu_toc.html +20 -3
  29. data/assets/data/panel.html +35 -22
  30. data/assets/data/quicklinks.html +15 -3
  31. data/assets/data/{search.yml → search.json} +44 -14
  32. data/assets/data/ssm.html +30 -14
  33. data/assets/data/themes.json +17 -6
  34. data/assets/data/twa_v1.json +7035 -6978
  35. data/assets/themes/j1/adapter/js/algolia.js +34 -15
  36. data/assets/themes/j1/adapter/js/attic.js +66 -45
  37. data/assets/themes/j1/adapter/js/carousel.js +43 -22
  38. data/assets/themes/j1/adapter/js/clipboard.js +232 -0
  39. data/assets/themes/j1/adapter/js/cookie_consent.js +21 -4
  40. data/assets/themes/j1/adapter/js/framer.js +18 -3
  41. data/assets/themes/j1/adapter/js/gallery_customizer.js +27 -10
  42. data/assets/themes/j1/adapter/js/j1.js +349 -759
  43. data/assets/themes/j1/adapter/js/{justified_gallery.js → jf_gallery.js} +64 -38
  44. data/assets/themes/j1/adapter/js/lightbox.js +20 -3
  45. data/assets/themes/j1/adapter/js/logger.js +23 -6
  46. data/assets/themes/j1/adapter/js/mdb.js +167 -0
  47. data/assets/themes/j1/adapter/js/mmenu.js +29 -11
  48. data/assets/themes/j1/adapter/js/navigator.js +126 -139
  49. data/assets/themes/j1/adapter/js/searcher.js +22 -4
  50. data/assets/themes/j1/adapter/js/ssm.js +96 -63
  51. data/assets/themes/j1/adapter/js/themer.js +35 -52
  52. data/assets/themes/j1/adapter/js/toccer.js +69 -158
  53. data/assets/themes/j1/core/css/theme_extensions.css +120 -1230
  54. data/assets/themes/j1/core/css/theme_extensions.min.css +1 -1
  55. data/assets/themes/j1/core/css/uno.css +253 -1275
  56. data/assets/themes/j1/core/css/uno.min.css +1 -1
  57. data/assets/themes/j1/core/css/vendor.css +7 -57
  58. data/assets/themes/j1/core/css/vendor.min.css +2 -2
  59. data/assets/themes/j1/core/js/template.js +16 -86
  60. data/assets/themes/j1/core/js/template.js.map +1 -1
  61. data/assets/themes/j1/core/js/template.min.js +1 -1
  62. data/assets/themes/j1/extensions/bsDatepicker/css/datepicker.css +203 -0
  63. data/assets/themes/j1/extensions/bsDatepicker/css/theme/uno.css +235 -0
  64. data/assets/themes/j1/extensions/bsDatepicker/js/datepicker.js +509 -0
  65. data/assets/themes/j1/extensions/bsDatepicker/less/datepicker.less +122 -0
  66. data/assets/themes/j1/extensions/bsThemeSwitcher/js/switcher.js +425 -0
  67. data/assets/themes/j1/extensions/bsThemeSwitcher/js/switcher.min.js +20 -0
  68. data/assets/themes/j1/extensions/clipboard/LICENSE +20 -0
  69. data/assets/themes/j1/extensions/clipboard/css/theme/uno.css +52 -0
  70. data/assets/themes/j1/extensions/clipboard/css/theme/uno.min.css +52 -0
  71. data/assets/themes/j1/extensions/clipboard/js/clipboard.js +975 -0
  72. data/assets/themes/j1/extensions/clipboard/js/clipboard.min.js +7 -0
  73. data/assets/themes/j1/extensions/{iconify → iconifyAPI}/js/iconify.min.js +0 -0
  74. data/assets/themes/j1/extensions/iframeResizer/LICENSE +21 -0
  75. data/assets/themes/j1/extensions/iframeResizer/examples/frame.absolute.html +127 -0
  76. data/assets/themes/j1/extensions/iframeResizer/examples/frame.content.html +157 -0
  77. data/assets/themes/j1/extensions/iframeResizer/examples/frame.hover.html +68 -0
  78. data/assets/themes/j1/extensions/iframeResizer/examples/frame.nested.html +100 -0
  79. data/assets/themes/j1/extensions/iframeResizer/examples/frame.textarea.html +45 -0
  80. data/assets/themes/j1/extensions/iframeResizer/examples/frame.tolerance.html +113 -0
  81. data/assets/themes/j1/extensions/iframeResizer/examples/index.html +83 -0
  82. data/assets/themes/j1/extensions/iframeResizer/examples/two.html +88 -0
  83. data/assets/themes/j1/extensions/iframeResizer/js/client/iframeResizer.contentWindow.js +1288 -0
  84. data/assets/themes/j1/extensions/iframeResizer/js/client/iframeResizer.contentWindow.map +1 -0
  85. data/assets/themes/j1/extensions/iframeResizer/js/client/iframeResizer.contentWindow.min.js +10 -0
  86. data/assets/themes/j1/extensions/iframeResizer/js/iframeResizer.js +1390 -0
  87. data/assets/themes/j1/extensions/iframeResizer/js/iframeResizer.map +1 -0
  88. data/assets/themes/j1/extensions/iframeResizer/js/iframeResizer.min.js +9 -0
  89. data/assets/themes/j1/extensions/jqMouseWheel/README.md +76 -0
  90. data/assets/themes/j1/extensions/jqMouseWheel/js/jquery.mousewheel.js +221 -0
  91. data/assets/themes/j1/extensions/jqMouseWheel/js/jquery.mousewheel.min.js +9 -0
  92. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/LICENSE +0 -0
  93. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/README.md +0 -0
  94. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/css/justifiedGallery.css +0 -0
  95. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/css/justifiedGallery.min.css +0 -0
  96. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/css/theme/uno.css +0 -0
  97. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/js/justifiedGallery.3.7.0.js +0 -0
  98. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/js/justifiedGallery.js +0 -0
  99. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/js/justifiedGallery.min.js +0 -0
  100. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/less/.csslintrc +0 -0
  101. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v3.7.0/less/justifiedGallery.less +0 -0
  102. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v4.0.0/css/justifiedGallery.css +0 -0
  103. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v4.0.0/css/justifiedGallery.min.css +0 -0
  104. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v4.0.0/css/theme/uno.css +0 -0
  105. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v4.0.0/js/jquery.justifiedGallery.js +0 -0
  106. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/_versions/v4.0.0/js/jquery.justifiedGallery.min.js +0 -0
  107. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/css/justifiedGallery.css +0 -0
  108. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/css/justifiedGallery.min.css +0 -0
  109. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/css/theme/uno.css +0 -0
  110. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/css/theme/uno.min.css +0 -0
  111. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/js/justifiedGallery.js +0 -0
  112. data/assets/themes/j1/extensions/{justified_gallery → justifiedGallery}/js/justifiedGallery.min.js +0 -0
  113. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/core/lg-fb-comment-box.css +0 -0
  114. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/core/lg-fb-comment-box.min.css +0 -0
  115. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/core/lg-transitions.css +0 -0
  116. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/core/lg-transitions.min.css +0 -0
  117. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/core/lightgallery.css +0 -0
  118. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/core/lightgallery.min.css +0 -0
  119. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/fonts/lg.eot +0 -0
  120. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/fonts/lg.svg +0 -0
  121. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/fonts/lg.ttf +0 -0
  122. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/fonts/lg.woff +0 -0
  123. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/img/loading.gif +0 -0
  124. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/img/video-play.png +0 -0
  125. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/img/vimeo-play.png +0 -0
  126. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/img/youtube-play.png +0 -0
  127. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/animation-w.png +0 -0
  128. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/customize-w.png +0 -0
  129. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/dynamic-w.png +0 -0
  130. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/facebook-icon.svg +0 -0
  131. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/googleplus-icon.svg +0 -0
  132. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/html5-w.png +0 -0
  133. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/linked-in.png +0 -0
  134. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/module-w.png +0 -0
  135. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/play-button.png +0 -0
  136. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/responsive-w.png +0 -0
  137. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/thumb-w.png +0 -0
  138. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/touch-w.png +0 -0
  139. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/twitter-icon.svg +0 -0
  140. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/twitter.png +0 -0
  141. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/video1-w.png +0 -0
  142. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/zoom-w.png +0 -0
  143. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/icons/zoom.png +0 -0
  144. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/uno.css +1 -1
  145. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/css/themes/uno.min.css +1 -1
  146. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/core/lightgallery.js +0 -0
  147. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/core/lightgallery.min.js +0 -0
  148. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/j1/j1-video.js +0 -0
  149. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/j1/j1-video.min.js +0 -0
  150. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-autoplay.js +0 -0
  151. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-autoplay.min.js +0 -0
  152. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-fullscreen.js +0 -0
  153. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-fullscreen.min.js +0 -0
  154. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-hash.js +0 -0
  155. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-hash.min.js +0 -0
  156. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-pager.js +0 -0
  157. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-pager.min.js +0 -0
  158. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-share.js +0 -0
  159. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-share.min.js +0 -0
  160. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-thumbnail.js +0 -0
  161. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-thumbnail.min.js +0 -0
  162. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-video.js +0 -0
  163. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-video.min.js +0 -0
  164. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-zoom.js +0 -0
  165. data/assets/themes/j1/extensions/{light_gallery → lightGallery}/js/modules/lg-zoom.min.js +0 -0
  166. data/assets/themes/j1/extensions/lightbox/LICENSE +22 -0
  167. data/assets/themes/j1/extensions/lightbox/css/lightbox.css +224 -0
  168. data/assets/themes/j1/extensions/lightbox/css/lightbox.min.css +21 -0
  169. data/assets/themes/j1/extensions/lightbox/css/theme/uno.css +25 -0
  170. data/assets/themes/j1/extensions/lightbox/css/theme/uno.min.css +26 -0
  171. data/{lib/starter_web/assets/images/modules/lightbox → assets/themes/j1/extensions/lightbox/images}/close.png +0 -0
  172. data/{lib/starter_web/assets/images/modules/lightbox → assets/themes/j1/extensions/lightbox/images}/loading.gif +0 -0
  173. data/{lib/starter_web/assets/images/modules/lightbox → assets/themes/j1/extensions/lightbox/images}/next.png +0 -0
  174. data/{lib/starter_web/assets/images/modules/lightbox → assets/themes/j1/extensions/lightbox/images}/prev.png +0 -0
  175. data/assets/themes/j1/extensions/lightbox/js/lightbox.js +583 -0
  176. data/assets/themes/j1/extensions/lightbox/js/lightbox.min.js +35 -0
  177. data/assets/themes/j1/extensions/mmenuLight/css/mmenu.css +392 -0
  178. data/assets/themes/j1/extensions/mmenuLight/css/mmenu.min.css +393 -0
  179. data/assets/themes/j1/extensions/mmenuLight/css/theme/uno.css +170 -0
  180. data/assets/themes/j1/extensions/mmenuLight/css/theme/uno.min.css +169 -0
  181. data/assets/themes/j1/extensions/mmenuLight/js/mmenu.js +30 -0
  182. data/assets/themes/j1/extensions/noUISlider/LICENSE +13 -0
  183. data/assets/themes/j1/extensions/noUISlider/css/nouislider.css +260 -0
  184. data/assets/themes/j1/extensions/noUISlider/css/nouislider.min.css +1 -0
  185. data/assets/themes/j1/extensions/noUISlider/js/nouislider.js +2312 -0
  186. data/assets/themes/j1/extensions/noUISlider/js/nouislider.min.js +3 -0
  187. data/assets/themes/j1/extensions/twemoji/js/LICENSE +21 -0
  188. data/assets/themes/j1/extensions/twemoji/js/picker/LICENSE +21 -0
  189. data/assets/themes/j1/extensions/twemoji/js/picker/twemoji-picker.js +21 -0
  190. data/assets/themes/j1/extensions/twemoji/js/picker/twemoji-picker.min.js +21 -0
  191. data/assets/themes/j1/extensions/twemoji/js/twemoji.js +590 -0
  192. data/assets/themes/j1/extensions/twemoji/js/twemoji.min.js +25 -0
  193. data/lib/j1/version.rb +1 -1
  194. data/lib/starter_web/Gemfile +7 -1
  195. data/lib/starter_web/_config.yml +9 -8
  196. data/lib/starter_web/_data/_defaults/resources.yml +13 -13
  197. data/lib/starter_web/_data/blocks/banner.yml +21 -29
  198. data/lib/starter_web/_data/blocks/footer.yml +10 -3
  199. data/lib/starter_web/_data/blocks/panel.yml +13 -13
  200. data/lib/starter_web/_data/layouts/default.yml +10 -0
  201. data/lib/starter_web/_data/layouts/home.yml +7 -7
  202. data/lib/starter_web/_data/layouts/page.yml +15 -16
  203. data/lib/starter_web/_data/modules/advertising.yml +48 -0
  204. data/lib/starter_web/_data/modules/attics.yml +2 -38
  205. data/lib/starter_web/_data/modules/cookie_consent.yml +3 -95
  206. data/lib/starter_web/_data/modules/defaults/attics.yml +16 -15
  207. data/lib/starter_web/_data/modules/defaults/cookie_consent.yml +75 -12
  208. data/lib/starter_web/_data/modules/defaults/jekyll_search.yml +9 -9
  209. data/lib/starter_web/_data/modules/defaults/navigator.yml +56 -21
  210. data/lib/starter_web/_data/modules/defaults/ssm.yml +3 -3
  211. data/lib/starter_web/_data/modules/defaults/toccer.yml +4 -8
  212. data/lib/starter_web/_data/modules/jekyll_search.yml +3 -21
  213. data/lib/starter_web/_data/modules/navigator.yml +1 -1
  214. data/lib/starter_web/_data/modules/navigator_menu.yml +4 -0
  215. data/lib/starter_web/_data/modules/ssm.yml +10 -1
  216. data/lib/starter_web/_data/modules/themer.yml +2 -3
  217. data/lib/starter_web/_data/modules/toccer.yml +7 -12
  218. data/lib/starter_web/_data/resources.yml +240 -112
  219. data/lib/starter_web/_data/template_settings.yml +109 -6
  220. data/lib/starter_web/_plugins/asciidoctor-extensions/fab-icon-inline.rb +1 -1
  221. data/lib/starter_web/_plugins/asciidoctor-extensions/fas-icon-inline.rb +2 -2
  222. data/lib/starter_web/_plugins/asciidoctor-extensions/iconify-icon-inline.rb +2 -2
  223. data/lib/starter_web/_plugins/asciidoctor-extensions/mdi-icon-inline.rb +2 -2
  224. data/lib/starter_web/_plugins/asciidoctor-extensions/twitter-emoji-inline.rb +2 -2
  225. data/lib/starter_web/_plugins/minifyJS.rb +54 -0
  226. data/lib/starter_web/_plugins/{uglify.rb → minifyJSON.rb} +15 -9
  227. data/lib/starter_web/assets/images/modules/attics/admin-dashboard-bootstrap-1280x600.jpg +0 -0
  228. data/lib/starter_web/assets/images/modules/attics/alex-holyoake-1920x1280.jpg +0 -0
  229. data/lib/starter_web/assets/images/modules/attics/anaya-katlego-1920x1280.jpg +0 -0
  230. data/lib/starter_web/assets/images/modules/attics/antonella-lombardi-1920x1280.jpg +0 -0
  231. data/lib/starter_web/assets/images/modules/attics/antonino-visalli-1920x1280.jpg +0 -0
  232. data/lib/starter_web/assets/images/modules/attics/banner/library-1920x800-bw.jpg +0 -0
  233. data/lib/starter_web/assets/images/modules/attics/banner/signpost-1920x800-bw.jpg +0 -0
  234. data/lib/starter_web/assets/images/modules/attics/banner/water-journal-1280x600.jpg +0 -0
  235. data/lib/starter_web/assets/images/modules/attics/banner/write-1280x600-bw.jpg +0 -0
  236. data/lib/starter_web/assets/images/modules/attics/brandon-mowinkel-1920x1280.jpg +0 -0
  237. data/lib/starter_web/assets/images/modules/attics/building-blocks-1920x1280-bw.jpg +0 -0
  238. data/lib/starter_web/assets/images/modules/attics/cookies-1920x1200-bw.jpg +0 -0
  239. data/lib/starter_web/assets/images/modules/attics/daniel-jensen-1920x1280.jpg +0 -0
  240. data/lib/starter_web/assets/images/modules/attics/giammarco-boscaro-1920x1280.jpg +0 -0
  241. data/lib/starter_web/assets/images/modules/attics/go-up-1920x1280-bw.jpg +0 -0
  242. data/lib/starter_web/assets/images/modules/attics/ian-schneider-1920x1280.jpg +0 -0
  243. data/lib/starter_web/assets/images/modules/attics/ideas-start-here-1920x1280-bw.jpg +0 -0
  244. data/lib/starter_web/assets/images/modules/attics/jason-rosewell-1920x1280.jpg +0 -0
  245. data/lib/starter_web/assets/images/modules/attics/jessica-ruscello-1920x1280.jpg +0 -0
  246. data/lib/starter_web/assets/images/modules/attics/lianhao-1920x1280.jpg +0 -0
  247. data/lib/starter_web/assets/images/modules/attics/library-1920x1280-bw.jpg +0 -0
  248. data/lib/starter_web/assets/images/modules/attics/matthaeus-1920x1280.jpg +0 -0
  249. data/lib/starter_web/assets/images/modules/attics/nousnou-iwasaki-1920x1280.jpg +0 -0
  250. data/lib/starter_web/assets/images/modules/attics/premium-1920x1280-bw.jpg +0 -0
  251. data/lib/starter_web/assets/images/modules/attics/robert-v-ruggiero-1920x1280.jpg +0 -0
  252. data/lib/starter_web/assets/images/modules/attics/romain-vignes-1920x1280.jpg +0 -0
  253. data/lib/starter_web/assets/images/modules/attics/runner-1920x1200-bw.jpg +0 -0
  254. data/lib/starter_web/assets/images/modules/attics/spider-web-1920x1200-bw.jpg +0 -0
  255. data/lib/starter_web/assets/images/modules/attics/the-place-1920x1280-bw.jpg +0 -0
  256. data/lib/starter_web/assets/images/modules/attics/welcome-1920x1280-bw.jpg +0 -0
  257. data/lib/starter_web/assets/images/modules/carousel/cats/cat-1.jpg +0 -0
  258. data/lib/starter_web/assets/images/modules/carousel/mega_cities/andreas-brucker_b.jpg +0 -0
  259. data/lib/starter_web/assets/images/modules/carousel/mega_cities/denys-nevozhai-1_b.jpg +0 -0
  260. data/lib/starter_web/assets/images/modules/carousel/mega_cities/denys-nevozhai-2_b.jpg +0 -0
  261. data/lib/starter_web/assets/images/modules/carousel/mega_cities/luca-bravo_b.jpg +0 -0
  262. data/lib/starter_web/assets/images/modules/carousel/mega_cities/thomas-tucker_b.jpg +0 -0
  263. data/lib/starter_web/assets/images/modules/gallery/mega_cities/banter-snaps_b.jpg +0 -0
  264. data/lib/starter_web/assets/images/modules/gallery/mega_cities/denys-nevozhai-1_b.jpg +0 -0
  265. data/lib/starter_web/assets/images/modules/gallery/mega_cities/denys-nevozhai-2-bw.jpg +0 -0
  266. data/lib/starter_web/assets/images/modules/gallery/mega_cities/denys-nevozhai-2_b.jpg +0 -0
  267. data/lib/starter_web/assets/images/modules/gallery/mega_cities/emmad-mazhari_b.jpg +0 -0
  268. data/lib/starter_web/assets/images/modules/gallery/mega_cities/ethan-brooke_b.jpg +0 -0
  269. data/lib/starter_web/assets/images/modules/gallery/mega_cities/federico-rizzarelli_b.jpg +0 -0
  270. data/lib/starter_web/assets/images/modules/gallery/mega_cities/gints-gailis_b.jpg +0 -0
  271. data/lib/starter_web/assets/images/modules/gallery/mega_cities/johan-mouchet_b.jpg +0 -0
  272. data/lib/starter_web/assets/images/modules/gallery/mega_cities/luca-bravo_b.jpg +0 -0
  273. data/lib/starter_web/assets/images/modules/gallery/mega_cities/oskars-sylwan_b.jpg +0 -0
  274. data/lib/starter_web/assets/images/modules/gallery/mega_cities/steven-diaz_b.jpg +0 -0
  275. data/lib/starter_web/assets/images/modules/gallery/mega_cities/thomas-tucker-bw.jpg +0 -0
  276. data/lib/starter_web/assets/images/modules/gallery/mega_cities/thomas-tucker_b.jpg +0 -0
  277. data/lib/starter_web/index.html +9 -8
  278. data/lib/starter_web/package.json +1 -1
  279. data/lib/starter_web/pages/public/clear_button.adoc +121 -0
  280. data/lib/starter_web/pages/public/learn/examples/floating_ad.adoc +221 -0
  281. data/lib/starter_web/pages/public/learn/{floating_sidebar.adoc → examples/floating_div.adoc} +60 -50
  282. data/lib/starter_web/pages/public/learn/kickstarter/web_in_a_day/000_includes/parts.asciidoc +1 -1
  283. data/lib/starter_web/pages/public/learn/kickstarter/web_in_a_day/100_meet_and_greet_jekyll.adoc +9 -4
  284. data/lib/starter_web/pages/public/learn/roundtrip/000_bs_tour_api.adoc +2 -2
  285. data/lib/starter_web/pages/public/learn/roundtrip/000_includes/documents/410_table_3_column.asciidoc +1 -1
  286. data/lib/starter_web/pages/public/learn/roundtrip/000_includes/documents/419_advanced_modals_html.asciidoc +5 -5
  287. data/lib/starter_web/pages/public/learn/roundtrip/100_present_images.adoc +2 -2
  288. data/lib/starter_web/pages/public/learn/roundtrip/200_typography.adoc +8 -3
  289. data/lib/starter_web/pages/public/learn/roundtrip/300_icon_fonts.adoc +35 -44
  290. data/lib/starter_web/pages/public/learn/roundtrip/400_asciidoc_extensions.adoc +1 -1
  291. data/lib/starter_web/pages/public/learn/roundtrip/420_responsive_tables_extensions.adoc +39 -39
  292. data/lib/starter_web/pages/public/learn/vtutorials/000_includes/documents/410_table_3_column.asciidoc +1 -1
  293. data/lib/starter_web/pages/public/learn/whats_up.adoc +1 -0
  294. data/lib/starter_web/pages/public/panels/intro_panel/panel.adoc +54 -48
  295. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/100_absolute_sizes.asciidoc +1 -1
  296. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/110_bs_grid_sizes.asciidoc +1 -1
  297. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/120_relative_sizes.asciidoc +1 -41
  298. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/200_rotate.asciidoc +1 -1
  299. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/300_flip.asciidoc +1 -1
  300. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/400_spin_pulsed.asciidoc +1 -1
  301. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/500_bw_color_palette.asciidoc +1 -1
  302. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/510_bs_color_palette.asciidoc +1 -1
  303. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/600_md_color_palette.asciidoc +1 -1
  304. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/601_md_color_palette_indigo.asciidoc +1 -1
  305. data/lib/starter_web/pages/public/previewer/000_includes/tables/mdi_icons/602_md_color_palette_pink.asciidoc +1 -1
  306. data/lib/starter_web/pages/public/previewer/000_includes/tables/twitter_emoji/100_bs_sizes.asciidoc +1 -1
  307. data/lib/starter_web/pages/public/previewer/000_includes/tables/twitter_emoji/100_relative_sizes.asciidoc +1 -1
  308. data/lib/starter_web/pages/public/previewer/000_includes/tables/twitter_emoji/200_rotate.asciidoc +1 -1
  309. data/lib/starter_web/pages/public/previewer/000_includes/tables/twitter_emoji/300_flip.asciidoc +1 -1
  310. data/lib/starter_web/pages/public/previewer/000_includes/tables/twitter_emoji/400_spin_pulsed.asciidoc +1 -1
  311. data/lib/starter_web/pages/public/previewer/bootstrap_theme.adoc +672 -863
  312. data/lib/starter_web/pages/public/previewer/iframer.adoc +15 -14
  313. data/lib/starter_web/pages/public/previewer/justified_gallery.html +1 -1
  314. data/lib/starter_web/pages/public/previewer/mdb_preview/000_includes/attributes.asciidoc +69 -0
  315. data/lib/starter_web/pages/public/previewer/mdb_preview/000_includes/documents/100_buttons.asciidoc +170 -0
  316. data/lib/starter_web/pages/public/previewer/mdb_preview/mdb_previewer.adoc +52 -0
  317. data/lib/starter_web/pages/public/previewer/mdi_icons_preview.adoc +1 -1
  318. data/lib/starter_web/pages/public/previewer/twitter_emoji_preview.adoc +2 -2
  319. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  320. data/lib/starter_web/utilsrv/package.json +1 -1
  321. metadata +148 -105
  322. data/assets/data/colors.json +0 -42
  323. data/assets/data/font_sizes.json +0 -42
  324. data/assets/data/messages.yml +0 -131
  325. data/assets/themes/j1/extensions/iframe_resizer/examples/frame.absolute.html +0 -86
  326. data/assets/themes/j1/extensions/iframe_resizer/examples/frame.content.html +0 -58
  327. data/assets/themes/j1/extensions/iframe_resizer/examples/frame.hover.html +0 -51
  328. data/assets/themes/j1/extensions/iframe_resizer/examples/frame.nested.html +0 -68
  329. data/assets/themes/j1/extensions/iframe_resizer/examples/frame.textarea.html +0 -46
  330. data/assets/themes/j1/extensions/iframe_resizer/examples/frame.tolerance.html +0 -79
  331. data/assets/themes/j1/extensions/iframe_resizer/examples/index.html +0 -70
  332. data/assets/themes/j1/extensions/iframe_resizer/examples/two.html +0 -71
  333. data/assets/themes/j1/extensions/iframe_resizer/js/client/iframeResizer.contentWindow.js +0 -1104
  334. data/assets/themes/j1/extensions/iframe_resizer/js/client/iframeResizer.contentWindow.map +0 -1
  335. data/assets/themes/j1/extensions/iframe_resizer/js/client/iframeResizer.contentWindow.min.js +0 -10
  336. data/assets/themes/j1/extensions/log4javascript/log4javascript.js +0 -5826
  337. data/assets/themes/j1/extensions/log4javascript/log4javascript.min.js +0 -266
  338. data/lib/starter_web/assets/images/modules/attics/admin-dashboard-bootstrap-1280x600.png +0 -0
  339. data/lib/starter_web/assets/images/modules/attics/mae-mu-Vf9gbsLZyf0-unsplash.jpg +0 -0
  340. data/lib/starter_web/assets/images/modules/attics/mae-mue-1920x1280-v.jpg +0 -0
  341. data/lib/starter_web/assets/images/modules/attics/mae-mue-1920x1280.jpg +0 -0
@@ -0,0 +1 @@
1
+ /*! nouislider - 10.1.0 - 2017-07-28 13:09:54 */.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;-ms-touch-action:none;touch-action:none;-ms-user-select:none;-moz-user-select:none;user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative;direction:ltr}.noUi-base{width:100%;height:100%;position:relative;z-index:1}.noUi-connect{position:absolute;right:0;top:0;left:0;bottom:0}.noUi-origin{position:absolute;height:0;width:0}.noUi-handle{position:relative;z-index:1}.noUi-state-tap .noUi-connect,.noUi-state-tap .noUi-origin{-webkit-transition:top .3s,right .3s,bottom .3s,left .3s;transition:top .3s,right .3s,bottom .3s,left .3s}.noUi-state-drag *{cursor:inherit!important}.noUi-base,.noUi-handle{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px}.noUi-target{background:#FAFAFA;border-radius:4px;border:1px solid #D3D3D3;box-shadow:inset 0 1px 1px #F0F0F0,0 3px 6px -5px #BBB}.noUi-connect{background:#3FB8AF;border-radius:4px;box-shadow:inset 0 0 3px rgba(51,51,51,.45);-webkit-transition:background 450ms;transition:background 450ms}.noUi-draggable{cursor:ew-resize}.noUi-vertical .noUi-draggable{cursor:ns-resize}.noUi-handle{border:1px solid #D9D9D9;border-radius:3px;background:#FFF;cursor:default;box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #EBEBEB,0 3px 6px -3px #BBB}.noUi-active{box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #DDD,0 3px 6px -3px #BBB}.noUi-handle:after,.noUi-handle:before{content:"";display:block;position:absolute;height:14px;width:1px;background:#E8E7E6;left:14px;top:6px}.noUi-handle:after{left:17px}.noUi-vertical .noUi-handle:after,.noUi-vertical .noUi-handle:before{width:14px;height:1px;left:6px;top:14px}.noUi-vertical .noUi-handle:after{top:17px}[disabled] .noUi-connect{background:#B8B8B8}[disabled] .noUi-handle,[disabled].noUi-handle,[disabled].noUi-target{cursor:not-allowed}.noUi-pips,.noUi-pips *{-moz-box-sizing:border-box;box-sizing:border-box}.noUi-pips{position:absolute;color:#999}.noUi-value{position:absolute;white-space:nowrap;text-align:center}.noUi-value-sub{color:#ccc;font-size:10px}.noUi-marker{position:absolute;background:#CCC}.noUi-marker-large,.noUi-marker-sub{background:#AAA}.noUi-pips-horizontal{padding:10px 0;height:80px;top:100%;left:0;width:100%}.noUi-value-horizontal{-webkit-transform:translate3d(-50%,50%,0);transform:translate3d(-50%,50%,0)}.noUi-marker-horizontal.noUi-marker{margin-left:-1px;width:2px;height:5px}.noUi-marker-horizontal.noUi-marker-sub{height:10px}.noUi-marker-horizontal.noUi-marker-large{height:15px}.noUi-pips-vertical{padding:0 10px;height:100%;top:0;left:100%}.noUi-value-vertical{-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0);padding-left:25px}.noUi-marker-vertical.noUi-marker{width:5px;height:2px;margin-top:-1px}.noUi-marker-vertical.noUi-marker-sub{width:10px}.noUi-marker-vertical.noUi-marker-large{width:15px}.noUi-tooltip{display:block;position:absolute;border:1px solid #D9D9D9;border-radius:3px;background:#fff;color:#000;padding:5px;text-align:center;white-space:nowrap}.noUi-horizontal .noUi-tooltip{-webkit-transform:translate(-50%,0);transform:translate(-50%,0);left:50%;bottom:120%}.noUi-vertical .noUi-tooltip{-webkit-transform:translate(0,-50%);transform:translate(0,-50%);top:50%;right:120%}
@@ -0,0 +1,2312 @@
1
+ /*! nouislider - 10.1.0 - 2017-07-28 17:11:18 */
2
+
3
+ (function (factory) {
4
+
5
+ if ( typeof define === 'function' && define.amd ) {
6
+
7
+ // AMD. Register as an anonymous module.
8
+ define([], factory);
9
+
10
+ } else if ( typeof exports === 'object' ) {
11
+
12
+ // Node/CommonJS
13
+ module.exports = factory();
14
+
15
+ } else {
16
+
17
+ // Browser globals
18
+ window.noUiSlider = factory();
19
+ }
20
+
21
+ }(function( ){
22
+
23
+ 'use strict';
24
+
25
+ var VERSION = '10.1.0';
26
+
27
+
28
+ function isValidFormatter ( entry ) {
29
+ return typeof entry === 'object' && typeof entry.to === 'function' && typeof entry.from === 'function';
30
+ }
31
+
32
+ function removeElement ( el ) {
33
+ el.parentElement.removeChild(el);
34
+ }
35
+
36
+ // Bindable version
37
+ function preventDefault ( e ) {
38
+ e.preventDefault();
39
+ }
40
+
41
+ // Removes duplicates from an array.
42
+ function unique ( array ) {
43
+ return array.filter(function(a){
44
+ return !this[a] ? this[a] = true : false;
45
+ }, {});
46
+ }
47
+
48
+ // Round a value to the closest 'to'.
49
+ function closest ( value, to ) {
50
+ return Math.round(value / to) * to;
51
+ }
52
+
53
+ // Current position of an element relative to the document.
54
+ function offset ( elem, orientation ) {
55
+
56
+ var rect = elem.getBoundingClientRect();
57
+ var doc = elem.ownerDocument;
58
+ var docElem = doc.documentElement;
59
+ var pageOffset = getPageOffset(doc);
60
+
61
+ // getBoundingClientRect contains left scroll in Chrome on Android.
62
+ // I haven't found a feature detection that proves this. Worst case
63
+ // scenario on mis-match: the 'tap' feature on horizontal sliders breaks.
64
+ if ( /webkit.*Chrome.*Mobile/i.test(navigator.userAgent) ) {
65
+ pageOffset.x = 0;
66
+ }
67
+
68
+ return orientation ? (rect.top + pageOffset.y - docElem.clientTop) : (rect.left + pageOffset.x - docElem.clientLeft);
69
+ }
70
+
71
+ // Checks whether a value is numerical.
72
+ function isNumeric ( a ) {
73
+ return typeof a === 'number' && !isNaN( a ) && isFinite( a );
74
+ }
75
+
76
+ // Sets a class and removes it after [duration] ms.
77
+ function addClassFor ( element, className, duration ) {
78
+ if (duration > 0) {
79
+ addClass(element, className);
80
+ setTimeout(function(){
81
+ removeClass(element, className);
82
+ }, duration);
83
+ }
84
+ }
85
+
86
+ // Limits a value to 0 - 100
87
+ function limit ( a ) {
88
+ return Math.max(Math.min(a, 100), 0);
89
+ }
90
+
91
+ // Wraps a variable as an array, if it isn't one yet.
92
+ // Note that an input array is returned by reference!
93
+ function asArray ( a ) {
94
+ return Array.isArray(a) ? a : [a];
95
+ }
96
+
97
+ // Counts decimals
98
+ function countDecimals ( numStr ) {
99
+ numStr = String(numStr);
100
+ var pieces = numStr.split(".");
101
+ return pieces.length > 1 ? pieces[1].length : 0;
102
+ }
103
+
104
+ // http://youmightnotneedjquery.com/#add_class
105
+ function addClass ( el, className ) {
106
+ if ( el.classList ) {
107
+ el.classList.add(className);
108
+ } else {
109
+ el.className += ' ' + className;
110
+ }
111
+ }
112
+
113
+ // http://youmightnotneedjquery.com/#remove_class
114
+ function removeClass ( el, className ) {
115
+ if ( el.classList ) {
116
+ el.classList.remove(className);
117
+ } else {
118
+ el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
119
+ }
120
+ }
121
+
122
+ // https://plainjs.com/javascript/attributes/adding-removing-and-testing-for-classes-9/
123
+ function hasClass ( el, className ) {
124
+ return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className);
125
+ }
126
+
127
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY#Notes
128
+ function getPageOffset ( doc ) {
129
+
130
+ var supportPageOffset = window.pageXOffset !== undefined;
131
+ var isCSS1Compat = ((doc.compatMode || "") === "CSS1Compat");
132
+ var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? doc.documentElement.scrollLeft : doc.body.scrollLeft;
133
+ var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? doc.documentElement.scrollTop : doc.body.scrollTop;
134
+
135
+ return {
136
+ x: x,
137
+ y: y
138
+ };
139
+ }
140
+
141
+ // we provide a function to compute constants instead
142
+ // of accessing window.* as soon as the module needs it
143
+ // so that we do not compute anything if not needed
144
+ function getActions ( ) {
145
+
146
+ // Determine the events to bind. IE11 implements pointerEvents without
147
+ // a prefix, which breaks compatibility with the IE10 implementation.
148
+ return window.navigator.pointerEnabled ? {
149
+ start: 'pointerdown',
150
+ move: 'pointermove',
151
+ end: 'pointerup'
152
+ } : window.navigator.msPointerEnabled ? {
153
+ start: 'MSPointerDown',
154
+ move: 'MSPointerMove',
155
+ end: 'MSPointerUp'
156
+ } : {
157
+ start: 'mousedown touchstart',
158
+ move: 'mousemove touchmove',
159
+ end: 'mouseup touchend'
160
+ };
161
+ }
162
+
163
+ // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
164
+ // Issue #785
165
+ function getSupportsPassive ( ) {
166
+
167
+ var supportsPassive = false;
168
+
169
+ try {
170
+
171
+ var opts = Object.defineProperty({}, 'passive', {
172
+ get: function() {
173
+ supportsPassive = true;
174
+ }
175
+ });
176
+
177
+ window.addEventListener('test', null, opts);
178
+
179
+ } catch (e) {}
180
+
181
+ return supportsPassive;
182
+ }
183
+
184
+ function getSupportsTouchActionNone ( ) {
185
+ return window.CSS && CSS.supports && CSS.supports('touch-action', 'none');
186
+ }
187
+
188
+
189
+ // Value calculation
190
+
191
+ // Determine the size of a sub-range in relation to a full range.
192
+ function subRangeRatio ( pa, pb ) {
193
+ return (100 / (pb - pa));
194
+ }
195
+
196
+ // (percentage) How many percent is this value of this range?
197
+ function fromPercentage ( range, value ) {
198
+ return (value * 100) / ( range[1] - range[0] );
199
+ }
200
+
201
+ // (percentage) Where is this value on this range?
202
+ function toPercentage ( range, value ) {
203
+ return fromPercentage( range, range[0] < 0 ?
204
+ value + Math.abs(range[0]) :
205
+ value - range[0] );
206
+ }
207
+
208
+ // (value) How much is this percentage on this range?
209
+ function isPercentage ( range, value ) {
210
+ return ((value * ( range[1] - range[0] )) / 100) + range[0];
211
+ }
212
+
213
+
214
+ // Range conversion
215
+
216
+ function getJ ( value, arr ) {
217
+
218
+ var j = 1;
219
+
220
+ while ( value >= arr[j] ){
221
+ j += 1;
222
+ }
223
+
224
+ return j;
225
+ }
226
+
227
+ // (percentage) Input a value, find where, on a scale of 0-100, it applies.
228
+ function toStepping ( xVal, xPct, value ) {
229
+
230
+ if ( value >= xVal.slice(-1)[0] ){
231
+ return 100;
232
+ }
233
+
234
+ var j = getJ( value, xVal ), va, vb, pa, pb;
235
+
236
+ va = xVal[j-1];
237
+ vb = xVal[j];
238
+ pa = xPct[j-1];
239
+ pb = xPct[j];
240
+
241
+ return pa + (toPercentage([va, vb], value) / subRangeRatio (pa, pb));
242
+ }
243
+
244
+ // (value) Input a percentage, find where it is on the specified range.
245
+ function fromStepping ( xVal, xPct, value ) {
246
+
247
+ // There is no range group that fits 100
248
+ if ( value >= 100 ){
249
+ return xVal.slice(-1)[0];
250
+ }
251
+
252
+ var j = getJ( value, xPct ), va, vb, pa, pb;
253
+
254
+ va = xVal[j-1];
255
+ vb = xVal[j];
256
+ pa = xPct[j-1];
257
+ pb = xPct[j];
258
+
259
+ return isPercentage([va, vb], (value - pa) * subRangeRatio (pa, pb));
260
+ }
261
+
262
+ // (percentage) Get the step that applies at a certain value.
263
+ function getStep ( xPct, xSteps, snap, value ) {
264
+
265
+ if ( value === 100 ) {
266
+ return value;
267
+ }
268
+
269
+ var j = getJ( value, xPct ), a, b;
270
+
271
+ // If 'snap' is set, steps are used as fixed points on the slider.
272
+ if ( snap ) {
273
+
274
+ a = xPct[j-1];
275
+ b = xPct[j];
276
+
277
+ // Find the closest position, a or b.
278
+ if ((value - a) > ((b-a)/2)){
279
+ return b;
280
+ }
281
+
282
+ return a;
283
+ }
284
+
285
+ if ( !xSteps[j-1] ){
286
+ return value;
287
+ }
288
+
289
+ return xPct[j-1] + closest(
290
+ value - xPct[j-1],
291
+ xSteps[j-1]
292
+ );
293
+ }
294
+
295
+
296
+ // Entry parsing
297
+
298
+ function handleEntryPoint ( index, value, that ) {
299
+
300
+ var percentage;
301
+
302
+ // Wrap numerical input in an array.
303
+ if ( typeof value === "number" ) {
304
+ value = [value];
305
+ }
306
+
307
+ // Reject any invalid input, by testing whether value is an array.
308
+ if ( Object.prototype.toString.call( value ) !== '[object Array]' ){
309
+ throw new Error("noUiSlider (" + VERSION + "): 'range' contains invalid value.");
310
+ }
311
+
312
+ // Covert min/max syntax to 0 and 100.
313
+ if ( index === 'min' ) {
314
+ percentage = 0;
315
+ } else if ( index === 'max' ) {
316
+ percentage = 100;
317
+ } else {
318
+ percentage = parseFloat( index );
319
+ }
320
+
321
+ // Check for correct input.
322
+ if ( !isNumeric( percentage ) || !isNumeric( value[0] ) ) {
323
+ throw new Error("noUiSlider (" + VERSION + "): 'range' value isn't numeric.");
324
+ }
325
+
326
+ // Store values.
327
+ that.xPct.push( percentage );
328
+ that.xVal.push( value[0] );
329
+
330
+ // NaN will evaluate to false too, but to keep
331
+ // logging clear, set step explicitly. Make sure
332
+ // not to override the 'step' setting with false.
333
+ if ( !percentage ) {
334
+ if ( !isNaN( value[1] ) ) {
335
+ that.xSteps[0] = value[1];
336
+ }
337
+ } else {
338
+ that.xSteps.push( isNaN(value[1]) ? false : value[1] );
339
+ }
340
+
341
+ that.xHighestCompleteStep.push(0);
342
+ }
343
+
344
+ function handleStepPoint ( i, n, that ) {
345
+
346
+ // Ignore 'false' stepping.
347
+ if ( !n ) {
348
+ return true;
349
+ }
350
+
351
+ // Factor to range ratio
352
+ that.xSteps[i] = fromPercentage([
353
+ that.xVal[i]
354
+ ,that.xVal[i+1]
355
+ ], n) / subRangeRatio (
356
+ that.xPct[i],
357
+ that.xPct[i+1] );
358
+
359
+ var totalSteps = (that.xVal[i+1] - that.xVal[i]) / that.xNumSteps[i];
360
+ var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1);
361
+ var step = that.xVal[i] + (that.xNumSteps[i] * highestStep);
362
+
363
+ that.xHighestCompleteStep[i] = step;
364
+ }
365
+
366
+
367
+ // Interface
368
+
369
+ function Spectrum ( entry, snap, singleStep ) {
370
+
371
+ this.xPct = [];
372
+ this.xVal = [];
373
+ this.xSteps = [ singleStep || false ];
374
+ this.xNumSteps = [ false ];
375
+ this.xHighestCompleteStep = [];
376
+
377
+ this.snap = snap;
378
+
379
+ var index, ordered = [ /* [0, 'min'], [1, '50%'], [2, 'max'] */ ];
380
+
381
+ // Map the object keys to an array.
382
+ for ( index in entry ) {
383
+ if ( entry.hasOwnProperty(index) ) {
384
+ ordered.push([entry[index], index]);
385
+ }
386
+ }
387
+
388
+ // Sort all entries by value (numeric sort).
389
+ if ( ordered.length && typeof ordered[0][0] === "object" ) {
390
+ ordered.sort(function(a, b) { return a[0][0] - b[0][0]; });
391
+ } else {
392
+ ordered.sort(function(a, b) { return a[0] - b[0]; });
393
+ }
394
+
395
+
396
+ // Convert all entries to subranges.
397
+ for ( index = 0; index < ordered.length; index++ ) {
398
+ handleEntryPoint(ordered[index][1], ordered[index][0], this);
399
+ }
400
+
401
+ // Store the actual step values.
402
+ // xSteps is sorted in the same order as xPct and xVal.
403
+ this.xNumSteps = this.xSteps.slice(0);
404
+
405
+ // Convert all numeric steps to the percentage of the subrange they represent.
406
+ for ( index = 0; index < this.xNumSteps.length; index++ ) {
407
+ handleStepPoint(index, this.xNumSteps[index], this);
408
+ }
409
+ }
410
+
411
+ Spectrum.prototype.getMargin = function ( value ) {
412
+
413
+ var step = this.xNumSteps[0];
414
+
415
+ if ( step && ((value / step) % 1) !== 0 ) {
416
+ throw new Error("noUiSlider (" + VERSION + "): 'limit', 'margin' and 'padding' must be divisible by step.");
417
+ }
418
+
419
+ return this.xPct.length === 2 ? fromPercentage(this.xVal, value) : false;
420
+ };
421
+
422
+ Spectrum.prototype.toStepping = function ( value ) {
423
+
424
+ value = toStepping( this.xVal, this.xPct, value );
425
+
426
+ return value;
427
+ };
428
+
429
+ Spectrum.prototype.fromStepping = function ( value ) {
430
+
431
+ return fromStepping( this.xVal, this.xPct, value );
432
+ };
433
+
434
+ Spectrum.prototype.getStep = function ( value ) {
435
+
436
+ value = getStep(this.xPct, this.xSteps, this.snap, value );
437
+
438
+ return value;
439
+ };
440
+
441
+ Spectrum.prototype.getNearbySteps = function ( value ) {
442
+
443
+ var j = getJ(value, this.xPct);
444
+
445
+ return {
446
+ stepBefore: { startValue: this.xVal[j-2], step: this.xNumSteps[j-2], highestStep: this.xHighestCompleteStep[j-2] },
447
+ thisStep: { startValue: this.xVal[j-1], step: this.xNumSteps[j-1], highestStep: this.xHighestCompleteStep[j-1] },
448
+ stepAfter: { startValue: this.xVal[j-0], step: this.xNumSteps[j-0], highestStep: this.xHighestCompleteStep[j-0] }
449
+ };
450
+ };
451
+
452
+ Spectrum.prototype.countStepDecimals = function () {
453
+ var stepDecimals = this.xNumSteps.map(countDecimals);
454
+ return Math.max.apply(null, stepDecimals);
455
+ };
456
+
457
+ // Outside testing
458
+ Spectrum.prototype.convert = function ( value ) {
459
+ return this.getStep(this.toStepping(value));
460
+ };
461
+
462
+ /* Every input option is tested and parsed. This'll prevent
463
+ endless validation in internal methods. These tests are
464
+ structured with an item for every option available. An
465
+ option can be marked as required by setting the 'r' flag.
466
+ The testing function is provided with three arguments:
467
+ - The provided value for the option;
468
+ - A reference to the options object;
469
+ - The name for the option;
470
+
471
+ The testing function returns false when an error is detected,
472
+ or true when everything is OK. It can also modify the option
473
+ object, to make sure all values can be correctly looped elsewhere. */
474
+
475
+ var defaultFormatter = { 'to': function( value ){
476
+ return value !== undefined && value.toFixed(2);
477
+ }, 'from': Number };
478
+
479
+ function validateFormat ( entry ) {
480
+
481
+ // Any object with a to and from method is supported.
482
+ if ( isValidFormatter(entry) ) {
483
+ return true;
484
+ }
485
+
486
+ throw new Error("noUiSlider (" + VERSION + "): 'format' requires 'to' and 'from' methods.");
487
+ }
488
+
489
+ function testStep ( parsed, entry ) {
490
+
491
+ if ( !isNumeric( entry ) ) {
492
+ throw new Error("noUiSlider (" + VERSION + "): 'step' is not numeric.");
493
+ }
494
+
495
+ // The step option can still be used to set stepping
496
+ // for linear sliders. Overwritten if set in 'range'.
497
+ parsed.singleStep = entry;
498
+ }
499
+
500
+ function testRange ( parsed, entry ) {
501
+
502
+ // Filter incorrect input.
503
+ if ( typeof entry !== 'object' || Array.isArray(entry) ) {
504
+ throw new Error("noUiSlider (" + VERSION + "): 'range' is not an object.");
505
+ }
506
+
507
+ // Catch missing start or end.
508
+ if ( entry.min === undefined || entry.max === undefined ) {
509
+ throw new Error("noUiSlider (" + VERSION + "): Missing 'min' or 'max' in 'range'.");
510
+ }
511
+
512
+ // Catch equal start or end.
513
+ if ( entry.min === entry.max ) {
514
+ throw new Error("noUiSlider (" + VERSION + "): 'range' 'min' and 'max' cannot be equal.");
515
+ }
516
+
517
+ parsed.spectrum = new Spectrum(entry, parsed.snap, parsed.singleStep);
518
+ }
519
+
520
+ function testStart ( parsed, entry ) {
521
+
522
+ entry = asArray(entry);
523
+
524
+ // Validate input. Values aren't tested, as the public .val method
525
+ // will always provide a valid location.
526
+ if ( !Array.isArray( entry ) || !entry.length ) {
527
+ throw new Error("noUiSlider (" + VERSION + "): 'start' option is incorrect.");
528
+ }
529
+
530
+ // Store the number of handles.
531
+ parsed.handles = entry.length;
532
+
533
+ // When the slider is initialized, the .val method will
534
+ // be called with the start options.
535
+ parsed.start = entry;
536
+ }
537
+
538
+ function testSnap ( parsed, entry ) {
539
+
540
+ // Enforce 100% stepping within subranges.
541
+ parsed.snap = entry;
542
+
543
+ if ( typeof entry !== 'boolean' ){
544
+ throw new Error("noUiSlider (" + VERSION + "): 'snap' option must be a boolean.");
545
+ }
546
+ }
547
+
548
+ function testAnimate ( parsed, entry ) {
549
+
550
+ // Enforce 100% stepping within subranges.
551
+ parsed.animate = entry;
552
+
553
+ if ( typeof entry !== 'boolean' ){
554
+ throw new Error("noUiSlider (" + VERSION + "): 'animate' option must be a boolean.");
555
+ }
556
+ }
557
+
558
+ function testAnimationDuration ( parsed, entry ) {
559
+
560
+ parsed.animationDuration = entry;
561
+
562
+ if ( typeof entry !== 'number' ){
563
+ throw new Error("noUiSlider (" + VERSION + "): 'animationDuration' option must be a number.");
564
+ }
565
+ }
566
+
567
+ function testConnect ( parsed, entry ) {
568
+
569
+ var connect = [false];
570
+ var i;
571
+
572
+ // Map legacy options
573
+ if ( entry === 'lower' ) {
574
+ entry = [true, false];
575
+ }
576
+
577
+ else if ( entry === 'upper' ) {
578
+ entry = [false, true];
579
+ }
580
+
581
+ // Handle boolean options
582
+ if ( entry === true || entry === false ) {
583
+
584
+ for ( i = 1; i < parsed.handles; i++ ) {
585
+ connect.push(entry);
586
+ }
587
+
588
+ connect.push(false);
589
+ }
590
+
591
+ // Reject invalid input
592
+ else if ( !Array.isArray( entry ) || !entry.length || entry.length !== parsed.handles + 1 ) {
593
+ throw new Error("noUiSlider (" + VERSION + "): 'connect' option doesn't match handle count.");
594
+ }
595
+
596
+ else {
597
+ connect = entry;
598
+ }
599
+
600
+ parsed.connect = connect;
601
+ }
602
+
603
+ function testOrientation ( parsed, entry ) {
604
+
605
+ // Set orientation to an a numerical value for easy
606
+ // array selection.
607
+ switch ( entry ){
608
+ case 'horizontal':
609
+ parsed.ort = 0;
610
+ break;
611
+ case 'vertical':
612
+ parsed.ort = 1;
613
+ break;
614
+ default:
615
+ throw new Error("noUiSlider (" + VERSION + "): 'orientation' option is invalid.");
616
+ }
617
+ }
618
+
619
+ function testMargin ( parsed, entry ) {
620
+
621
+ if ( !isNumeric(entry) ){
622
+ throw new Error("noUiSlider (" + VERSION + "): 'margin' option must be numeric.");
623
+ }
624
+
625
+ // Issue #582
626
+ if ( entry === 0 ) {
627
+ return;
628
+ }
629
+
630
+ parsed.margin = parsed.spectrum.getMargin(entry);
631
+
632
+ if ( !parsed.margin ) {
633
+ throw new Error("noUiSlider (" + VERSION + "): 'margin' option is only supported on linear sliders.");
634
+ }
635
+ }
636
+
637
+ function testLimit ( parsed, entry ) {
638
+
639
+ if ( !isNumeric(entry) ){
640
+ throw new Error("noUiSlider (" + VERSION + "): 'limit' option must be numeric.");
641
+ }
642
+
643
+ parsed.limit = parsed.spectrum.getMargin(entry);
644
+
645
+ if ( !parsed.limit || parsed.handles < 2 ) {
646
+ throw new Error("noUiSlider (" + VERSION + "): 'limit' option is only supported on linear sliders with 2 or more handles.");
647
+ }
648
+ }
649
+
650
+ function testPadding ( parsed, entry ) {
651
+
652
+ if ( !isNumeric(entry) ){
653
+ throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be numeric.");
654
+ }
655
+
656
+ if ( entry === 0 ) {
657
+ return;
658
+ }
659
+
660
+ parsed.padding = parsed.spectrum.getMargin(entry);
661
+
662
+ if ( !parsed.padding ) {
663
+ throw new Error("noUiSlider (" + VERSION + "): 'padding' option is only supported on linear sliders.");
664
+ }
665
+
666
+ if ( parsed.padding < 0 ) {
667
+ throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be a positive number.");
668
+ }
669
+
670
+ if ( parsed.padding >= 50 ) {
671
+ throw new Error("noUiSlider (" + VERSION + "): 'padding' option must be less than half the range.");
672
+ }
673
+ }
674
+
675
+ function testDirection ( parsed, entry ) {
676
+
677
+ // Set direction as a numerical value for easy parsing.
678
+ // Invert connection for RTL sliders, so that the proper
679
+ // handles get the connect/background classes.
680
+ switch ( entry ) {
681
+ case 'ltr':
682
+ parsed.dir = 0;
683
+ break;
684
+ case 'rtl':
685
+ parsed.dir = 1;
686
+ break;
687
+ default:
688
+ throw new Error("noUiSlider (" + VERSION + "): 'direction' option was not recognized.");
689
+ }
690
+ }
691
+
692
+ function testBehaviour ( parsed, entry ) {
693
+
694
+ // Make sure the input is a string.
695
+ if ( typeof entry !== 'string' ) {
696
+ throw new Error("noUiSlider (" + VERSION + "): 'behaviour' must be a string containing options.");
697
+ }
698
+
699
+ // Check if the string contains any keywords.
700
+ // None are required.
701
+ var tap = entry.indexOf('tap') >= 0;
702
+ var drag = entry.indexOf('drag') >= 0;
703
+ var fixed = entry.indexOf('fixed') >= 0;
704
+ var snap = entry.indexOf('snap') >= 0;
705
+ var hover = entry.indexOf('hover') >= 0;
706
+
707
+ if ( fixed ) {
708
+
709
+ if ( parsed.handles !== 2 ) {
710
+ throw new Error("noUiSlider (" + VERSION + "): 'fixed' behaviour must be used with 2 handles");
711
+ }
712
+
713
+ // Use margin to enforce fixed state
714
+ testMargin(parsed, parsed.start[1] - parsed.start[0]);
715
+ }
716
+
717
+ parsed.events = {
718
+ tap: tap || snap,
719
+ drag: drag,
720
+ fixed: fixed,
721
+ snap: snap,
722
+ hover: hover
723
+ };
724
+ }
725
+
726
+ function testMultitouch ( parsed, entry ) {
727
+ parsed.multitouch = entry;
728
+
729
+ if ( typeof entry !== 'boolean' ){
730
+ throw new Error("noUiSlider (" + VERSION + "): 'multitouch' option must be a boolean.");
731
+ }
732
+ }
733
+
734
+ function testTooltips ( parsed, entry ) {
735
+
736
+ if ( entry === false ) {
737
+ return;
738
+ }
739
+
740
+ else if ( entry === true ) {
741
+
742
+ parsed.tooltips = [];
743
+
744
+ for ( var i = 0; i < parsed.handles; i++ ) {
745
+ parsed.tooltips.push(true);
746
+ }
747
+ }
748
+
749
+ else {
750
+
751
+ parsed.tooltips = asArray(entry);
752
+
753
+ if ( parsed.tooltips.length !== parsed.handles ) {
754
+ throw new Error("noUiSlider (" + VERSION + "): must pass a formatter for all handles.");
755
+ }
756
+
757
+ parsed.tooltips.forEach(function(formatter){
758
+ if ( typeof formatter !== 'boolean' && (typeof formatter !== 'object' || typeof formatter.to !== 'function') ) {
759
+ throw new Error("noUiSlider (" + VERSION + "): 'tooltips' must be passed a formatter or 'false'.");
760
+ }
761
+ });
762
+ }
763
+ }
764
+
765
+ function testAriaFormat ( parsed, entry ) {
766
+ parsed.ariaFormat = entry;
767
+ validateFormat(entry);
768
+ }
769
+
770
+ function testFormat ( parsed, entry ) {
771
+ parsed.format = entry;
772
+ validateFormat(entry);
773
+ }
774
+
775
+ function testCssPrefix ( parsed, entry ) {
776
+
777
+ if ( entry !== undefined && typeof entry !== 'string' && entry !== false ) {
778
+ throw new Error("noUiSlider (" + VERSION + "): 'cssPrefix' must be a string or `false`.");
779
+ }
780
+
781
+ parsed.cssPrefix = entry;
782
+ }
783
+
784
+ function testCssClasses ( parsed, entry ) {
785
+
786
+ if ( entry !== undefined && typeof entry !== 'object' ) {
787
+ throw new Error("noUiSlider (" + VERSION + "): 'cssClasses' must be an object.");
788
+ }
789
+
790
+ if ( typeof parsed.cssPrefix === 'string' ) {
791
+ parsed.cssClasses = {};
792
+
793
+ for ( var key in entry ) {
794
+ if ( !entry.hasOwnProperty(key) ) { continue; }
795
+
796
+ parsed.cssClasses[key] = parsed.cssPrefix + entry[key];
797
+ }
798
+ } else {
799
+ parsed.cssClasses = entry;
800
+ }
801
+ }
802
+
803
+ function testUseRaf ( parsed, entry ) {
804
+ if ( entry === true || entry === false ) {
805
+ parsed.useRequestAnimationFrame = entry;
806
+ } else {
807
+ throw new Error("noUiSlider (" + VERSION + "): 'useRequestAnimationFrame' option should be true (default) or false.");
808
+ }
809
+ }
810
+
811
+ // Test all developer settings and parse to assumption-safe values.
812
+ function testOptions ( options ) {
813
+
814
+ // To prove a fix for #537, freeze options here.
815
+ // If the object is modified, an error will be thrown.
816
+ // Object.freeze(options);
817
+
818
+ var parsed = {
819
+ margin: 0,
820
+ limit: 0,
821
+ padding: 0,
822
+ animate: true,
823
+ animationDuration: 300,
824
+ ariaFormat: defaultFormatter,
825
+ format: defaultFormatter
826
+ };
827
+
828
+ // Tests are executed in the order they are presented here.
829
+ var tests = {
830
+ 'step': { r: false, t: testStep },
831
+ 'start': { r: true, t: testStart },
832
+ 'connect': { r: true, t: testConnect },
833
+ 'direction': { r: true, t: testDirection },
834
+ 'snap': { r: false, t: testSnap },
835
+ 'animate': { r: false, t: testAnimate },
836
+ 'animationDuration': { r: false, t: testAnimationDuration },
837
+ 'range': { r: true, t: testRange },
838
+ 'orientation': { r: false, t: testOrientation },
839
+ 'margin': { r: false, t: testMargin },
840
+ 'limit': { r: false, t: testLimit },
841
+ 'padding': { r: false, t: testPadding },
842
+ 'behaviour': { r: true, t: testBehaviour },
843
+ 'multitouch': { r: true, t: testMultitouch },
844
+ 'ariaFormat': { r: false, t: testAriaFormat },
845
+ 'format': { r: false, t: testFormat },
846
+ 'tooltips': { r: false, t: testTooltips },
847
+ 'cssPrefix': { r: false, t: testCssPrefix },
848
+ 'cssClasses': { r: false, t: testCssClasses },
849
+ 'useRequestAnimationFrame': { r: false, t: testUseRaf }
850
+ };
851
+
852
+ var defaults = {
853
+ 'connect': false,
854
+ 'direction': 'ltr',
855
+ 'behaviour': 'tap',
856
+ 'multitouch': false,
857
+ 'orientation': 'horizontal',
858
+ 'cssPrefix' : 'noUi-',
859
+ 'cssClasses': {
860
+ target: 'target',
861
+ base: 'base',
862
+ origin: 'origin',
863
+ handle: 'handle',
864
+ handleLower: 'handle-lower',
865
+ handleUpper: 'handle-upper',
866
+ horizontal: 'horizontal',
867
+ vertical: 'vertical',
868
+ background: 'background',
869
+ connect: 'connect',
870
+ ltr: 'ltr',
871
+ rtl: 'rtl',
872
+ draggable: 'draggable',
873
+ drag: 'state-drag',
874
+ tap: 'state-tap',
875
+ active: 'active',
876
+ tooltip: 'tooltip',
877
+ pips: 'pips',
878
+ pipsHorizontal: 'pips-horizontal',
879
+ pipsVertical: 'pips-vertical',
880
+ marker: 'marker',
881
+ markerHorizontal: 'marker-horizontal',
882
+ markerVertical: 'marker-vertical',
883
+ markerNormal: 'marker-normal',
884
+ markerLarge: 'marker-large',
885
+ markerSub: 'marker-sub',
886
+ value: 'value',
887
+ valueHorizontal: 'value-horizontal',
888
+ valueVertical: 'value-vertical',
889
+ valueNormal: 'value-normal',
890
+ valueLarge: 'value-large',
891
+ valueSub: 'value-sub'
892
+ },
893
+ 'useRequestAnimationFrame': true
894
+ };
895
+
896
+ // AriaFormat defaults to regular format, if any.
897
+ if ( options.format && !options.ariaFormat ) {
898
+ options.ariaFormat = options.format;
899
+ }
900
+
901
+ // Run all options through a testing mechanism to ensure correct
902
+ // input. It should be noted that options might get modified to
903
+ // be handled properly. E.g. wrapping integers in arrays.
904
+ Object.keys(tests).forEach(function( name ){
905
+
906
+ // If the option isn't set, but it is required, throw an error.
907
+ if ( options[name] === undefined && defaults[name] === undefined ) {
908
+
909
+ if ( tests[name].r ) {
910
+ throw new Error("noUiSlider (" + VERSION + "): '" + name + "' is required.");
911
+ }
912
+
913
+ return true;
914
+ }
915
+
916
+ tests[name].t( parsed, options[name] === undefined ? defaults[name] : options[name] );
917
+ });
918
+
919
+ // Forward pips options
920
+ parsed.pips = options.pips;
921
+
922
+ var styles = [['left', 'top'], ['right', 'bottom']];
923
+
924
+ // Pre-define the styles.
925
+ parsed.style = styles[parsed.dir][parsed.ort];
926
+ parsed.styleOposite = styles[parsed.dir?0:1][parsed.ort];
927
+
928
+ return parsed;
929
+ }
930
+
931
+
932
+ function closure ( target, options, originalOptions ){
933
+
934
+ var actions = getActions();
935
+ var supportsTouchActionNone = getSupportsTouchActionNone();
936
+ var supportsPassive = supportsTouchActionNone && getSupportsPassive();
937
+
938
+ // All variables local to 'closure' are prefixed with 'scope_'
939
+ var scope_Target = target;
940
+ var scope_Locations = [];
941
+ var scope_Base;
942
+ var scope_Handles;
943
+ var scope_HandleNumbers = [];
944
+ var scope_ActiveHandlesCount = 0;
945
+ var scope_Connects;
946
+ var scope_Spectrum = options.spectrum;
947
+ var scope_Values = [];
948
+ var scope_Events = {};
949
+ var scope_Self;
950
+ var scope_Pips;
951
+ var scope_Document = target.ownerDocument;
952
+ var scope_DocumentElement = scope_Document.documentElement;
953
+ var scope_Body = scope_Document.body;
954
+
955
+
956
+ // Creates a node, adds it to target, returns the new node.
957
+ function addNodeTo ( target, className ) {
958
+
959
+ var div = scope_Document.createElement('div');
960
+
961
+ if ( className ) {
962
+ addClass(div, className);
963
+ }
964
+
965
+ target.appendChild(div);
966
+
967
+ return div;
968
+ }
969
+
970
+ // Append a origin to the base
971
+ function addOrigin ( base, handleNumber ) {
972
+
973
+ var origin = addNodeTo(base, options.cssClasses.origin);
974
+ var handle = addNodeTo(origin, options.cssClasses.handle);
975
+
976
+ handle.setAttribute('data-handle', handleNumber);
977
+
978
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
979
+ // 0 = focusable and reachable
980
+ handle.setAttribute('tabindex', '0');
981
+ handle.setAttribute('role', 'slider');
982
+ handle.setAttribute('aria-orientation', options.ort ? 'vertical' : 'horizontal');
983
+
984
+ if ( handleNumber === 0 ) {
985
+ addClass(handle, options.cssClasses.handleLower);
986
+ }
987
+
988
+ else if ( handleNumber === options.handles - 1 ) {
989
+ addClass(handle, options.cssClasses.handleUpper);
990
+ }
991
+
992
+ return origin;
993
+ }
994
+
995
+ // Insert nodes for connect elements
996
+ function addConnect ( base, add ) {
997
+
998
+ if ( !add ) {
999
+ return false;
1000
+ }
1001
+
1002
+ return addNodeTo(base, options.cssClasses.connect);
1003
+ }
1004
+
1005
+ // Add handles to the slider base.
1006
+ function addElements ( connectOptions, base ) {
1007
+
1008
+ scope_Handles = [];
1009
+ scope_Connects = [];
1010
+
1011
+ scope_Connects.push(addConnect(base, connectOptions[0]));
1012
+
1013
+ // [::::O====O====O====]
1014
+ // connectOptions = [0, 1, 1, 1]
1015
+
1016
+ for ( var i = 0; i < options.handles; i++ ) {
1017
+ // Keep a list of all added handles.
1018
+ scope_Handles.push(addOrigin(base, i));
1019
+ scope_HandleNumbers[i] = i;
1020
+ scope_Connects.push(addConnect(base, connectOptions[i + 1]));
1021
+ }
1022
+ }
1023
+
1024
+ // Initialize a single slider.
1025
+ function addSlider ( target ) {
1026
+
1027
+ // Apply classes and data to the target.
1028
+ addClass(target, options.cssClasses.target);
1029
+
1030
+ if ( options.dir === 0 ) {
1031
+ addClass(target, options.cssClasses.ltr);
1032
+ } else {
1033
+ addClass(target, options.cssClasses.rtl);
1034
+ }
1035
+
1036
+ if ( options.ort === 0 ) {
1037
+ addClass(target, options.cssClasses.horizontal);
1038
+ } else {
1039
+ addClass(target, options.cssClasses.vertical);
1040
+ }
1041
+
1042
+ scope_Base = addNodeTo(target, options.cssClasses.base);
1043
+ }
1044
+
1045
+
1046
+ function addTooltip ( handle, handleNumber ) {
1047
+
1048
+ if ( !options.tooltips[handleNumber] ) {
1049
+ return false;
1050
+ }
1051
+
1052
+ return addNodeTo(handle.firstChild, options.cssClasses.tooltip);
1053
+ }
1054
+
1055
+ // The tooltips option is a shorthand for using the 'update' event.
1056
+ function tooltips ( ) {
1057
+
1058
+ // Tooltips are added with options.tooltips in original order.
1059
+ var tips = scope_Handles.map(addTooltip);
1060
+
1061
+ bindEvent('update', function(values, handleNumber, unencoded) {
1062
+
1063
+ if ( !tips[handleNumber] ) {
1064
+ return;
1065
+ }
1066
+
1067
+ var formattedValue = values[handleNumber];
1068
+
1069
+ if ( options.tooltips[handleNumber] !== true ) {
1070
+ formattedValue = options.tooltips[handleNumber].to(unencoded[handleNumber]);
1071
+ }
1072
+
1073
+ tips[handleNumber].innerHTML = formattedValue;
1074
+ });
1075
+ }
1076
+
1077
+
1078
+ function aria ( ) {
1079
+
1080
+ bindEvent('update', function ( values, handleNumber, unencoded, tap, positions ) {
1081
+
1082
+ // Update Aria Values for all handles, as a change in one changes min and max values for the next.
1083
+ scope_HandleNumbers.forEach(function( handleNumber ){
1084
+
1085
+ var handle = scope_Handles[handleNumber];
1086
+
1087
+ var min = checkHandlePosition(scope_Locations, handleNumber, 0, true, true, true);
1088
+ var max = checkHandlePosition(scope_Locations, handleNumber, 100, true, true, true);
1089
+
1090
+ var now = positions[handleNumber];
1091
+ var text = options.ariaFormat.to(unencoded[handleNumber]);
1092
+
1093
+ handle.children[0].setAttribute('aria-valuemin', min.toFixed(1));
1094
+ handle.children[0].setAttribute('aria-valuemax', max.toFixed(1));
1095
+ handle.children[0].setAttribute('aria-valuenow', now.toFixed(1));
1096
+ handle.children[0].setAttribute('aria-valuetext', text);
1097
+ });
1098
+ });
1099
+ }
1100
+
1101
+
1102
+ function getGroup ( mode, values, stepped ) {
1103
+
1104
+ // Use the range.
1105
+ if ( mode === 'range' || mode === 'steps' ) {
1106
+ return scope_Spectrum.xVal;
1107
+ }
1108
+
1109
+ if ( mode === 'count' ) {
1110
+
1111
+ if ( !values ) {
1112
+ throw new Error("noUiSlider (" + VERSION + "): 'values' required for mode 'count'.");
1113
+ }
1114
+
1115
+ // Divide 0 - 100 in 'count' parts.
1116
+ var spread = ( 100 / (values - 1) );
1117
+ var v;
1118
+ var i = 0;
1119
+
1120
+ values = [];
1121
+
1122
+ // List these parts and have them handled as 'positions'.
1123
+ while ( (v = i++ * spread) <= 100 ) {
1124
+ values.push(v);
1125
+ }
1126
+
1127
+ mode = 'positions';
1128
+ }
1129
+
1130
+ if ( mode === 'positions' ) {
1131
+
1132
+ // Map all percentages to on-range values.
1133
+ return values.map(function( value ){
1134
+ return scope_Spectrum.fromStepping( stepped ? scope_Spectrum.getStep( value ) : value );
1135
+ });
1136
+ }
1137
+
1138
+ if ( mode === 'values' ) {
1139
+
1140
+ // If the value must be stepped, it needs to be converted to a percentage first.
1141
+ if ( stepped ) {
1142
+
1143
+ return values.map(function( value ){
1144
+
1145
+ // Convert to percentage, apply step, return to value.
1146
+ return scope_Spectrum.fromStepping( scope_Spectrum.getStep( scope_Spectrum.toStepping( value ) ) );
1147
+ });
1148
+
1149
+ }
1150
+
1151
+ // Otherwise, we can simply use the values.
1152
+ return values;
1153
+ }
1154
+ }
1155
+
1156
+ function generateSpread ( density, mode, group ) {
1157
+
1158
+ function safeIncrement(value, increment) {
1159
+ // Avoid floating point variance by dropping the smallest decimal places.
1160
+ return (value + increment).toFixed(7) / 1;
1161
+ }
1162
+
1163
+ var indexes = {};
1164
+ var firstInRange = scope_Spectrum.xVal[0];
1165
+ var lastInRange = scope_Spectrum.xVal[scope_Spectrum.xVal.length-1];
1166
+ var ignoreFirst = false;
1167
+ var ignoreLast = false;
1168
+ var prevPct = 0;
1169
+
1170
+ // Create a copy of the group, sort it and filter away all duplicates.
1171
+ group = unique(group.slice().sort(function(a, b){ return a - b; }));
1172
+
1173
+ // Make sure the range starts with the first element.
1174
+ if ( group[0] !== firstInRange ) {
1175
+ group.unshift(firstInRange);
1176
+ ignoreFirst = true;
1177
+ }
1178
+
1179
+ // Likewise for the last one.
1180
+ if ( group[group.length - 1] !== lastInRange ) {
1181
+ group.push(lastInRange);
1182
+ ignoreLast = true;
1183
+ }
1184
+
1185
+ group.forEach(function ( current, index ) {
1186
+
1187
+ // Get the current step and the lower + upper positions.
1188
+ var step;
1189
+ var i;
1190
+ var q;
1191
+ var low = current;
1192
+ var high = group[index+1];
1193
+ var newPct;
1194
+ var pctDifference;
1195
+ var pctPos;
1196
+ var type;
1197
+ var steps;
1198
+ var realSteps;
1199
+ var stepsize;
1200
+
1201
+ // When using 'steps' mode, use the provided steps.
1202
+ // Otherwise, we'll step on to the next subrange.
1203
+ if ( mode === 'steps' ) {
1204
+ step = scope_Spectrum.xNumSteps[ index ];
1205
+ }
1206
+
1207
+ // Default to a 'full' step.
1208
+ if ( !step ) {
1209
+ step = high-low;
1210
+ }
1211
+
1212
+ // Low can be 0, so test for false. If high is undefined,
1213
+ // we are at the last subrange. Index 0 is already handled.
1214
+ if ( low === false || high === undefined ) {
1215
+ return;
1216
+ }
1217
+
1218
+ // Make sure step isn't 0, which would cause an infinite loop (#654)
1219
+ step = Math.max(step, 0.0000001);
1220
+
1221
+ // Find all steps in the subrange.
1222
+ for ( i = low; i <= high; i = safeIncrement(i, step) ) {
1223
+
1224
+ // Get the percentage value for the current step,
1225
+ // calculate the size for the subrange.
1226
+ newPct = scope_Spectrum.toStepping( i );
1227
+ pctDifference = newPct - prevPct;
1228
+
1229
+ steps = pctDifference / density;
1230
+ realSteps = Math.round(steps);
1231
+
1232
+ // This ratio represents the ammount of percentage-space a point indicates.
1233
+ // For a density 1 the points/percentage = 1. For density 2, that percentage needs to be re-devided.
1234
+ // Round the percentage offset to an even number, then divide by two
1235
+ // to spread the offset on both sides of the range.
1236
+ stepsize = pctDifference/realSteps;
1237
+
1238
+ // Divide all points evenly, adding the correct number to this subrange.
1239
+ // Run up to <= so that 100% gets a point, event if ignoreLast is set.
1240
+ for ( q = 1; q <= realSteps; q += 1 ) {
1241
+
1242
+ // The ratio between the rounded value and the actual size might be ~1% off.
1243
+ // Correct the percentage offset by the number of points
1244
+ // per subrange. density = 1 will result in 100 points on the
1245
+ // full range, 2 for 50, 4 for 25, etc.
1246
+ pctPos = prevPct + ( q * stepsize );
1247
+ indexes[pctPos.toFixed(5)] = ['x', 0];
1248
+ }
1249
+
1250
+ // Determine the point type.
1251
+ type = (group.indexOf(i) > -1) ? 1 : ( mode === 'steps' ? 2 : 0 );
1252
+
1253
+ // Enforce the 'ignoreFirst' option by overwriting the type for 0.
1254
+ if ( !index && ignoreFirst ) {
1255
+ type = 0;
1256
+ }
1257
+
1258
+ if ( !(i === high && ignoreLast)) {
1259
+ // Mark the 'type' of this point. 0 = plain, 1 = real value, 2 = step value.
1260
+ indexes[newPct.toFixed(5)] = [i, type];
1261
+ }
1262
+
1263
+ // Update the percentage count.
1264
+ prevPct = newPct;
1265
+ }
1266
+ });
1267
+
1268
+ return indexes;
1269
+ }
1270
+
1271
+ function addMarking ( spread, filterFunc, formatter ) {
1272
+
1273
+ var element = scope_Document.createElement('div');
1274
+
1275
+ var valueSizeClasses = [
1276
+ options.cssClasses.valueNormal,
1277
+ options.cssClasses.valueLarge,
1278
+ options.cssClasses.valueSub
1279
+ ];
1280
+ var markerSizeClasses = [
1281
+ options.cssClasses.markerNormal,
1282
+ options.cssClasses.markerLarge,
1283
+ options.cssClasses.markerSub
1284
+ ];
1285
+ var valueOrientationClasses = [
1286
+ options.cssClasses.valueHorizontal,
1287
+ options.cssClasses.valueVertical
1288
+ ];
1289
+ var markerOrientationClasses = [
1290
+ options.cssClasses.markerHorizontal,
1291
+ options.cssClasses.markerVertical
1292
+ ];
1293
+
1294
+ addClass(element, options.cssClasses.pips);
1295
+ addClass(element, options.ort === 0 ? options.cssClasses.pipsHorizontal : options.cssClasses.pipsVertical);
1296
+
1297
+ function getClasses( type, source ){
1298
+ var a = source === options.cssClasses.value;
1299
+ var orientationClasses = a ? valueOrientationClasses : markerOrientationClasses;
1300
+ var sizeClasses = a ? valueSizeClasses : markerSizeClasses;
1301
+
1302
+ return source + ' ' + orientationClasses[options.ort] + ' ' + sizeClasses[type];
1303
+ }
1304
+
1305
+ function addSpread ( offset, values ){
1306
+
1307
+ // Apply the filter function, if it is set.
1308
+ values[1] = (values[1] && filterFunc) ? filterFunc(values[0], values[1]) : values[1];
1309
+
1310
+ // Add a marker for every point
1311
+ var node = addNodeTo(element, false);
1312
+ node.className = getClasses(values[1], options.cssClasses.marker);
1313
+ node.style[options.style] = offset + '%';
1314
+
1315
+ // Values are only appended for points marked '1' or '2'.
1316
+ if ( values[1] ) {
1317
+ node = addNodeTo(element, false);
1318
+ node.className = getClasses(values[1], options.cssClasses.value);
1319
+ node.style[options.style] = offset + '%';
1320
+ node.innerText = formatter.to(values[0]);
1321
+ }
1322
+ }
1323
+
1324
+ // Append all points.
1325
+ Object.keys(spread).forEach(function(a){
1326
+ addSpread(a, spread[a]);
1327
+ });
1328
+
1329
+ return element;
1330
+ }
1331
+
1332
+ function removePips ( ) {
1333
+ if ( scope_Pips ) {
1334
+ removeElement(scope_Pips);
1335
+ scope_Pips = null;
1336
+ }
1337
+ }
1338
+
1339
+ function pips ( grid ) {
1340
+
1341
+ // Fix #669
1342
+ removePips();
1343
+
1344
+ var mode = grid.mode;
1345
+ var density = grid.density || 1;
1346
+ var filter = grid.filter || false;
1347
+ var values = grid.values || false;
1348
+ var stepped = grid.stepped || false;
1349
+ var group = getGroup( mode, values, stepped );
1350
+ var spread = generateSpread( density, mode, group );
1351
+ var format = grid.format || {
1352
+ to: Math.round
1353
+ };
1354
+
1355
+ scope_Pips = scope_Target.appendChild(addMarking(
1356
+ spread,
1357
+ filter,
1358
+ format
1359
+ ));
1360
+
1361
+ return scope_Pips;
1362
+ }
1363
+
1364
+
1365
+ // Shorthand for base dimensions.
1366
+ function baseSize ( ) {
1367
+ var rect = scope_Base.getBoundingClientRect(), alt = 'offset' + ['Width', 'Height'][options.ort];
1368
+ return options.ort === 0 ? (rect.width||scope_Base[alt]) : (rect.height||scope_Base[alt]);
1369
+ }
1370
+
1371
+ // Handler for attaching events trough a proxy.
1372
+ function attachEvent ( events, element, callback, data ) {
1373
+
1374
+ // This function can be used to 'filter' events to the slider.
1375
+ // element is a node, not a nodeList
1376
+
1377
+ var method = function ( e ){
1378
+
1379
+ if ( scope_Target.hasAttribute('disabled') ) {
1380
+ return false;
1381
+ }
1382
+
1383
+ // Stop if an active 'tap' transition is taking place.
1384
+ if ( hasClass(scope_Target, options.cssClasses.tap) ) {
1385
+ return false;
1386
+ }
1387
+
1388
+ e = fixEvent(e, data.pageOffset, data.target || element);
1389
+
1390
+ // Handle reject of multitouch
1391
+ if ( !e ) {
1392
+ return false;
1393
+ }
1394
+
1395
+ // Ignore right or middle clicks on start #454
1396
+ if ( events === actions.start && e.buttons !== undefined && e.buttons > 1 ) {
1397
+ return false;
1398
+ }
1399
+
1400
+ // Ignore right or middle clicks on start #454
1401
+ if ( data.hover && e.buttons ) {
1402
+ return false;
1403
+ }
1404
+
1405
+ // 'supportsPassive' is only true if a browser also supports touch-action: none in CSS.
1406
+ // iOS safari does not, so it doesn't get to benefit from passive scrolling. iOS does support
1407
+ // touch-action: manipulation, but that allows panning, which breaks
1408
+ // sliders after zooming/on non-responsive pages.
1409
+ // See: https://bugs.webkit.org/show_bug.cgi?id=133112
1410
+ if ( !supportsPassive ) {
1411
+ e.preventDefault();
1412
+ }
1413
+
1414
+ e.calcPoint = e.points[ options.ort ];
1415
+
1416
+ // Call the event handler with the event [ and additional data ].
1417
+ callback ( e, data );
1418
+ };
1419
+
1420
+ var methods = [];
1421
+
1422
+ // Bind a closure on the target for every event type.
1423
+ events.split(' ').forEach(function( eventName ){
1424
+ element.addEventListener(eventName, method, supportsPassive ? { passive: true } : false);
1425
+ methods.push([eventName, method]);
1426
+ });
1427
+
1428
+ return methods;
1429
+ }
1430
+
1431
+ // Provide a clean event with standardized offset values.
1432
+ function fixEvent ( e, pageOffset, target ) {
1433
+
1434
+ // Filter the event to register the type, which can be
1435
+ // touch, mouse or pointer. Offset changes need to be
1436
+ // made on an event specific basis.
1437
+ var touch = e.type.indexOf('touch') === 0;
1438
+ var mouse = e.type.indexOf('mouse') === 0;
1439
+ var pointer = e.type.indexOf('pointer') === 0;
1440
+
1441
+ var x;
1442
+ var y;
1443
+
1444
+ // IE10 implemented pointer events with a prefix;
1445
+ if ( e.type.indexOf('MSPointer') === 0 ) {
1446
+ pointer = true;
1447
+ }
1448
+
1449
+
1450
+ // In the event that multitouch is activated, the only thing one handle should be concerned
1451
+ // about is the touches that originated on top of it.
1452
+ if ( touch && options.multitouch ) {
1453
+ // Returns true if a touch originated on the target.
1454
+ var isTouchOnTarget = function (touch) {
1455
+ return touch.target === target || target.contains(touch.target);
1456
+ };
1457
+ // In the case of touchstart events, we need to make sure there is still no more than one
1458
+ // touch on the target so we look amongst all touches.
1459
+ if (e.type === 'touchstart') {
1460
+ var targetTouches = Array.prototype.filter.call(e.touches, isTouchOnTarget);
1461
+ // Do not support more than one touch per handle.
1462
+ if ( targetTouches.length > 1 ) {
1463
+ return false;
1464
+ }
1465
+ x = targetTouches[0].pageX;
1466
+ y = targetTouches[0].pageY;
1467
+ } else {
1468
+ // In the other cases, find on changedTouches is enough.
1469
+ var targetTouch = Array.prototype.find.call(e.changedTouches, isTouchOnTarget);
1470
+ // Cancel if the target touch has not moved.
1471
+ if ( !targetTouch ) {
1472
+ return false;
1473
+ }
1474
+ x = targetTouch.pageX;
1475
+ y = targetTouch.pageY;
1476
+ }
1477
+ } else if ( touch ) {
1478
+ // Fix bug when user touches with two or more fingers on mobile devices.
1479
+ // It's useful when you have two or more sliders on one page,
1480
+ // that can be touched simultaneously.
1481
+ // #649, #663, #668
1482
+ if ( e.touches.length > 1 ) {
1483
+ return false;
1484
+ }
1485
+
1486
+ // noUiSlider supports one movement at a time,
1487
+ // so we can select the first 'changedTouch'.
1488
+ x = e.changedTouches[0].pageX;
1489
+ y = e.changedTouches[0].pageY;
1490
+ }
1491
+
1492
+ pageOffset = pageOffset || getPageOffset(scope_Document);
1493
+
1494
+ if ( mouse || pointer ) {
1495
+ x = e.clientX + pageOffset.x;
1496
+ y = e.clientY + pageOffset.y;
1497
+ }
1498
+
1499
+ e.pageOffset = pageOffset;
1500
+ e.points = [x, y];
1501
+ e.cursor = mouse || pointer; // Fix #435
1502
+
1503
+ return e;
1504
+ }
1505
+
1506
+ // Translate a coordinate in the document to a percentage on the slider
1507
+ function calcPointToPercentage ( calcPoint ) {
1508
+ var location = calcPoint - offset(scope_Base, options.ort);
1509
+ var proposal = ( location * 100 ) / baseSize();
1510
+ return options.dir ? 100 - proposal : proposal;
1511
+ }
1512
+
1513
+ // Find handle closest to a certain percentage on the slider
1514
+ function getClosestHandle ( proposal ) {
1515
+
1516
+ var closest = 100;
1517
+ var handleNumber = false;
1518
+
1519
+ scope_Handles.forEach(function(handle, index){
1520
+
1521
+ // Disabled handles are ignored
1522
+ if ( handle.hasAttribute('disabled') ) {
1523
+ return;
1524
+ }
1525
+
1526
+ var pos = Math.abs(scope_Locations[index] - proposal);
1527
+
1528
+ if ( pos < closest ) {
1529
+ handleNumber = index;
1530
+ closest = pos;
1531
+ }
1532
+ });
1533
+
1534
+ return handleNumber;
1535
+ }
1536
+
1537
+ // Moves handle(s) by a percentage
1538
+ // (bool, % to move, [% where handle started, ...], [index in scope_Handles, ...])
1539
+ function moveHandles ( upward, proposal, locations, handleNumbers ) {
1540
+
1541
+ var proposals = locations.slice();
1542
+
1543
+ var b = [!upward, upward];
1544
+ var f = [upward, !upward];
1545
+
1546
+ // Copy handleNumbers so we don't change the dataset
1547
+ handleNumbers = handleNumbers.slice();
1548
+
1549
+ // Check to see which handle is 'leading'.
1550
+ // If that one can't move the second can't either.
1551
+ if ( upward ) {
1552
+ handleNumbers.reverse();
1553
+ }
1554
+
1555
+ // Step 1: get the maximum percentage that any of the handles can move
1556
+ if ( handleNumbers.length > 1 ) {
1557
+
1558
+ handleNumbers.forEach(function(handleNumber, o) {
1559
+
1560
+ var to = checkHandlePosition(proposals, handleNumber, proposals[handleNumber] + proposal, b[o], f[o], false);
1561
+
1562
+ // Stop if one of the handles can't move.
1563
+ if ( to === false ) {
1564
+ proposal = 0;
1565
+ } else {
1566
+ proposal = to - proposals[handleNumber];
1567
+ proposals[handleNumber] = to;
1568
+ }
1569
+ });
1570
+ }
1571
+
1572
+ // If using one handle, check backward AND forward
1573
+ else {
1574
+ b = f = [true];
1575
+ }
1576
+
1577
+ var state = false;
1578
+
1579
+ // Step 2: Try to set the handles with the found percentage
1580
+ handleNumbers.forEach(function(handleNumber, o) {
1581
+ state = setHandle(handleNumber, locations[handleNumber] + proposal, b[o], f[o]) || state;
1582
+ });
1583
+
1584
+ // Step 3: If a handle moved, fire events
1585
+ if ( state ) {
1586
+ handleNumbers.forEach(function(handleNumber){
1587
+ fireEvent('update', handleNumber);
1588
+ fireEvent('slide', handleNumber);
1589
+ });
1590
+ }
1591
+ }
1592
+
1593
+ // External event handling
1594
+ function fireEvent ( eventName, handleNumber, tap ) {
1595
+
1596
+ Object.keys(scope_Events).forEach(function( targetEvent ) {
1597
+
1598
+ var eventType = targetEvent.split('.')[0];
1599
+
1600
+ if ( eventName === eventType ) {
1601
+ scope_Events[targetEvent].forEach(function( callback ) {
1602
+
1603
+ callback.call(
1604
+ // Use the slider public API as the scope ('this')
1605
+ scope_Self,
1606
+ // Return values as array, so arg_1[arg_2] is always valid.
1607
+ scope_Values.map(options.format.to),
1608
+ // Handle index, 0 or 1
1609
+ handleNumber,
1610
+ // Unformatted slider values
1611
+ scope_Values.slice(),
1612
+ // Event is fired by tap, true or false
1613
+ tap || false,
1614
+ // Left offset of the handle, in relation to the slider
1615
+ scope_Locations.slice()
1616
+ );
1617
+ });
1618
+ }
1619
+ });
1620
+ }
1621
+
1622
+
1623
+ // Fire 'end' when a mouse or pen leaves the document.
1624
+ function documentLeave ( event, data ) {
1625
+ if ( event.type === "mouseout" && event.target.nodeName === "HTML" && event.relatedTarget === null ){
1626
+ eventEnd (event, data);
1627
+ }
1628
+ }
1629
+
1630
+ // Handle movement on document for handle and range drag.
1631
+ function eventMove ( event, data ) {
1632
+
1633
+ // Fix #498
1634
+ // Check value of .buttons in 'start' to work around a bug in IE10 mobile (data.buttonsProperty).
1635
+ // https://connect.microsoft.com/IE/feedback/details/927005/mobile-ie10-windows-phone-buttons-property-of-pointermove-event-always-zero
1636
+ // IE9 has .buttons and .which zero on mousemove.
1637
+ // Firefox breaks the spec MDN defines.
1638
+ if ( navigator.appVersion.indexOf("MSIE 9") === -1 && event.buttons === 0 && data.buttonsProperty !== 0 ) {
1639
+ return eventEnd(event, data);
1640
+ }
1641
+
1642
+ // Check if we are moving up or down
1643
+ var movement = (options.dir ? -1 : 1) * (event.calcPoint - data.startCalcPoint);
1644
+
1645
+ // Convert the movement into a percentage of the slider width/height
1646
+ var proposal = (movement * 100) / data.baseSize;
1647
+
1648
+ moveHandles(movement > 0, proposal, data.locations, data.handleNumbers);
1649
+ }
1650
+
1651
+ // Unbind move events on document, call callbacks.
1652
+ function eventEnd ( event, data ) {
1653
+
1654
+ // The handle is no longer active, so remove the class.
1655
+ if ( data.handle ) {
1656
+ removeClass(data.handle, options.cssClasses.active);
1657
+ scope_ActiveHandlesCount -= 1;
1658
+ }
1659
+
1660
+ // Unbind the move and end events, which are added on 'start'.
1661
+ data.listeners.forEach(function( c ) {
1662
+ scope_DocumentElement.removeEventListener(c[0], c[1]);
1663
+ });
1664
+
1665
+ if ( scope_ActiveHandlesCount === 0 ) {
1666
+ // Remove dragging class.
1667
+ removeClass(scope_Target, options.cssClasses.drag);
1668
+ setZindex();
1669
+
1670
+ // Remove cursor styles and text-selection events bound to the body.
1671
+ if ( event.cursor ) {
1672
+ scope_Body.style.cursor = '';
1673
+ scope_Body.removeEventListener('selectstart', preventDefault);
1674
+ }
1675
+ }
1676
+
1677
+ data.handleNumbers.forEach(function(handleNumber){
1678
+ fireEvent('change', handleNumber);
1679
+ fireEvent('set', handleNumber);
1680
+ fireEvent('end', handleNumber);
1681
+ });
1682
+ }
1683
+
1684
+ // Bind move events on document.
1685
+ function eventStart ( event, data ) {
1686
+
1687
+ var handle;
1688
+ if ( data.handleNumbers.length === 1 ) {
1689
+
1690
+ var handleOrigin = scope_Handles[data.handleNumbers[0]];
1691
+
1692
+ // Ignore 'disabled' handles
1693
+ if ( handleOrigin.hasAttribute('disabled') ) {
1694
+ return false;
1695
+ }
1696
+
1697
+ handle = handleOrigin.children[0];
1698
+ scope_ActiveHandlesCount += 1;
1699
+
1700
+ // Mark the handle as 'active' so it can be styled.
1701
+ addClass(handle, options.cssClasses.active);
1702
+ }
1703
+
1704
+ // A drag should never propagate up to the 'tap' event.
1705
+ event.stopPropagation();
1706
+
1707
+ // Record the event listeners.
1708
+ var listeners = [];
1709
+
1710
+ // Attach the move and end events.
1711
+ var moveEvent = attachEvent(actions.move, scope_DocumentElement, eventMove, {
1712
+ // The event target has changed so we need to propagate the original one so that we keep
1713
+ // relying on it to extract target touches.
1714
+ target: event.target,
1715
+ handle: handle,
1716
+ listeners: listeners,
1717
+ startCalcPoint: event.calcPoint,
1718
+ baseSize: baseSize(),
1719
+ pageOffset: event.pageOffset,
1720
+ handleNumbers: data.handleNumbers,
1721
+ buttonsProperty: event.buttons,
1722
+ locations: scope_Locations.slice()
1723
+ });
1724
+
1725
+ var endEvent = attachEvent(actions.end, scope_DocumentElement, eventEnd, {
1726
+ target: event.target,
1727
+ handle: handle,
1728
+ listeners: listeners,
1729
+ handleNumbers: data.handleNumbers
1730
+ });
1731
+
1732
+ var outEvent = attachEvent("mouseout", scope_DocumentElement, documentLeave, {
1733
+ target: event.target,
1734
+ handle: handle,
1735
+ listeners: listeners,
1736
+ handleNumbers: data.handleNumbers
1737
+ });
1738
+
1739
+ // We want to make sure we pushed the listeners in the listener list rather than creating
1740
+ // a new one as it has already been passed to the event handlers.
1741
+ listeners.push.apply(listeners, moveEvent.concat(endEvent, outEvent));
1742
+
1743
+ // Text selection isn't an issue on touch devices,
1744
+ // so adding cursor styles can be skipped.
1745
+ if ( event.cursor ) {
1746
+
1747
+ // Prevent the 'I' cursor and extend the range-drag cursor.
1748
+ scope_Body.style.cursor = getComputedStyle(event.target).cursor;
1749
+
1750
+ // Mark the target with a dragging state.
1751
+ if ( scope_Handles.length > 1 ) {
1752
+ addClass(scope_Target, options.cssClasses.drag);
1753
+ }
1754
+
1755
+ // Prevent text selection when dragging the handles.
1756
+ // In noUiSlider <= 9.2.0, this was handled by calling preventDefault on mouse/touch start/move,
1757
+ // which is scroll blocking. The selectstart event is supported by FireFox starting from version 52,
1758
+ // meaning the only holdout is iOS Safari. This doesn't matter: text selection isn't triggered there.
1759
+ // The 'cursor' flag is false.
1760
+ // See: http://caniuse.com/#search=selectstart
1761
+ scope_Body.addEventListener('selectstart', preventDefault, false);
1762
+ }
1763
+
1764
+ data.handleNumbers.forEach(function(handleNumber){
1765
+ fireEvent('start', handleNumber);
1766
+ });
1767
+ }
1768
+
1769
+ // Move closest handle to tapped location.
1770
+ function eventTap ( event ) {
1771
+
1772
+ // The tap event shouldn't propagate up
1773
+ event.stopPropagation();
1774
+
1775
+ var proposal = calcPointToPercentage(event.calcPoint);
1776
+ var handleNumber = getClosestHandle(proposal);
1777
+
1778
+ // Tackle the case that all handles are 'disabled'.
1779
+ if ( handleNumber === false ) {
1780
+ return false;
1781
+ }
1782
+
1783
+ // Flag the slider as it is now in a transitional state.
1784
+ // Transition takes a configurable amount of ms (default 300). Re-enable the slider after that.
1785
+ if ( !options.events.snap ) {
1786
+ addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration);
1787
+ }
1788
+
1789
+ setHandle(handleNumber, proposal, true, true);
1790
+
1791
+ setZindex();
1792
+
1793
+ fireEvent('slide', handleNumber, true);
1794
+ fireEvent('update', handleNumber, true);
1795
+ fireEvent('change', handleNumber, true);
1796
+ fireEvent('set', handleNumber, true);
1797
+
1798
+ if ( options.events.snap ) {
1799
+ eventStart(event, { handleNumbers: [handleNumber] });
1800
+ }
1801
+ }
1802
+
1803
+ // Fires a 'hover' event for a hovered mouse/pen position.
1804
+ function eventHover ( event ) {
1805
+
1806
+ var proposal = calcPointToPercentage(event.calcPoint);
1807
+
1808
+ var to = scope_Spectrum.getStep(proposal);
1809
+ var value = scope_Spectrum.fromStepping(to);
1810
+
1811
+ Object.keys(scope_Events).forEach(function( targetEvent ) {
1812
+ if ( 'hover' === targetEvent.split('.')[0] ) {
1813
+ scope_Events[targetEvent].forEach(function( callback ) {
1814
+ callback.call( scope_Self, value );
1815
+ });
1816
+ }
1817
+ });
1818
+ }
1819
+
1820
+ // Attach events to several slider parts.
1821
+ function bindSliderEvents ( behaviour ) {
1822
+
1823
+ // Attach the standard drag event to the handles.
1824
+ if ( !behaviour.fixed ) {
1825
+
1826
+ scope_Handles.forEach(function( handle, index ){
1827
+
1828
+ // These events are only bound to the visual handle
1829
+ // element, not the 'real' origin element.
1830
+ attachEvent ( actions.start, handle.children[0], eventStart, {
1831
+ handleNumbers: [index]
1832
+ });
1833
+ });
1834
+ }
1835
+
1836
+ // Attach the tap event to the slider base.
1837
+ if ( behaviour.tap ) {
1838
+ attachEvent (actions.start, scope_Base, eventTap, {});
1839
+ }
1840
+
1841
+ // Fire hover events
1842
+ if ( behaviour.hover ) {
1843
+ attachEvent (actions.move, scope_Base, eventHover, { hover: true });
1844
+ }
1845
+
1846
+ // Make the range draggable.
1847
+ if ( behaviour.drag ){
1848
+
1849
+ scope_Connects.forEach(function( connect, index ){
1850
+
1851
+ if ( connect === false || index === 0 || index === scope_Connects.length - 1 ) {
1852
+ return;
1853
+ }
1854
+
1855
+ var handleBefore = scope_Handles[index - 1];
1856
+ var handleAfter = scope_Handles[index];
1857
+ var eventHolders = [connect];
1858
+
1859
+ addClass(connect, options.cssClasses.draggable);
1860
+
1861
+ // When the range is fixed, the entire range can
1862
+ // be dragged by the handles. The handle in the first
1863
+ // origin will propagate the start event upward,
1864
+ // but it needs to be bound manually on the other.
1865
+ if ( behaviour.fixed ) {
1866
+ eventHolders.push(handleBefore.children[0]);
1867
+ eventHolders.push(handleAfter.children[0]);
1868
+ }
1869
+
1870
+ eventHolders.forEach(function( eventHolder ) {
1871
+ attachEvent ( actions.start, eventHolder, eventStart, {
1872
+ handles: [handleBefore, handleAfter],
1873
+ handleNumbers: [index - 1, index]
1874
+ });
1875
+ });
1876
+ });
1877
+ }
1878
+ }
1879
+
1880
+
1881
+ // Split out the handle positioning logic so the Move event can use it, too
1882
+ function checkHandlePosition ( reference, handleNumber, to, lookBackward, lookForward, getValue ) {
1883
+
1884
+ // For sliders with multiple handles, limit movement to the other handle.
1885
+ // Apply the margin option by adding it to the handle positions.
1886
+ if ( scope_Handles.length > 1 ) {
1887
+
1888
+ if ( lookBackward && handleNumber > 0 ) {
1889
+ to = Math.max(to, reference[handleNumber - 1] + options.margin);
1890
+ }
1891
+
1892
+ if ( lookForward && handleNumber < scope_Handles.length - 1 ) {
1893
+ to = Math.min(to, reference[handleNumber + 1] - options.margin);
1894
+ }
1895
+ }
1896
+
1897
+ // The limit option has the opposite effect, limiting handles to a
1898
+ // maximum distance from another. Limit must be > 0, as otherwise
1899
+ // handles would be unmoveable.
1900
+ if ( scope_Handles.length > 1 && options.limit ) {
1901
+
1902
+ if ( lookBackward && handleNumber > 0 ) {
1903
+ to = Math.min(to, reference[handleNumber - 1] + options.limit);
1904
+ }
1905
+
1906
+ if ( lookForward && handleNumber < scope_Handles.length - 1 ) {
1907
+ to = Math.max(to, reference[handleNumber + 1] - options.limit);
1908
+ }
1909
+ }
1910
+
1911
+ // The padding option keeps the handles a certain distance from the
1912
+ // edges of the slider. Padding must be > 0.
1913
+ if ( options.padding ) {
1914
+
1915
+ if ( handleNumber === 0 ) {
1916
+ to = Math.max(to, options.padding);
1917
+ }
1918
+
1919
+ if ( handleNumber === scope_Handles.length - 1 ) {
1920
+ to = Math.min(to, 100 - options.padding);
1921
+ }
1922
+ }
1923
+
1924
+ to = scope_Spectrum.getStep(to);
1925
+
1926
+ // Limit percentage to the 0 - 100 range
1927
+ to = limit(to);
1928
+
1929
+ // Return false if handle can't move
1930
+ if ( to === reference[handleNumber] && !getValue ) {
1931
+ return false;
1932
+ }
1933
+
1934
+ return to;
1935
+ }
1936
+
1937
+ function toPct ( pct ) {
1938
+ return pct + '%';
1939
+ }
1940
+
1941
+ // Updates scope_Locations and scope_Values, updates visual state
1942
+ function updateHandlePosition ( handleNumber, to ) {
1943
+
1944
+ // Update locations.
1945
+ scope_Locations[handleNumber] = to;
1946
+
1947
+ // Convert the value to the slider stepping/range.
1948
+ scope_Values[handleNumber] = scope_Spectrum.fromStepping(to);
1949
+
1950
+ // Called synchronously or on the next animationFrame
1951
+ var stateUpdate = function() {
1952
+ scope_Handles[handleNumber].style[options.style] = toPct(to);
1953
+ updateConnect(handleNumber);
1954
+ updateConnect(handleNumber + 1);
1955
+ };
1956
+
1957
+ // Set the handle to the new position.
1958
+ // Use requestAnimationFrame for efficient painting.
1959
+ // No significant effect in Chrome, Edge sees dramatic performace improvements.
1960
+ // Option to disable is useful for unit tests, and single-step debugging.
1961
+ if ( window.requestAnimationFrame && options.useRequestAnimationFrame ) {
1962
+ window.requestAnimationFrame(stateUpdate);
1963
+ } else {
1964
+ stateUpdate();
1965
+ }
1966
+ }
1967
+
1968
+ function setZindex ( ) {
1969
+
1970
+ scope_HandleNumbers.forEach(function(handleNumber){
1971
+ // Handles before the slider middle are stacked later = higher,
1972
+ // Handles after the middle later is lower
1973
+ // [[7] [8] .......... | .......... [5] [4]
1974
+ var dir = (scope_Locations[handleNumber] > 50 ? -1 : 1);
1975
+ var zIndex = 3 + (scope_Handles.length + (dir * handleNumber));
1976
+ scope_Handles[handleNumber].childNodes[0].style.zIndex = zIndex;
1977
+ });
1978
+ }
1979
+
1980
+ // Test suggested values and apply margin, step.
1981
+ function setHandle ( handleNumber, to, lookBackward, lookForward ) {
1982
+
1983
+ to = checkHandlePosition(scope_Locations, handleNumber, to, lookBackward, lookForward, false);
1984
+
1985
+ if ( to === false ) {
1986
+ return false;
1987
+ }
1988
+
1989
+ updateHandlePosition(handleNumber, to);
1990
+
1991
+ return true;
1992
+ }
1993
+
1994
+ // Updates style attribute for connect nodes
1995
+ function updateConnect ( index ) {
1996
+
1997
+ // Skip connects set to false
1998
+ if ( !scope_Connects[index] ) {
1999
+ return;
2000
+ }
2001
+
2002
+ var l = 0;
2003
+ var h = 100;
2004
+
2005
+ if ( index !== 0 ) {
2006
+ l = scope_Locations[index - 1];
2007
+ }
2008
+
2009
+ if ( index !== scope_Connects.length - 1 ) {
2010
+ h = scope_Locations[index];
2011
+ }
2012
+
2013
+ scope_Connects[index].style[options.style] = toPct(l);
2014
+ scope_Connects[index].style[options.styleOposite] = toPct(100 - h);
2015
+ }
2016
+
2017
+ // ...
2018
+ function setValue ( to, handleNumber ) {
2019
+
2020
+ // Setting with null indicates an 'ignore'.
2021
+ // Inputting 'false' is invalid.
2022
+ if ( to === null || to === false ) {
2023
+ return;
2024
+ }
2025
+
2026
+ // If a formatted number was passed, attemt to decode it.
2027
+ if ( typeof to === 'number' ) {
2028
+ to = String(to);
2029
+ }
2030
+
2031
+ to = options.format.from(to);
2032
+
2033
+ // Request an update for all links if the value was invalid.
2034
+ // Do so too if setting the handle fails.
2035
+ if ( to !== false && !isNaN(to) ) {
2036
+ setHandle(handleNumber, scope_Spectrum.toStepping(to), false, false);
2037
+ }
2038
+ }
2039
+
2040
+ // Set the slider value.
2041
+ function valueSet ( input, fireSetEvent ) {
2042
+
2043
+ var values = asArray(input);
2044
+ var isInit = scope_Locations[0] === undefined;
2045
+
2046
+ // Event fires by default
2047
+ fireSetEvent = (fireSetEvent === undefined ? true : !!fireSetEvent);
2048
+
2049
+ values.forEach(setValue);
2050
+
2051
+ // Animation is optional.
2052
+ // Make sure the initial values were set before using animated placement.
2053
+ if ( options.animate && !isInit ) {
2054
+ addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration);
2055
+ }
2056
+
2057
+ // Now that all base values are set, apply constraints
2058
+ scope_HandleNumbers.forEach(function(handleNumber){
2059
+ setHandle(handleNumber, scope_Locations[handleNumber], true, false);
2060
+ });
2061
+
2062
+ setZindex();
2063
+
2064
+ scope_HandleNumbers.forEach(function(handleNumber){
2065
+
2066
+ fireEvent('update', handleNumber);
2067
+
2068
+ // Fire the event only for handles that received a new value, as per #579
2069
+ if ( values[handleNumber] !== null && fireSetEvent ) {
2070
+ fireEvent('set', handleNumber);
2071
+ }
2072
+ });
2073
+ }
2074
+
2075
+ // Reset slider to initial values
2076
+ function valueReset ( fireSetEvent ) {
2077
+ valueSet(options.start, fireSetEvent);
2078
+ }
2079
+
2080
+ // Get the slider value.
2081
+ function valueGet ( ) {
2082
+
2083
+ var values = scope_Values.map(options.format.to);
2084
+
2085
+ // If only one handle is used, return a single value.
2086
+ if ( values.length === 1 ){
2087
+ return values[0];
2088
+ }
2089
+
2090
+ return values;
2091
+ }
2092
+
2093
+ // Removes classes from the root and empties it.
2094
+ function destroy ( ) {
2095
+
2096
+ for ( var key in options.cssClasses ) {
2097
+ if ( !options.cssClasses.hasOwnProperty(key) ) { continue; }
2098
+ removeClass(scope_Target, options.cssClasses[key]);
2099
+ }
2100
+
2101
+ while (scope_Target.firstChild) {
2102
+ scope_Target.removeChild(scope_Target.firstChild);
2103
+ }
2104
+
2105
+ delete scope_Target.noUiSlider;
2106
+ }
2107
+
2108
+ // Get the current step size for the slider.
2109
+ function getCurrentStep ( ) {
2110
+
2111
+ // Check all locations, map them to their stepping point.
2112
+ // Get the step point, then find it in the input list.
2113
+ return scope_Locations.map(function( location, index ){
2114
+
2115
+ var nearbySteps = scope_Spectrum.getNearbySteps( location );
2116
+ var value = scope_Values[index];
2117
+ var increment = nearbySteps.thisStep.step;
2118
+ var decrement = null;
2119
+
2120
+ // If the next value in this step moves into the next step,
2121
+ // the increment is the start of the next step - the current value
2122
+ if ( increment !== false ) {
2123
+ if ( value + increment > nearbySteps.stepAfter.startValue ) {
2124
+ increment = nearbySteps.stepAfter.startValue - value;
2125
+ }
2126
+ }
2127
+
2128
+
2129
+ // If the value is beyond the starting point
2130
+ if ( value > nearbySteps.thisStep.startValue ) {
2131
+ decrement = nearbySteps.thisStep.step;
2132
+ }
2133
+
2134
+ else if ( nearbySteps.stepBefore.step === false ) {
2135
+ decrement = false;
2136
+ }
2137
+
2138
+ // If a handle is at the start of a step, it always steps back into the previous step first
2139
+ else {
2140
+ decrement = value - nearbySteps.stepBefore.highestStep;
2141
+ }
2142
+
2143
+
2144
+ // Now, if at the slider edges, there is not in/decrement
2145
+ if ( location === 100 ) {
2146
+ increment = null;
2147
+ }
2148
+
2149
+ else if ( location === 0 ) {
2150
+ decrement = null;
2151
+ }
2152
+
2153
+ // As per #391, the comparison for the decrement step can have some rounding issues.
2154
+ var stepDecimals = scope_Spectrum.countStepDecimals();
2155
+
2156
+ // Round per #391
2157
+ if ( increment !== null && increment !== false ) {
2158
+ increment = Number(increment.toFixed(stepDecimals));
2159
+ }
2160
+
2161
+ if ( decrement !== null && decrement !== false ) {
2162
+ decrement = Number(decrement.toFixed(stepDecimals));
2163
+ }
2164
+
2165
+ return [decrement, increment];
2166
+ });
2167
+ }
2168
+
2169
+ // Attach an event to this slider, possibly including a namespace
2170
+ function bindEvent ( namespacedEvent, callback ) {
2171
+ scope_Events[namespacedEvent] = scope_Events[namespacedEvent] || [];
2172
+ scope_Events[namespacedEvent].push(callback);
2173
+
2174
+ // If the event bound is 'update,' fire it immediately for all handles.
2175
+ if ( namespacedEvent.split('.')[0] === 'update' ) {
2176
+ scope_Handles.forEach(function(a, index){
2177
+ fireEvent('update', index);
2178
+ });
2179
+ }
2180
+ }
2181
+
2182
+ // Undo attachment of event
2183
+ function removeEvent ( namespacedEvent ) {
2184
+
2185
+ var event = namespacedEvent && namespacedEvent.split('.')[0];
2186
+ var namespace = event && namespacedEvent.substring(event.length);
2187
+
2188
+ Object.keys(scope_Events).forEach(function( bind ){
2189
+
2190
+ var tEvent = bind.split('.')[0],
2191
+ tNamespace = bind.substring(tEvent.length);
2192
+
2193
+ if ( (!event || event === tEvent) && (!namespace || namespace === tNamespace) ) {
2194
+ delete scope_Events[bind];
2195
+ }
2196
+ });
2197
+ }
2198
+
2199
+ // Updateable: margin, limit, padding, step, range, animate, snap
2200
+ function updateOptions ( optionsToUpdate, fireSetEvent ) {
2201
+
2202
+ // Spectrum is created using the range, snap, direction and step options.
2203
+ // 'snap' and 'step' can be updated.
2204
+ // If 'snap' and 'step' are not passed, they should remain unchanged.
2205
+ var v = valueGet();
2206
+
2207
+ var updateAble = ['margin', 'limit', 'padding', 'range', 'animate', 'snap', 'step', 'format'];
2208
+
2209
+ // Only change options that we're actually passed to update.
2210
+ updateAble.forEach(function(name){
2211
+ if ( optionsToUpdate[name] !== undefined ) {
2212
+ originalOptions[name] = optionsToUpdate[name];
2213
+ }
2214
+ });
2215
+
2216
+ var newOptions = testOptions(originalOptions);
2217
+
2218
+ // Load new options into the slider state
2219
+ updateAble.forEach(function(name){
2220
+ if ( optionsToUpdate[name] !== undefined ) {
2221
+ options[name] = newOptions[name];
2222
+ }
2223
+ });
2224
+
2225
+ scope_Spectrum = newOptions.spectrum;
2226
+
2227
+ // Limit, margin and padding depend on the spectrum but are stored outside of it. (#677)
2228
+ options.margin = newOptions.margin;
2229
+ options.limit = newOptions.limit;
2230
+ options.padding = newOptions.padding;
2231
+
2232
+ // Update pips, removes existing.
2233
+ if ( options.pips ) {
2234
+ pips(options.pips);
2235
+ }
2236
+
2237
+ // Invalidate the current positioning so valueSet forces an update.
2238
+ scope_Locations = [];
2239
+ valueSet(optionsToUpdate.start || v, fireSetEvent);
2240
+ }
2241
+
2242
+ // Throw an error if the slider was already initialized.
2243
+ if ( scope_Target.noUiSlider ) {
2244
+ throw new Error("noUiSlider (" + VERSION + "): Slider was already initialized.");
2245
+ }
2246
+
2247
+ // Create the base element, initialise HTML and set classes.
2248
+ // Add handles and connect elements.
2249
+ addSlider(scope_Target);
2250
+ addElements(options.connect, scope_Base);
2251
+
2252
+ scope_Self = {
2253
+ destroy: destroy,
2254
+ steps: getCurrentStep,
2255
+ on: bindEvent,
2256
+ off: removeEvent,
2257
+ get: valueGet,
2258
+ set: valueSet,
2259
+ reset: valueReset,
2260
+ // Exposed for unit testing, don't use this in your application.
2261
+ __moveHandles: function(a, b, c) { moveHandles(a, b, scope_Locations, c); },
2262
+ options: originalOptions, // Issue #600, #678
2263
+ updateOptions: updateOptions,
2264
+ target: scope_Target, // Issue #597
2265
+ removePips: removePips,
2266
+ pips: pips // Issue #594
2267
+ };
2268
+
2269
+ // Attach user events.
2270
+ bindSliderEvents(options.events);
2271
+
2272
+ // Use the public value method to set the start values.
2273
+ valueSet(options.start);
2274
+
2275
+ if ( options.pips ) {
2276
+ pips(options.pips);
2277
+ }
2278
+
2279
+ if ( options.tooltips ) {
2280
+ tooltips();
2281
+ }
2282
+
2283
+ aria();
2284
+
2285
+ return scope_Self;
2286
+
2287
+ }
2288
+
2289
+
2290
+ // Run the standard initializer
2291
+ function initialize ( target, originalOptions ) {
2292
+
2293
+ if ( !target || !target.nodeName ) {
2294
+ throw new Error("noUiSlider (" + VERSION + "): create requires a single element, got: " + target);
2295
+ }
2296
+
2297
+ // Test the options and create the slider environment;
2298
+ var options = testOptions( originalOptions, target );
2299
+ var api = closure( target, options, originalOptions );
2300
+
2301
+ target.noUiSlider = api;
2302
+
2303
+ return api;
2304
+ }
2305
+
2306
+ // Use an object instead of a function for future expansibility;
2307
+ return {
2308
+ version: VERSION,
2309
+ create: initialize
2310
+ };
2311
+
2312
+ }));